2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "disas/disas.h"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL
= (0x00 << 26),
41 OPC_REGIMM
= (0x01 << 26),
42 OPC_CP0
= (0x10 << 26),
43 OPC_CP1
= (0x11 << 26),
44 OPC_CP2
= (0x12 << 26),
45 OPC_CP3
= (0x13 << 26),
46 OPC_SPECIAL2
= (0x1C << 26),
47 OPC_SPECIAL3
= (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI
= (0x08 << 26),
50 OPC_ADDIU
= (0x09 << 26),
51 OPC_SLTI
= (0x0A << 26),
52 OPC_SLTIU
= (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI
= (0x0C << 26),
55 OPC_ORI
= (0x0D << 26),
56 OPC_XORI
= (0x0E << 26),
57 OPC_LUI
= (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI
= (0x18 << 26),
60 OPC_DADDIU
= (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL
= (0x03 << 26),
64 OPC_JALS
= OPC_JAL
| 0x5,
65 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL
= (0x14 << 26),
67 OPC_BNE
= (0x05 << 26),
68 OPC_BNEL
= (0x15 << 26),
69 OPC_BLEZ
= (0x06 << 26),
70 OPC_BLEZL
= (0x16 << 26),
71 OPC_BGTZ
= (0x07 << 26),
72 OPC_BGTZL
= (0x17 << 26),
73 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS
= OPC_JALX
| 0x5,
76 OPC_LDL
= (0x1A << 26),
77 OPC_LDR
= (0x1B << 26),
78 OPC_LB
= (0x20 << 26),
79 OPC_LH
= (0x21 << 26),
80 OPC_LWL
= (0x22 << 26),
81 OPC_LW
= (0x23 << 26),
82 OPC_LWPC
= OPC_LW
| 0x5,
83 OPC_LBU
= (0x24 << 26),
84 OPC_LHU
= (0x25 << 26),
85 OPC_LWR
= (0x26 << 26),
86 OPC_LWU
= (0x27 << 26),
87 OPC_SB
= (0x28 << 26),
88 OPC_SH
= (0x29 << 26),
89 OPC_SWL
= (0x2A << 26),
90 OPC_SW
= (0x2B << 26),
91 OPC_SDL
= (0x2C << 26),
92 OPC_SDR
= (0x2D << 26),
93 OPC_SWR
= (0x2E << 26),
94 OPC_LL
= (0x30 << 26),
95 OPC_LLD
= (0x34 << 26),
96 OPC_LD
= (0x37 << 26),
97 OPC_LDPC
= OPC_LD
| 0x5,
98 OPC_SC
= (0x38 << 26),
99 OPC_SCD
= (0x3C << 26),
100 OPC_SD
= (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1
= (0x31 << 26),
103 OPC_LWC2
= (0x32 << 26),
104 OPC_LDC1
= (0x35 << 26),
105 OPC_LDC2
= (0x36 << 26),
106 OPC_SWC1
= (0x39 << 26),
107 OPC_SWC2
= (0x3A << 26),
108 OPC_SDC1
= (0x3D << 26),
109 OPC_SDC2
= (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX
= (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE
= (0x2F << 26),
114 OPC_PREF
= (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL
= 0x00 | OPC_SPECIAL
,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
129 OPC_ROTR
= OPC_SRL
| (1 << 21),
130 OPC_SRA
= 0x03 | OPC_SPECIAL
,
131 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
132 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
133 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
134 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
135 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
136 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
137 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
138 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
139 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
140 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
141 OPC_DROTR
= OPC_DSRL
| (1 << 21),
142 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
143 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
144 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
145 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
146 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
147 /* Multiplication / division */
148 OPC_MULT
= 0x18 | OPC_SPECIAL
,
149 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
150 OPC_DIV
= 0x1A | OPC_SPECIAL
,
151 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
152 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
153 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
154 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
155 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD
= 0x20 | OPC_SPECIAL
,
158 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
159 OPC_SUB
= 0x22 | OPC_SPECIAL
,
160 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
161 OPC_AND
= 0x24 | OPC_SPECIAL
,
162 OPC_OR
= 0x25 | OPC_SPECIAL
,
163 OPC_XOR
= 0x26 | OPC_SPECIAL
,
164 OPC_NOR
= 0x27 | OPC_SPECIAL
,
165 OPC_SLT
= 0x2A | OPC_SPECIAL
,
166 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
167 OPC_DADD
= 0x2C | OPC_SPECIAL
,
168 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
169 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
170 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
172 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
173 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
174 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
175 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
177 OPC_TGE
= 0x30 | OPC_SPECIAL
,
178 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
179 OPC_TLT
= 0x32 | OPC_SPECIAL
,
180 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
181 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
182 OPC_TNE
= 0x36 | OPC_SPECIAL
,
183 /* HI / LO registers load & stores */
184 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
185 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
186 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
187 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
188 /* Conditional moves */
189 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
190 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
192 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
195 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
196 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
197 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
198 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
199 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
201 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
202 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
203 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
204 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
205 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
206 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
207 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
215 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
216 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
217 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
218 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
219 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
220 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
221 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
222 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
223 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
224 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
225 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
226 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
227 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
235 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
236 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
237 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
238 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
239 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
240 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
241 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
242 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
243 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
244 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
245 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
246 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
247 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
248 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
249 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
250 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
259 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
260 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
261 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
262 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
264 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
265 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
266 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
267 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
268 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
269 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
270 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
271 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
272 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
273 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
274 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
275 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
277 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
278 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
279 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
280 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
282 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
290 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
291 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
292 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
293 OPC_INS
= 0x04 | OPC_SPECIAL3
,
294 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
295 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
296 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
297 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
298 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
299 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
300 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
301 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
304 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
305 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
306 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
307 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
308 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
309 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
310 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
311 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
312 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
313 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
314 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
315 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
318 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
321 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
322 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
323 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
327 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
330 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
335 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
338 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
341 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
344 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
352 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
353 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
361 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
367 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
374 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
375 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
376 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
383 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
384 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
385 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
386 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
388 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
389 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
390 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
391 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
392 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
395 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
396 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
397 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
399 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
404 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
405 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
406 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
414 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
415 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
416 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
417 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
424 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
427 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
429 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
436 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
437 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
438 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
439 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
447 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
450 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
453 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
460 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
461 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
462 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
463 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
465 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
468 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
470 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
471 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
481 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
488 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
489 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
490 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
491 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
515 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
516 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
517 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
518 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
548 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
549 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
556 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
557 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
558 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
559 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
566 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
567 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
568 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
569 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
570 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
571 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
578 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
596 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
598 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
599 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
600 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
607 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
608 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
609 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
610 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
613 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
622 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
623 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
632 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
639 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
656 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
665 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Append Sub-class */
671 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
672 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
673 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
674 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
681 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
682 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
683 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
684 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
700 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
713 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
716 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
737 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
744 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
768 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
776 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
777 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
778 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
779 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
780 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
781 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
782 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
783 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
784 OPC_C0
= (0x10 << 21) | OPC_CP0
,
785 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
786 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
794 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
795 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
796 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
797 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
798 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR
= 0x01 | OPC_C0
,
806 OPC_TLBWI
= 0x02 | OPC_C0
,
807 OPC_TLBWR
= 0x06 | OPC_C0
,
808 OPC_TLBP
= 0x08 | OPC_C0
,
809 OPC_RFE
= 0x10 | OPC_C0
,
810 OPC_ERET
= 0x18 | OPC_C0
,
811 OPC_DERET
= 0x1F | OPC_C0
,
812 OPC_WAIT
= 0x20 | OPC_C0
,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S
= 16, /* single fp */
822 FMT_D
= 17, /* double fp */
823 FMT_E
= 18, /* extended fp */
824 FMT_Q
= 19, /* quad fp */
825 FMT_W
= 20, /* 32-bit fixed */
826 FMT_L
= 21, /* 64-bit fixed */
827 FMT_PS
= 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
833 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
834 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
835 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
836 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
837 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
838 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
839 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
840 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
841 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
842 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
843 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
844 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
845 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
846 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
847 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
848 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
849 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
857 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
858 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
859 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
863 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
864 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
868 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
869 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
876 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
877 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
878 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
879 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
880 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
881 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
882 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
883 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
890 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
891 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
892 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
893 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
896 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
898 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
899 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
900 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
901 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
902 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
905 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
907 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
908 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
909 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
910 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
911 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
912 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
913 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
914 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
916 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
917 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
918 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
919 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
920 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
921 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
922 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
923 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
925 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
926 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
927 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
928 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
929 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
930 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
932 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
933 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
934 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
935 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
936 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
937 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
939 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
940 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
941 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
942 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
943 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
944 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
946 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
947 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
948 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
949 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
950 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
951 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
953 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
954 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
955 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
956 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
957 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
958 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
960 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
961 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
962 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
963 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
964 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
965 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
967 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
968 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
969 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
970 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
971 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
972 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
974 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
975 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
976 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
977 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
978 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
979 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1
= 0x00 | OPC_CP3
,
987 OPC_LDXC1
= 0x01 | OPC_CP3
,
988 OPC_LUXC1
= 0x05 | OPC_CP3
,
989 OPC_SWXC1
= 0x08 | OPC_CP3
,
990 OPC_SDXC1
= 0x09 | OPC_CP3
,
991 OPC_SUXC1
= 0x0D | OPC_CP3
,
992 OPC_PREFX
= 0x0F | OPC_CP3
,
993 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
994 OPC_MADD_S
= 0x20 | OPC_CP3
,
995 OPC_MADD_D
= 0x21 | OPC_CP3
,
996 OPC_MADD_PS
= 0x26 | OPC_CP3
,
997 OPC_MSUB_S
= 0x28 | OPC_CP3
,
998 OPC_MSUB_D
= 0x29 | OPC_CP3
,
999 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1000 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1001 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1002 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1003 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1004 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1005 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env
;
1010 static TCGv cpu_gpr
[32], cpu_PC
;
1011 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1012 static TCGv cpu_dspctrl
, btarget
, bcond
;
1013 static TCGv_i32 hflags
;
1014 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1015 static TCGv_i64 fpu_f64
[32];
1017 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1018 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext
{
1065 struct TranslationBlock
*tb
;
1066 target_ulong pc
, saved_pc
;
1068 int singlestep_enabled
;
1070 /* Routine used to access memory */
1072 uint32_t hflags
, saved_hflags
;
1074 target_ulong btarget
;
1078 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP
= 1, /* We want to stop translation for any reason */
1081 BS_BRANCH
= 2, /* We reached a branch condition */
1082 BS_EXCP
= 3, /* We reached an exception condition */
1085 static const char * const regnames
[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI
[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO
[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX
[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames
[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1120 #define LOG_DISAS(...) \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t
, int reg
)
1135 tcg_gen_movi_tl(t
, 0);
1137 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1140 static inline void gen_store_gpr (TCGv t
, int reg
)
1143 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t
, int reg
)
1149 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1152 static inline void gen_store_ACX (TCGv t
, int reg
)
1154 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from
, int to
)
1160 TCGv t0
= tcg_temp_new();
1163 tcg_gen_movi_tl(t0
, 0);
1165 TCGv_i32 t2
= tcg_temp_new_i32();
1166 TCGv_ptr addr
= tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1169 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1170 tcg_gen_andi_i32(t2
, t2
, 0xf);
1171 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1172 tcg_gen_ext_i32_ptr(addr
, t2
);
1173 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1175 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1176 tcg_temp_free_ptr(addr
);
1177 tcg_temp_free_i32(t2
);
1179 gen_store_gpr(t0
, to
);
1183 static inline void gen_store_srsgpr (int from
, int to
)
1186 TCGv t0
= tcg_temp_new();
1187 TCGv_i32 t2
= tcg_temp_new_i32();
1188 TCGv_ptr addr
= tcg_temp_new_ptr();
1190 gen_load_gpr(t0
, from
);
1191 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1192 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1193 tcg_gen_andi_i32(t2
, t2
, 0xf);
1194 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1195 tcg_gen_ext_i32_ptr(addr
, t2
);
1196 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1198 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1199 tcg_temp_free_ptr(addr
);
1200 tcg_temp_free_i32(t2
);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1208 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1211 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1213 TCGv_i64 t64
= tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64
, t
);
1215 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1216 tcg_temp_free_i64(t64
);
1219 static void gen_load_fpr32h(TCGv_i32 t
, int reg
)
1221 TCGv_i64 t64
= tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1223 tcg_gen_trunc_i64_i32(t
, t64
);
1224 tcg_temp_free_i64(t64
);
1227 static void gen_store_fpr32h(TCGv_i32 t
, int reg
)
1229 TCGv_i64 t64
= tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64
, t
);
1231 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1232 tcg_temp_free_i64(t64
);
1235 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1237 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1238 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1240 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1244 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1246 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1247 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1250 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1251 t0
= tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0
, t
, 32);
1253 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1254 tcg_temp_free_i64(t0
);
1258 static inline int get_fp_bit (int cc
)
1267 static inline void gen_save_pc(target_ulong pc
)
1269 tcg_gen_movi_tl(cpu_PC
, pc
);
1272 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1275 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1276 gen_save_pc(ctx
->pc
);
1277 ctx
->saved_pc
= ctx
->pc
;
1279 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1280 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1281 ctx
->saved_hflags
= ctx
->hflags
;
1282 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1288 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1294 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1296 ctx
->saved_hflags
= ctx
->hflags
;
1297 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1303 ctx
->btarget
= env
->btarget
;
1309 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1311 TCGv_i32 texcp
= tcg_const_i32(excp
);
1312 TCGv_i32 terr
= tcg_const_i32(err
);
1313 save_cpu_state(ctx
, 1);
1314 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1315 tcg_temp_free_i32(terr
);
1316 tcg_temp_free_i32(texcp
);
1320 generate_exception (DisasContext
*ctx
, int excp
)
1322 save_cpu_state(ctx
, 1);
1323 gen_helper_0e0i(raise_exception
, excp
);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1329 tcg_gen_add_tl(ret
, arg0
, arg1
);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1336 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1337 tcg_gen_ext32s_i64(ret
, ret
);
1342 static inline void check_cp0_enabled(DisasContext
*ctx
)
1344 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1345 generate_exception_err(ctx
, EXCP_CpU
, 0);
1348 static inline void check_cp1_enabled(DisasContext
*ctx
)
1350 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1351 generate_exception_err(ctx
, EXCP_CpU
, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1358 static inline void check_cop1x(DisasContext
*ctx
)
1360 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1361 generate_exception(ctx
, EXCP_RI
);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1369 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1370 generate_exception(ctx
, EXCP_RI
);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1386 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1387 generate_exception(ctx
, EXCP_RI
);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext
*ctx
)
1396 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1397 if (ctx
->insn_flags
& ASE_DSP
) {
1398 generate_exception(ctx
, EXCP_DSPDIS
);
1400 generate_exception(ctx
, EXCP_RI
);
1405 static inline void check_dspr2(DisasContext
*ctx
)
1407 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1408 if (ctx
->insn_flags
& ASE_DSP
) {
1409 generate_exception(ctx
, EXCP_DSPDIS
);
1411 generate_exception(ctx
, EXCP_RI
);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext
*ctx
, int flags
)
1420 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1421 generate_exception(ctx
, EXCP_RI
);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext
*ctx
)
1429 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1430 generate_exception(ctx
, EXCP_RI
);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1447 check_cp1_64bitmode(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d
, FMT_D
, 64)
1487 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1488 FOP_CONDS(, 0, s
, FMT_S
, 32)
1489 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1490 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1491 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1515 OP_LD_ATOMIC(ll
,ld32s
);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld
,ld64
);
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1555 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1561 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1562 int base
, int16_t offset
)
1565 tcg_gen_movi_tl(addr
, offset
);
1566 } else if (offset
== 0) {
1567 gen_load_gpr(addr
, base
);
1569 tcg_gen_movi_tl(addr
, offset
);
1570 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1574 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1576 target_ulong pc
= ctx
->pc
;
1578 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1579 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1584 pc
&= ~(target_ulong
)3;
1589 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1590 int rt
, int base
, int16_t offset
)
1592 const char *opn
= "ld";
1595 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1603 t0
= tcg_temp_new();
1604 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1607 #if defined(TARGET_MIPS64)
1609 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1610 gen_store_gpr(t0
, rt
);
1614 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1615 gen_store_gpr(t0
, rt
);
1619 save_cpu_state(ctx
, 1);
1620 op_ld_lld(t0
, t0
, ctx
);
1621 gen_store_gpr(t0
, rt
);
1625 t1
= tcg_temp_new();
1626 tcg_gen_andi_tl(t1
, t0
, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1
, t1
, 7);
1630 tcg_gen_shli_tl(t1
, t1
, 3);
1631 tcg_gen_andi_tl(t0
, t0
, ~7);
1632 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1633 tcg_gen_shl_tl(t0
, t0
, t1
);
1634 tcg_gen_xori_tl(t1
, t1
, 63);
1635 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1636 tcg_gen_shr_tl(t2
, t2
, t1
);
1637 gen_load_gpr(t1
, rt
);
1638 tcg_gen_and_tl(t1
, t1
, t2
);
1640 tcg_gen_or_tl(t0
, t0
, t1
);
1642 gen_store_gpr(t0
, rt
);
1646 t1
= tcg_temp_new();
1647 tcg_gen_andi_tl(t1
, t0
, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1
, t1
, 7);
1651 tcg_gen_shli_tl(t1
, t1
, 3);
1652 tcg_gen_andi_tl(t0
, t0
, ~7);
1653 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1654 tcg_gen_shr_tl(t0
, t0
, t1
);
1655 tcg_gen_xori_tl(t1
, t1
, 63);
1656 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1657 tcg_gen_shl_tl(t2
, t2
, t1
);
1658 gen_load_gpr(t1
, rt
);
1659 tcg_gen_and_tl(t1
, t1
, t2
);
1661 tcg_gen_or_tl(t0
, t0
, t1
);
1663 gen_store_gpr(t0
, rt
);
1667 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1668 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1670 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1671 gen_store_gpr(t0
, rt
);
1676 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1677 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1679 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1680 gen_store_gpr(t0
, rt
);
1684 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1685 gen_store_gpr(t0
, rt
);
1689 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
1690 gen_store_gpr(t0
, rt
);
1694 tcg_gen_qemu_ld16u(t0
, t0
, ctx
->mem_idx
);
1695 gen_store_gpr(t0
, rt
);
1699 tcg_gen_qemu_ld8s(t0
, t0
, ctx
->mem_idx
);
1700 gen_store_gpr(t0
, rt
);
1704 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
1705 gen_store_gpr(t0
, rt
);
1709 t1
= tcg_temp_new();
1710 tcg_gen_andi_tl(t1
, t0
, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1
, t1
, 3);
1714 tcg_gen_shli_tl(t1
, t1
, 3);
1715 tcg_gen_andi_tl(t0
, t0
, ~3);
1716 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1717 tcg_gen_shl_tl(t0
, t0
, t1
);
1718 tcg_gen_xori_tl(t1
, t1
, 31);
1719 t2
= tcg_const_tl(0x7fffffffull
);
1720 tcg_gen_shr_tl(t2
, t2
, t1
);
1721 gen_load_gpr(t1
, rt
);
1722 tcg_gen_and_tl(t1
, t1
, t2
);
1724 tcg_gen_or_tl(t0
, t0
, t1
);
1726 tcg_gen_ext32s_tl(t0
, t0
);
1727 gen_store_gpr(t0
, rt
);
1731 t1
= tcg_temp_new();
1732 tcg_gen_andi_tl(t1
, t0
, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1
, t1
, 3);
1736 tcg_gen_shli_tl(t1
, t1
, 3);
1737 tcg_gen_andi_tl(t0
, t0
, ~3);
1738 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1739 tcg_gen_shr_tl(t0
, t0
, t1
);
1740 tcg_gen_xori_tl(t1
, t1
, 31);
1741 t2
= tcg_const_tl(0xfffffffeull
);
1742 tcg_gen_shl_tl(t2
, t2
, t1
);
1743 gen_load_gpr(t1
, rt
);
1744 tcg_gen_and_tl(t1
, t1
, t2
);
1746 tcg_gen_or_tl(t0
, t0
, t1
);
1748 tcg_gen_ext32s_tl(t0
, t0
);
1749 gen_store_gpr(t0
, rt
);
1753 save_cpu_state(ctx
, 1);
1754 op_ld_ll(t0
, t0
, ctx
);
1755 gen_store_gpr(t0
, rt
);
1759 (void)opn
; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1765 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1766 int base
, int16_t offset
)
1768 const char *opn
= "st";
1769 TCGv t0
= tcg_temp_new();
1770 TCGv t1
= tcg_temp_new();
1772 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1773 gen_load_gpr(t1
, rt
);
1775 #if defined(TARGET_MIPS64)
1777 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
1781 save_cpu_state(ctx
, 1);
1782 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1786 save_cpu_state(ctx
, 1);
1787 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1792 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1796 tcg_gen_qemu_st16(t1
, t0
, ctx
->mem_idx
);
1800 tcg_gen_qemu_st8(t1
, t0
, ctx
->mem_idx
);
1804 save_cpu_state(ctx
, 1);
1805 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1809 save_cpu_state(ctx
, 1);
1810 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1814 (void)opn
; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1823 int base
, int16_t offset
)
1825 const char *opn
= "st_cond";
1828 #ifdef CONFIG_USER_ONLY
1829 t0
= tcg_temp_local_new();
1830 t1
= tcg_temp_local_new();
1832 t0
= tcg_temp_new();
1833 t1
= tcg_temp_new();
1835 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1836 gen_load_gpr(t1
, rt
);
1838 #if defined(TARGET_MIPS64)
1840 save_cpu_state(ctx
, 1);
1841 op_st_scd(t1
, t0
, rt
, ctx
);
1846 save_cpu_state(ctx
, 1);
1847 op_st_sc(t1
, t0
, rt
, ctx
);
1851 (void)opn
; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1859 int base
, int16_t offset
)
1861 const char *opn
= "flt_ldst";
1862 TCGv t0
= tcg_temp_new();
1864 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1870 TCGv_i32 fp0
= tcg_temp_new_i32();
1872 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1873 tcg_gen_trunc_tl_i32(fp0
, t0
);
1874 gen_store_fpr32(fp0
, ft
);
1875 tcg_temp_free_i32(fp0
);
1881 TCGv_i32 fp0
= tcg_temp_new_i32();
1882 TCGv t1
= tcg_temp_new();
1884 gen_load_fpr32(fp0
, ft
);
1885 tcg_gen_extu_i32_tl(t1
, fp0
);
1886 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1888 tcg_temp_free_i32(fp0
);
1894 TCGv_i64 fp0
= tcg_temp_new_i64();
1896 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
1897 gen_store_fpr64(ctx
, fp0
, ft
);
1898 tcg_temp_free_i64(fp0
);
1904 TCGv_i64 fp0
= tcg_temp_new_i64();
1906 gen_load_fpr64(ctx
, fp0
, ft
);
1907 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
1908 tcg_temp_free_i64(fp0
);
1914 generate_exception(ctx
, EXCP_RI
);
1917 (void)opn
; /* avoid a compiler warning */
1918 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1923 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1924 uint32_t op
, int rt
, int rs
, int16_t imm
)
1926 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1927 check_cp1_enabled(ctx
);
1928 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1930 generate_exception_err(ctx
, EXCP_CpU
, 1);
1934 /* Arithmetic with immediate operand */
1935 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1936 int rt
, int rs
, int16_t imm
)
1938 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1939 const char *opn
= "imm arith";
1941 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
1950 TCGv t0
= tcg_temp_local_new();
1951 TCGv t1
= tcg_temp_new();
1952 TCGv t2
= tcg_temp_new();
1953 int l1
= gen_new_label();
1955 gen_load_gpr(t1
, rs
);
1956 tcg_gen_addi_tl(t0
, t1
, uimm
);
1957 tcg_gen_ext32s_tl(t0
, t0
);
1959 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1960 tcg_gen_xori_tl(t2
, t0
, uimm
);
1961 tcg_gen_and_tl(t1
, t1
, t2
);
1963 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx
, EXCP_OVERFLOW
);
1968 tcg_gen_ext32s_tl(t0
, t0
);
1969 gen_store_gpr(t0
, rt
);
1976 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1977 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1979 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1983 #if defined(TARGET_MIPS64)
1986 TCGv t0
= tcg_temp_local_new();
1987 TCGv t1
= tcg_temp_new();
1988 TCGv t2
= tcg_temp_new();
1989 int l1
= gen_new_label();
1991 gen_load_gpr(t1
, rs
);
1992 tcg_gen_addi_tl(t0
, t1
, uimm
);
1994 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1995 tcg_gen_xori_tl(t2
, t0
, uimm
);
1996 tcg_gen_and_tl(t1
, t1
, t2
);
1998 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx
, EXCP_OVERFLOW
);
2003 gen_store_gpr(t0
, rt
);
2010 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2012 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2018 (void)opn
; /* avoid a compiler warning */
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2022 /* Logic with immediate operand */
2023 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2024 int rt
, int rs
, int16_t imm
)
2029 /* If no destination, treat it as a NOP. */
2033 uimm
= (uint16_t)imm
;
2036 if (likely(rs
!= 0))
2037 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2039 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2041 regnames
[rs
], uimm
);
2045 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2047 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2049 regnames
[rs
], uimm
);
2052 if (likely(rs
!= 0))
2053 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2055 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2057 regnames
[rs
], uimm
);
2060 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2070 /* Set on less than with immediate operand */
2071 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2072 int rt
, int rs
, int16_t imm
)
2074 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2075 const char *opn
= "imm arith";
2079 /* If no destination, treat it as a NOP. */
2083 t0
= tcg_temp_new();
2084 gen_load_gpr(t0
, rs
);
2087 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2091 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2095 (void)opn
; /* avoid a compiler warning */
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2100 /* Shifts with immediate operand */
2101 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2102 int rt
, int rs
, int16_t imm
)
2104 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2105 const char *opn
= "imm shift";
2109 /* If no destination, treat it as a NOP. */
2114 t0
= tcg_temp_new();
2115 gen_load_gpr(t0
, rs
);
2118 tcg_gen_shli_tl(t0
, t0
, uimm
);
2119 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2123 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2128 tcg_gen_ext32u_tl(t0
, t0
);
2129 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2131 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2137 TCGv_i32 t1
= tcg_temp_new_i32();
2139 tcg_gen_trunc_tl_i32(t1
, t0
);
2140 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2141 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2142 tcg_temp_free_i32(t1
);
2144 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2148 #if defined(TARGET_MIPS64)
2150 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2154 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2158 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2163 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2165 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2170 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2174 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2178 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2182 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2187 (void)opn
; /* avoid a compiler warning */
2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2193 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2194 int rd
, int rs
, int rt
)
2196 const char *opn
= "arith";
2198 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2199 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
2209 TCGv t0
= tcg_temp_local_new();
2210 TCGv t1
= tcg_temp_new();
2211 TCGv t2
= tcg_temp_new();
2212 int l1
= gen_new_label();
2214 gen_load_gpr(t1
, rs
);
2215 gen_load_gpr(t2
, rt
);
2216 tcg_gen_add_tl(t0
, t1
, t2
);
2217 tcg_gen_ext32s_tl(t0
, t0
);
2218 tcg_gen_xor_tl(t1
, t1
, t2
);
2219 tcg_gen_xor_tl(t2
, t0
, t2
);
2220 tcg_gen_andc_tl(t1
, t2
, t1
);
2222 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx
, EXCP_OVERFLOW
);
2227 gen_store_gpr(t0
, rd
);
2233 if (rs
!= 0 && rt
!= 0) {
2234 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2235 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2236 } else if (rs
== 0 && rt
!= 0) {
2237 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2238 } else if (rs
!= 0 && rt
== 0) {
2239 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2241 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2247 TCGv t0
= tcg_temp_local_new();
2248 TCGv t1
= tcg_temp_new();
2249 TCGv t2
= tcg_temp_new();
2250 int l1
= gen_new_label();
2252 gen_load_gpr(t1
, rs
);
2253 gen_load_gpr(t2
, rt
);
2254 tcg_gen_sub_tl(t0
, t1
, t2
);
2255 tcg_gen_ext32s_tl(t0
, t0
);
2256 tcg_gen_xor_tl(t2
, t1
, t2
);
2257 tcg_gen_xor_tl(t1
, t0
, t1
);
2258 tcg_gen_and_tl(t1
, t1
, t2
);
2260 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2262 /* operands of different sign, first operand and result different sign */
2263 generate_exception(ctx
, EXCP_OVERFLOW
);
2265 gen_store_gpr(t0
, rd
);
2271 if (rs
!= 0 && rt
!= 0) {
2272 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2273 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2274 } else if (rs
== 0 && rt
!= 0) {
2275 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2276 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2277 } else if (rs
!= 0 && rt
== 0) {
2278 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2280 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2284 #if defined(TARGET_MIPS64)
2287 TCGv t0
= tcg_temp_local_new();
2288 TCGv t1
= tcg_temp_new();
2289 TCGv t2
= tcg_temp_new();
2290 int l1
= gen_new_label();
2292 gen_load_gpr(t1
, rs
);
2293 gen_load_gpr(t2
, rt
);
2294 tcg_gen_add_tl(t0
, t1
, t2
);
2295 tcg_gen_xor_tl(t1
, t1
, t2
);
2296 tcg_gen_xor_tl(t2
, t0
, t2
);
2297 tcg_gen_andc_tl(t1
, t2
, t1
);
2299 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx
, EXCP_OVERFLOW
);
2304 gen_store_gpr(t0
, rd
);
2310 if (rs
!= 0 && rt
!= 0) {
2311 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2312 } else if (rs
== 0 && rt
!= 0) {
2313 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2314 } else if (rs
!= 0 && rt
== 0) {
2315 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2317 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2323 TCGv t0
= tcg_temp_local_new();
2324 TCGv t1
= tcg_temp_new();
2325 TCGv t2
= tcg_temp_new();
2326 int l1
= gen_new_label();
2328 gen_load_gpr(t1
, rs
);
2329 gen_load_gpr(t2
, rt
);
2330 tcg_gen_sub_tl(t0
, t1
, t2
);
2331 tcg_gen_xor_tl(t2
, t1
, t2
);
2332 tcg_gen_xor_tl(t1
, t0
, t1
);
2333 tcg_gen_and_tl(t1
, t1
, t2
);
2335 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2337 /* operands of different sign, first operand and result different sign */
2338 generate_exception(ctx
, EXCP_OVERFLOW
);
2340 gen_store_gpr(t0
, rd
);
2346 if (rs
!= 0 && rt
!= 0) {
2347 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2348 } else if (rs
== 0 && rt
!= 0) {
2349 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2350 } else if (rs
!= 0 && rt
== 0) {
2351 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2353 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2359 if (likely(rs
!= 0 && rt
!= 0)) {
2360 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2361 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2363 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2368 (void)opn
; /* avoid a compiler warning */
2369 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2372 /* Conditional move */
2373 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2374 int rd
, int rs
, int rt
)
2376 const char *opn
= "cond move";
2380 /* If no destination, treat it as a NOP. */
2385 t0
= tcg_temp_new();
2386 gen_load_gpr(t0
, rt
);
2387 t1
= tcg_const_tl(0);
2388 t2
= tcg_temp_new();
2389 gen_load_gpr(t2
, rs
);
2392 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2396 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2404 (void)opn
; /* avoid a compiler warning */
2405 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2409 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2410 int rd
, int rs
, int rt
)
2412 const char *opn
= "logic";
2415 /* If no destination, treat it as a NOP. */
2422 if (likely(rs
!= 0 && rt
!= 0)) {
2423 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2425 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2430 if (rs
!= 0 && rt
!= 0) {
2431 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2432 } else if (rs
== 0 && rt
!= 0) {
2433 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2434 } else if (rs
!= 0 && rt
== 0) {
2435 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2437 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2442 if (likely(rs
!= 0 && rt
!= 0)) {
2443 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2444 } else if (rs
== 0 && rt
!= 0) {
2445 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2446 } else if (rs
!= 0 && rt
== 0) {
2447 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2449 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2454 if (likely(rs
!= 0 && rt
!= 0)) {
2455 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2456 } else if (rs
== 0 && rt
!= 0) {
2457 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2458 } else if (rs
!= 0 && rt
== 0) {
2459 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2461 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2466 (void)opn
; /* avoid a compiler warning */
2467 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2470 /* Set on lower than */
2471 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2472 int rd
, int rs
, int rt
)
2474 const char *opn
= "slt";
2478 /* If no destination, treat it as a NOP. */
2483 t0
= tcg_temp_new();
2484 t1
= tcg_temp_new();
2485 gen_load_gpr(t0
, rs
);
2486 gen_load_gpr(t1
, rt
);
2489 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2493 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2497 (void)opn
; /* avoid a compiler warning */
2498 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2504 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2505 int rd
, int rs
, int rt
)
2507 const char *opn
= "shifts";
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2517 t0
= tcg_temp_new();
2518 t1
= tcg_temp_new();
2519 gen_load_gpr(t0
, rs
);
2520 gen_load_gpr(t1
, rt
);
2523 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2524 tcg_gen_shl_tl(t0
, t1
, t0
);
2525 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2529 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2530 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2534 tcg_gen_ext32u_tl(t1
, t1
);
2535 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2536 tcg_gen_shr_tl(t0
, t1
, t0
);
2537 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2542 TCGv_i32 t2
= tcg_temp_new_i32();
2543 TCGv_i32 t3
= tcg_temp_new_i32();
2545 tcg_gen_trunc_tl_i32(t2
, t0
);
2546 tcg_gen_trunc_tl_i32(t3
, t1
);
2547 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2548 tcg_gen_rotr_i32(t2
, t3
, t2
);
2549 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2550 tcg_temp_free_i32(t2
);
2551 tcg_temp_free_i32(t3
);
2555 #if defined(TARGET_MIPS64)
2557 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2558 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2562 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2563 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2567 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2572 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2578 (void)opn
; /* avoid a compiler warning */
2579 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2584 /* Arithmetic on HI/LO registers */
2585 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2587 const char *opn
= "hilo";
2589 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2601 #if defined(TARGET_MIPS64)
2603 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2607 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2612 #if defined(TARGET_MIPS64)
2614 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2618 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2624 #if defined(TARGET_MIPS64)
2626 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2630 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2633 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2639 #if defined(TARGET_MIPS64)
2641 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2645 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2648 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2653 (void)opn
; /* avoid a compiler warning */
2654 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2657 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2658 int acc
, int rs
, int rt
)
2660 const char *opn
= "mul/div";
2663 t0
= tcg_temp_new();
2664 t1
= tcg_temp_new();
2666 gen_load_gpr(t0
, rs
);
2667 gen_load_gpr(t1
, rt
);
2676 TCGv t2
= tcg_temp_new();
2677 TCGv t3
= tcg_temp_new();
2678 tcg_gen_ext32s_tl(t0
, t0
);
2679 tcg_gen_ext32s_tl(t1
, t1
);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2681 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2682 tcg_gen_and_tl(t2
, t2
, t3
);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2684 tcg_gen_or_tl(t2
, t2
, t3
);
2685 tcg_gen_movi_tl(t3
, 0);
2686 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2687 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2688 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2689 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2690 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2698 TCGv t2
= tcg_const_tl(0);
2699 TCGv t3
= tcg_const_tl(1);
2700 tcg_gen_ext32u_tl(t0
, t0
);
2701 tcg_gen_ext32u_tl(t1
, t1
);
2702 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2703 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2704 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2705 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2706 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2714 TCGv_i32 t2
= tcg_temp_new_i32();
2715 TCGv_i32 t3
= tcg_temp_new_i32();
2716 tcg_gen_trunc_tl_i32(t2
, t0
);
2717 tcg_gen_trunc_tl_i32(t3
, t1
);
2718 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2719 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2720 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2721 tcg_temp_free_i32(t2
);
2722 tcg_temp_free_i32(t3
);
2728 TCGv_i32 t2
= tcg_temp_new_i32();
2729 TCGv_i32 t3
= tcg_temp_new_i32();
2730 tcg_gen_trunc_tl_i32(t2
, t0
);
2731 tcg_gen_trunc_tl_i32(t3
, t1
);
2732 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2733 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2734 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2735 tcg_temp_free_i32(t2
);
2736 tcg_temp_free_i32(t3
);
2740 #if defined(TARGET_MIPS64)
2743 TCGv t2
= tcg_temp_new();
2744 TCGv t3
= tcg_temp_new();
2745 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2747 tcg_gen_and_tl(t2
, t2
, t3
);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2749 tcg_gen_or_tl(t2
, t2
, t3
);
2750 tcg_gen_movi_tl(t3
, 0);
2751 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2752 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2753 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2761 TCGv t2
= tcg_const_tl(0);
2762 TCGv t3
= tcg_const_tl(1);
2763 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2764 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2765 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2772 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2776 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2782 TCGv_i64 t2
= tcg_temp_new_i64();
2783 TCGv_i64 t3
= tcg_temp_new_i64();
2785 tcg_gen_ext_tl_i64(t2
, t0
);
2786 tcg_gen_ext_tl_i64(t3
, t1
);
2787 tcg_gen_mul_i64(t2
, t2
, t3
);
2788 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2789 tcg_gen_add_i64(t2
, t2
, t3
);
2790 tcg_temp_free_i64(t3
);
2791 tcg_gen_trunc_i64_tl(t0
, t2
);
2792 tcg_gen_shri_i64(t2
, t2
, 32);
2793 tcg_gen_trunc_i64_tl(t1
, t2
);
2794 tcg_temp_free_i64(t2
);
2795 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2796 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2802 TCGv_i64 t2
= tcg_temp_new_i64();
2803 TCGv_i64 t3
= tcg_temp_new_i64();
2805 tcg_gen_ext32u_tl(t0
, t0
);
2806 tcg_gen_ext32u_tl(t1
, t1
);
2807 tcg_gen_extu_tl_i64(t2
, t0
);
2808 tcg_gen_extu_tl_i64(t3
, t1
);
2809 tcg_gen_mul_i64(t2
, t2
, t3
);
2810 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2811 tcg_gen_add_i64(t2
, t2
, t3
);
2812 tcg_temp_free_i64(t3
);
2813 tcg_gen_trunc_i64_tl(t0
, t2
);
2814 tcg_gen_shri_i64(t2
, t2
, 32);
2815 tcg_gen_trunc_i64_tl(t1
, t2
);
2816 tcg_temp_free_i64(t2
);
2817 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2818 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2824 TCGv_i64 t2
= tcg_temp_new_i64();
2825 TCGv_i64 t3
= tcg_temp_new_i64();
2827 tcg_gen_ext_tl_i64(t2
, t0
);
2828 tcg_gen_ext_tl_i64(t3
, t1
);
2829 tcg_gen_mul_i64(t2
, t2
, t3
);
2830 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2831 tcg_gen_sub_i64(t2
, t3
, t2
);
2832 tcg_temp_free_i64(t3
);
2833 tcg_gen_trunc_i64_tl(t0
, t2
);
2834 tcg_gen_shri_i64(t2
, t2
, 32);
2835 tcg_gen_trunc_i64_tl(t1
, t2
);
2836 tcg_temp_free_i64(t2
);
2837 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2838 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2844 TCGv_i64 t2
= tcg_temp_new_i64();
2845 TCGv_i64 t3
= tcg_temp_new_i64();
2847 tcg_gen_ext32u_tl(t0
, t0
);
2848 tcg_gen_ext32u_tl(t1
, t1
);
2849 tcg_gen_extu_tl_i64(t2
, t0
);
2850 tcg_gen_extu_tl_i64(t3
, t1
);
2851 tcg_gen_mul_i64(t2
, t2
, t3
);
2852 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2853 tcg_gen_sub_i64(t2
, t3
, t2
);
2854 tcg_temp_free_i64(t3
);
2855 tcg_gen_trunc_i64_tl(t0
, t2
);
2856 tcg_gen_shri_i64(t2
, t2
, 32);
2857 tcg_gen_trunc_i64_tl(t1
, t2
);
2858 tcg_temp_free_i64(t2
);
2859 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2860 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2866 generate_exception(ctx
, EXCP_RI
);
2869 (void)opn
; /* avoid a compiler warning */
2870 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2876 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2877 int rd
, int rs
, int rt
)
2879 const char *opn
= "mul vr54xx";
2880 TCGv t0
= tcg_temp_new();
2881 TCGv t1
= tcg_temp_new();
2883 gen_load_gpr(t0
, rs
);
2884 gen_load_gpr(t1
, rt
);
2887 case OPC_VR54XX_MULS
:
2888 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2891 case OPC_VR54XX_MULSU
:
2892 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2895 case OPC_VR54XX_MACC
:
2896 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2899 case OPC_VR54XX_MACCU
:
2900 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2903 case OPC_VR54XX_MSAC
:
2904 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2907 case OPC_VR54XX_MSACU
:
2908 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2911 case OPC_VR54XX_MULHI
:
2912 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2915 case OPC_VR54XX_MULHIU
:
2916 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2919 case OPC_VR54XX_MULSHI
:
2920 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2923 case OPC_VR54XX_MULSHIU
:
2924 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2927 case OPC_VR54XX_MACCHI
:
2928 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2931 case OPC_VR54XX_MACCHIU
:
2932 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2935 case OPC_VR54XX_MSACHI
:
2936 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2939 case OPC_VR54XX_MSACHIU
:
2940 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2944 MIPS_INVAL("mul vr54xx");
2945 generate_exception(ctx
, EXCP_RI
);
2948 gen_store_gpr(t0
, rd
);
2949 (void)opn
; /* avoid a compiler warning */
2950 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2957 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2960 const char *opn
= "CLx";
2968 t0
= tcg_temp_new();
2969 gen_load_gpr(t0
, rs
);
2972 gen_helper_clo(cpu_gpr
[rd
], t0
);
2976 gen_helper_clz(cpu_gpr
[rd
], t0
);
2979 #if defined(TARGET_MIPS64)
2981 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2985 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2990 (void)opn
; /* avoid a compiler warning */
2991 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2995 /* Godson integer instructions */
2996 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2997 int rd
, int rs
, int rt
)
2999 const char *opn
= "loongson";
3011 case OPC_MULTU_G_2E
:
3012 case OPC_MULTU_G_2F
:
3013 #if defined(TARGET_MIPS64)
3014 case OPC_DMULT_G_2E
:
3015 case OPC_DMULT_G_2F
:
3016 case OPC_DMULTU_G_2E
:
3017 case OPC_DMULTU_G_2F
:
3019 t0
= tcg_temp_new();
3020 t1
= tcg_temp_new();
3023 t0
= tcg_temp_local_new();
3024 t1
= tcg_temp_local_new();
3028 gen_load_gpr(t0
, rs
);
3029 gen_load_gpr(t1
, rt
);
3034 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3035 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3038 case OPC_MULTU_G_2E
:
3039 case OPC_MULTU_G_2F
:
3040 tcg_gen_ext32u_tl(t0
, t0
);
3041 tcg_gen_ext32u_tl(t1
, t1
);
3042 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3043 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3049 int l1
= gen_new_label();
3050 int l2
= gen_new_label();
3051 int l3
= gen_new_label();
3052 tcg_gen_ext32s_tl(t0
, t0
);
3053 tcg_gen_ext32s_tl(t1
, t1
);
3054 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3055 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3058 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3059 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3060 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3063 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3064 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3072 int l1
= gen_new_label();
3073 int l2
= gen_new_label();
3074 tcg_gen_ext32u_tl(t0
, t0
);
3075 tcg_gen_ext32u_tl(t1
, t1
);
3076 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3077 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3080 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3081 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3089 int l1
= gen_new_label();
3090 int l2
= gen_new_label();
3091 int l3
= gen_new_label();
3092 tcg_gen_ext32u_tl(t0
, t0
);
3093 tcg_gen_ext32u_tl(t1
, t1
);
3094 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3095 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3096 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3098 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3101 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3102 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3110 int l1
= gen_new_label();
3111 int l2
= gen_new_label();
3112 tcg_gen_ext32u_tl(t0
, t0
);
3113 tcg_gen_ext32u_tl(t1
, t1
);
3114 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3115 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3118 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3119 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3124 #if defined(TARGET_MIPS64)
3125 case OPC_DMULT_G_2E
:
3126 case OPC_DMULT_G_2F
:
3127 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3130 case OPC_DMULTU_G_2E
:
3131 case OPC_DMULTU_G_2F
:
3132 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3138 int l1
= gen_new_label();
3139 int l2
= gen_new_label();
3140 int l3
= gen_new_label();
3141 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3142 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3145 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3146 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3147 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3150 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3155 case OPC_DDIVU_G_2E
:
3156 case OPC_DDIVU_G_2F
:
3158 int l1
= gen_new_label();
3159 int l2
= gen_new_label();
3160 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3161 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3164 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3172 int l1
= gen_new_label();
3173 int l2
= gen_new_label();
3174 int l3
= gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3176 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3177 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3179 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3182 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3187 case OPC_DMODU_G_2E
:
3188 case OPC_DMODU_G_2F
:
3190 int l1
= gen_new_label();
3191 int l2
= gen_new_label();
3192 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3193 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3196 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3204 (void)opn
; /* avoid a compiler warning */
3205 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3210 /* Loongson multimedia instructions */
3211 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3213 const char *opn
= "loongson_cp2";
3214 uint32_t opc
, shift_max
;
3217 opc
= MASK_LMI(ctx
->opcode
);
3223 t0
= tcg_temp_local_new_i64();
3224 t1
= tcg_temp_local_new_i64();
3227 t0
= tcg_temp_new_i64();
3228 t1
= tcg_temp_new_i64();
3232 gen_load_fpr64(ctx
, t0
, rs
);
3233 gen_load_fpr64(ctx
, t1
, rt
);
3235 #define LMI_HELPER(UP, LO) \
3236 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237 #define LMI_HELPER_1(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239 #define LMI_DIRECT(UP, LO, OP) \
3240 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3243 LMI_HELPER(PADDSH
, paddsh
);
3244 LMI_HELPER(PADDUSH
, paddush
);
3245 LMI_HELPER(PADDH
, paddh
);
3246 LMI_HELPER(PADDW
, paddw
);
3247 LMI_HELPER(PADDSB
, paddsb
);
3248 LMI_HELPER(PADDUSB
, paddusb
);
3249 LMI_HELPER(PADDB
, paddb
);
3251 LMI_HELPER(PSUBSH
, psubsh
);
3252 LMI_HELPER(PSUBUSH
, psubush
);
3253 LMI_HELPER(PSUBH
, psubh
);
3254 LMI_HELPER(PSUBW
, psubw
);
3255 LMI_HELPER(PSUBSB
, psubsb
);
3256 LMI_HELPER(PSUBUSB
, psubusb
);
3257 LMI_HELPER(PSUBB
, psubb
);
3259 LMI_HELPER(PSHUFH
, pshufh
);
3260 LMI_HELPER(PACKSSWH
, packsswh
);
3261 LMI_HELPER(PACKSSHB
, packsshb
);
3262 LMI_HELPER(PACKUSHB
, packushb
);
3264 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3265 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3266 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3267 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3268 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3269 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3271 LMI_HELPER(PAVGH
, pavgh
);
3272 LMI_HELPER(PAVGB
, pavgb
);
3273 LMI_HELPER(PMAXSH
, pmaxsh
);
3274 LMI_HELPER(PMINSH
, pminsh
);
3275 LMI_HELPER(PMAXUB
, pmaxub
);
3276 LMI_HELPER(PMINUB
, pminub
);
3278 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3279 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3280 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3281 LMI_HELPER(PCMPGTH
, pcmpgth
);
3282 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3283 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3285 LMI_HELPER(PSLLW
, psllw
);
3286 LMI_HELPER(PSLLH
, psllh
);
3287 LMI_HELPER(PSRLW
, psrlw
);
3288 LMI_HELPER(PSRLH
, psrlh
);
3289 LMI_HELPER(PSRAW
, psraw
);
3290 LMI_HELPER(PSRAH
, psrah
);
3292 LMI_HELPER(PMULLH
, pmullh
);
3293 LMI_HELPER(PMULHH
, pmulhh
);
3294 LMI_HELPER(PMULHUH
, pmulhuh
);
3295 LMI_HELPER(PMADDHW
, pmaddhw
);
3297 LMI_HELPER(PASUBUB
, pasubub
);
3298 LMI_HELPER_1(BIADD
, biadd
);
3299 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3301 LMI_DIRECT(PADDD
, paddd
, add
);
3302 LMI_DIRECT(PSUBD
, psubd
, sub
);
3303 LMI_DIRECT(XOR_CP2
, xor, xor);
3304 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3305 LMI_DIRECT(AND_CP2
, and, and);
3306 LMI_DIRECT(PANDN
, pandn
, andc
);
3307 LMI_DIRECT(OR
, or, or);
3310 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3314 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3318 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3322 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3327 tcg_gen_andi_i64(t1
, t1
, 3);
3328 tcg_gen_shli_i64(t1
, t1
, 4);
3329 tcg_gen_shr_i64(t0
, t0
, t1
);
3330 tcg_gen_ext16u_i64(t0
, t0
);
3335 tcg_gen_add_i64(t0
, t0
, t1
);
3336 tcg_gen_ext32s_i64(t0
, t0
);
3340 tcg_gen_sub_i64(t0
, t0
, t1
);
3341 tcg_gen_ext32s_i64(t0
, t0
);
3370 /* Make sure shift count isn't TCG undefined behaviour. */
3371 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3376 tcg_gen_shl_i64(t0
, t0
, t1
);
3380 /* Since SRA is UndefinedResult without sign-extended inputs,
3381 we can treat SRA and DSRA the same. */
3382 tcg_gen_sar_i64(t0
, t0
, t1
);
3385 /* We want to shift in zeros for SRL; zero-extend first. */
3386 tcg_gen_ext32u_i64(t0
, t0
);
3389 tcg_gen_shr_i64(t0
, t0
, t1
);
3393 if (shift_max
== 32) {
3394 tcg_gen_ext32s_i64(t0
, t0
);
3397 /* Shifts larger than MAX produce zero. */
3398 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3399 tcg_gen_neg_i64(t1
, t1
);
3400 tcg_gen_and_i64(t0
, t0
, t1
);
3406 TCGv_i64 t2
= tcg_temp_new_i64();
3407 int lab
= gen_new_label();
3409 tcg_gen_mov_i64(t2
, t0
);
3410 tcg_gen_add_i64(t0
, t1
, t2
);
3411 if (opc
== OPC_ADD_CP2
) {
3412 tcg_gen_ext32s_i64(t0
, t0
);
3414 tcg_gen_xor_i64(t1
, t1
, t2
);
3415 tcg_gen_xor_i64(t2
, t2
, t0
);
3416 tcg_gen_andc_i64(t1
, t2
, t1
);
3417 tcg_temp_free_i64(t2
);
3418 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3419 generate_exception(ctx
, EXCP_OVERFLOW
);
3422 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3429 TCGv_i64 t2
= tcg_temp_new_i64();
3430 int lab
= gen_new_label();
3432 tcg_gen_mov_i64(t2
, t0
);
3433 tcg_gen_sub_i64(t0
, t1
, t2
);
3434 if (opc
== OPC_SUB_CP2
) {
3435 tcg_gen_ext32s_i64(t0
, t0
);
3437 tcg_gen_xor_i64(t1
, t1
, t2
);
3438 tcg_gen_xor_i64(t2
, t2
, t0
);
3439 tcg_gen_and_i64(t1
, t1
, t2
);
3440 tcg_temp_free_i64(t2
);
3441 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3442 generate_exception(ctx
, EXCP_OVERFLOW
);
3445 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3450 tcg_gen_ext32u_i64(t0
, t0
);
3451 tcg_gen_ext32u_i64(t1
, t1
);
3452 tcg_gen_mul_i64(t0
, t0
, t1
);
3462 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3463 FD field is the CC field? */
3466 generate_exception(ctx
, EXCP_RI
);
3473 gen_store_fpr64(ctx
, t0
, rd
);
3475 (void)opn
; /* avoid a compiler warning */
3476 MIPS_DEBUG("%s %s, %s, %s", opn
,
3477 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3478 tcg_temp_free_i64(t0
);
3479 tcg_temp_free_i64(t1
);
3483 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3484 int rs
, int rt
, int16_t imm
)
3487 TCGv t0
= tcg_temp_new();
3488 TCGv t1
= tcg_temp_new();
3491 /* Load needed operands */
3499 /* Compare two registers */
3501 gen_load_gpr(t0
, rs
);
3502 gen_load_gpr(t1
, rt
);
3512 /* Compare register to immediate */
3513 if (rs
!= 0 || imm
!= 0) {
3514 gen_load_gpr(t0
, rs
);
3515 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3522 case OPC_TEQ
: /* rs == rs */
3523 case OPC_TEQI
: /* r0 == 0 */
3524 case OPC_TGE
: /* rs >= rs */
3525 case OPC_TGEI
: /* r0 >= 0 */
3526 case OPC_TGEU
: /* rs >= rs unsigned */
3527 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3529 generate_exception(ctx
, EXCP_TRAP
);
3531 case OPC_TLT
: /* rs < rs */
3532 case OPC_TLTI
: /* r0 < 0 */
3533 case OPC_TLTU
: /* rs < rs unsigned */
3534 case OPC_TLTIU
: /* r0 < 0 unsigned */
3535 case OPC_TNE
: /* rs != rs */
3536 case OPC_TNEI
: /* r0 != 0 */
3537 /* Never trap: treat as NOP. */
3541 int l1
= gen_new_label();
3546 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3550 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3554 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3558 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3562 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3566 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3569 generate_exception(ctx
, EXCP_TRAP
);
3576 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3578 TranslationBlock
*tb
;
3580 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3581 likely(!ctx
->singlestep_enabled
)) {
3584 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3587 if (ctx
->singlestep_enabled
) {
3588 save_cpu_state(ctx
, 0);
3589 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3595 /* Branches (before delay slot) */
3596 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3598 int rs
, int rt
, int32_t offset
)
3600 target_ulong btgt
= -1;
3602 int bcond_compute
= 0;
3603 TCGv t0
= tcg_temp_new();
3604 TCGv t1
= tcg_temp_new();
3606 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3607 #ifdef MIPS_DEBUG_DISAS
3608 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3610 generate_exception(ctx
, EXCP_RI
);
3614 /* Load needed operands */
3620 /* Compare two registers */
3622 gen_load_gpr(t0
, rs
);
3623 gen_load_gpr(t1
, rt
);
3626 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3642 /* Compare to zero */
3644 gen_load_gpr(t0
, rs
);
3647 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3650 #if defined(TARGET_MIPS64)
3652 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3654 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3657 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3664 /* Jump to immediate */
3665 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3671 /* Jump to register */
3672 if (offset
!= 0 && offset
!= 16) {
3673 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3674 others are reserved. */
3675 MIPS_INVAL("jump hint");
3676 generate_exception(ctx
, EXCP_RI
);
3679 gen_load_gpr(btarget
, rs
);
3682 MIPS_INVAL("branch/jump");
3683 generate_exception(ctx
, EXCP_RI
);
3686 if (bcond_compute
== 0) {
3687 /* No condition to be computed */
3689 case OPC_BEQ
: /* rx == rx */
3690 case OPC_BEQL
: /* rx == rx likely */
3691 case OPC_BGEZ
: /* 0 >= 0 */
3692 case OPC_BGEZL
: /* 0 >= 0 likely */
3693 case OPC_BLEZ
: /* 0 <= 0 */
3694 case OPC_BLEZL
: /* 0 <= 0 likely */
3696 ctx
->hflags
|= MIPS_HFLAG_B
;
3697 MIPS_DEBUG("balways");
3700 case OPC_BGEZAL
: /* 0 >= 0 */
3701 case OPC_BGEZALL
: /* 0 >= 0 likely */
3702 ctx
->hflags
|= (opc
== OPC_BGEZALS
3704 : MIPS_HFLAG_BDS32
);
3705 /* Always take and link */
3707 ctx
->hflags
|= MIPS_HFLAG_B
;
3708 MIPS_DEBUG("balways and link");
3710 case OPC_BNE
: /* rx != rx */
3711 case OPC_BGTZ
: /* 0 > 0 */
3712 case OPC_BLTZ
: /* 0 < 0 */
3714 MIPS_DEBUG("bnever (NOP)");
3717 case OPC_BLTZAL
: /* 0 < 0 */
3718 ctx
->hflags
|= (opc
== OPC_BLTZALS
3720 : MIPS_HFLAG_BDS32
);
3721 /* Handle as an unconditional branch to get correct delay
3724 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3725 ctx
->hflags
|= MIPS_HFLAG_B
;
3726 MIPS_DEBUG("bnever and link");
3728 case OPC_BLTZALL
: /* 0 < 0 likely */
3729 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3730 /* Skip the instruction in the delay slot */
3731 MIPS_DEBUG("bnever, link and skip");
3734 case OPC_BNEL
: /* rx != rx likely */
3735 case OPC_BGTZL
: /* 0 > 0 likely */
3736 case OPC_BLTZL
: /* 0 < 0 likely */
3737 /* Skip the instruction in the delay slot */
3738 MIPS_DEBUG("bnever and skip");
3742 ctx
->hflags
|= MIPS_HFLAG_B
;
3743 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3747 ctx
->hflags
|= MIPS_HFLAG_BX
;
3752 ctx
->hflags
|= MIPS_HFLAG_B
;
3753 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3755 : MIPS_HFLAG_BDS32
);
3756 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3759 ctx
->hflags
|= MIPS_HFLAG_BR
;
3760 if (insn_bytes
== 4)
3761 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3762 MIPS_DEBUG("jr %s", regnames
[rs
]);
3768 ctx
->hflags
|= MIPS_HFLAG_BR
;
3769 ctx
->hflags
|= (opc
== OPC_JALRS
3771 : MIPS_HFLAG_BDS32
);
3772 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3775 MIPS_INVAL("branch/jump");
3776 generate_exception(ctx
, EXCP_RI
);
3782 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3783 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3784 regnames
[rs
], regnames
[rt
], btgt
);
3787 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3788 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3789 regnames
[rs
], regnames
[rt
], btgt
);
3792 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3793 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3794 regnames
[rs
], regnames
[rt
], btgt
);
3797 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3798 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3799 regnames
[rs
], regnames
[rt
], btgt
);
3802 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3803 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3806 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3807 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3811 ctx
->hflags
|= (opc
== OPC_BGEZALS
3813 : MIPS_HFLAG_BDS32
);
3814 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3815 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3819 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3821 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3824 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3825 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3828 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3829 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3832 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3833 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3836 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3837 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3840 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3841 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3844 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3845 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3848 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3849 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3851 #if defined(TARGET_MIPS64)
3853 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3854 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3859 ctx
->hflags
|= (opc
== OPC_BLTZALS
3861 : MIPS_HFLAG_BDS32
);
3862 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3864 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3866 ctx
->hflags
|= MIPS_HFLAG_BC
;
3869 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3871 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3873 ctx
->hflags
|= MIPS_HFLAG_BL
;
3876 MIPS_INVAL("conditional branch/jump");
3877 generate_exception(ctx
, EXCP_RI
);
3881 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3882 blink
, ctx
->hflags
, btgt
);
3884 ctx
->btarget
= btgt
;
3886 int post_delay
= insn_bytes
;
3887 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3889 if (opc
!= OPC_JALRC
)
3890 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3892 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3896 if (insn_bytes
== 2)
3897 ctx
->hflags
|= MIPS_HFLAG_B16
;
3902 /* special3 bitfield operations */
3903 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3904 int rs
, int lsb
, int msb
)
3906 TCGv t0
= tcg_temp_new();
3907 TCGv t1
= tcg_temp_new();
3909 gen_load_gpr(t1
, rs
);
3914 tcg_gen_shri_tl(t0
, t1
, lsb
);
3916 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3918 tcg_gen_ext32s_tl(t0
, t0
);
3921 #if defined(TARGET_MIPS64)
3923 tcg_gen_shri_tl(t0
, t1
, lsb
);
3925 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3929 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3930 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3933 tcg_gen_shri_tl(t0
, t1
, lsb
);
3934 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3940 gen_load_gpr(t0
, rt
);
3941 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3942 tcg_gen_ext32s_tl(t0
, t0
);
3944 #if defined(TARGET_MIPS64)
3946 gen_load_gpr(t0
, rt
);
3947 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3950 gen_load_gpr(t0
, rt
);
3951 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3954 gen_load_gpr(t0
, rt
);
3955 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3960 MIPS_INVAL("bitops");
3961 generate_exception(ctx
, EXCP_RI
);
3966 gen_store_gpr(t0
, rt
);
3971 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3976 /* If no destination, treat it as a NOP. */
3981 t0
= tcg_temp_new();
3982 gen_load_gpr(t0
, rt
);
3986 TCGv t1
= tcg_temp_new();
3988 tcg_gen_shri_tl(t1
, t0
, 8);
3989 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3990 tcg_gen_shli_tl(t0
, t0
, 8);
3991 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3992 tcg_gen_or_tl(t0
, t0
, t1
);
3994 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3998 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4001 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4003 #if defined(TARGET_MIPS64)
4006 TCGv t1
= tcg_temp_new();
4008 tcg_gen_shri_tl(t1
, t0
, 8);
4009 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4010 tcg_gen_shli_tl(t0
, t0
, 8);
4011 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4012 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4018 TCGv t1
= tcg_temp_new();
4020 tcg_gen_shri_tl(t1
, t0
, 16);
4021 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4022 tcg_gen_shli_tl(t0
, t0
, 16);
4023 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4024 tcg_gen_or_tl(t0
, t0
, t1
);
4025 tcg_gen_shri_tl(t1
, t0
, 32);
4026 tcg_gen_shli_tl(t0
, t0
, 32);
4027 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4033 MIPS_INVAL("bsfhl");
4034 generate_exception(ctx
, EXCP_RI
);
4041 #ifndef CONFIG_USER_ONLY
4042 /* CP0 (MMU and control) */
4043 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4045 TCGv_i32 t0
= tcg_temp_new_i32();
4047 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4048 tcg_gen_ext_i32_tl(arg
, t0
);
4049 tcg_temp_free_i32(t0
);
4052 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4054 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4055 tcg_gen_ext32s_tl(arg
, arg
);
4058 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4060 TCGv_i32 t0
= tcg_temp_new_i32();
4062 tcg_gen_trunc_tl_i32(t0
, arg
);
4063 tcg_gen_st_i32(t0
, cpu_env
, off
);
4064 tcg_temp_free_i32(t0
);
4067 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4069 tcg_gen_ext32s_tl(arg
, arg
);
4070 tcg_gen_st_tl(arg
, cpu_env
, off
);
4073 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4075 const char *rn
= "invalid";
4078 check_insn(ctx
, ISA_MIPS32
);
4084 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4088 check_insn(ctx
, ASE_MT
);
4089 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4093 check_insn(ctx
, ASE_MT
);
4094 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4098 check_insn(ctx
, ASE_MT
);
4099 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4109 gen_helper_mfc0_random(arg
, cpu_env
);
4113 check_insn(ctx
, ASE_MT
);
4114 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4118 check_insn(ctx
, ASE_MT
);
4119 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4123 check_insn(ctx
, ASE_MT
);
4124 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4128 check_insn(ctx
, ASE_MT
);
4129 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4133 check_insn(ctx
, ASE_MT
);
4134 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4138 check_insn(ctx
, ASE_MT
);
4139 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4140 rn
= "VPEScheFBack";
4143 check_insn(ctx
, ASE_MT
);
4144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4154 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4155 tcg_gen_ext32s_tl(arg
, arg
);
4159 check_insn(ctx
, ASE_MT
);
4160 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4164 check_insn(ctx
, ASE_MT
);
4165 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4169 check_insn(ctx
, ASE_MT
);
4170 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4174 check_insn(ctx
, ASE_MT
);
4175 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4179 check_insn(ctx
, ASE_MT
);
4180 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4184 check_insn(ctx
, ASE_MT
);
4185 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4189 check_insn(ctx
, ASE_MT
);
4190 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4200 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4201 tcg_gen_ext32s_tl(arg
, arg
);
4211 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4212 tcg_gen_ext32s_tl(arg
, arg
);
4216 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4217 rn
= "ContextConfig";
4226 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4230 check_insn(ctx
, ISA_MIPS32R2
);
4231 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4245 check_insn(ctx
, ISA_MIPS32R2
);
4246 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4250 check_insn(ctx
, ISA_MIPS32R2
);
4251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4255 check_insn(ctx
, ISA_MIPS32R2
);
4256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4260 check_insn(ctx
, ISA_MIPS32R2
);
4261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4265 check_insn(ctx
, ISA_MIPS32R2
);
4266 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4276 check_insn(ctx
, ISA_MIPS32R2
);
4277 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4287 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4288 tcg_gen_ext32s_tl(arg
, arg
);
4298 /* Mark as an IO operation because we read the time. */
4301 gen_helper_mfc0_count(arg
, cpu_env
);
4305 /* Break the TB to be able to take timer interrupts immediately
4306 after reading count. */
4307 ctx
->bstate
= BS_STOP
;
4310 /* 6,7 are implementation dependent */
4318 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4319 tcg_gen_ext32s_tl(arg
, arg
);
4329 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4332 /* 6,7 are implementation dependent */
4340 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4344 check_insn(ctx
, ISA_MIPS32R2
);
4345 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4349 check_insn(ctx
, ISA_MIPS32R2
);
4350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4354 check_insn(ctx
, ISA_MIPS32R2
);
4355 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4375 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4376 tcg_gen_ext32s_tl(arg
, arg
);
4386 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4390 check_insn(ctx
, ISA_MIPS32R2
);
4391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4416 /* 4,5 are reserved */
4417 /* 6,7 are implementation dependent */
4419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4423 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4433 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4443 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4453 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4463 #if defined(TARGET_MIPS64)
4464 check_insn(ctx
, ISA_MIPS3
);
4465 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4466 tcg_gen_ext32s_tl(arg
, arg
);
4475 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4478 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4486 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4487 rn
= "'Diagnostic"; /* implementation dependent */
4492 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4496 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4497 rn
= "TraceControl";
4500 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4501 rn
= "TraceControl2";
4504 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4505 rn
= "UserTraceData";
4508 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4519 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4520 tcg_gen_ext32s_tl(arg
, arg
);
4530 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4531 rn
= "Performance0";
4534 // gen_helper_mfc0_performance1(arg);
4535 rn
= "Performance1";
4538 // gen_helper_mfc0_performance2(arg);
4539 rn
= "Performance2";
4542 // gen_helper_mfc0_performance3(arg);
4543 rn
= "Performance3";
4546 // gen_helper_mfc0_performance4(arg);
4547 rn
= "Performance4";
4550 // gen_helper_mfc0_performance5(arg);
4551 rn
= "Performance5";
4554 // gen_helper_mfc0_performance6(arg);
4555 rn
= "Performance6";
4558 // gen_helper_mfc0_performance7(arg);
4559 rn
= "Performance7";
4566 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4572 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4622 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4623 tcg_gen_ext32s_tl(arg
, arg
);
4634 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4644 (void)rn
; /* avoid a compiler warning */
4645 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4649 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4650 generate_exception(ctx
, EXCP_RI
);
4653 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4655 const char *rn
= "invalid";
4658 check_insn(ctx
, ISA_MIPS32
);
4667 gen_helper_mtc0_index(cpu_env
, arg
);
4671 check_insn(ctx
, ASE_MT
);
4672 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4676 check_insn(ctx
, ASE_MT
);
4681 check_insn(ctx
, ASE_MT
);
4696 check_insn(ctx
, ASE_MT
);
4697 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4701 check_insn(ctx
, ASE_MT
);
4702 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4706 check_insn(ctx
, ASE_MT
);
4707 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4711 check_insn(ctx
, ASE_MT
);
4712 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4716 check_insn(ctx
, ASE_MT
);
4717 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4721 check_insn(ctx
, ASE_MT
);
4722 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4723 rn
= "VPEScheFBack";
4726 check_insn(ctx
, ASE_MT
);
4727 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4737 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4741 check_insn(ctx
, ASE_MT
);
4742 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4746 check_insn(ctx
, ASE_MT
);
4747 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4751 check_insn(ctx
, ASE_MT
);
4752 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4756 check_insn(ctx
, ASE_MT
);
4757 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4761 check_insn(ctx
, ASE_MT
);
4762 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4766 check_insn(ctx
, ASE_MT
);
4767 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4771 check_insn(ctx
, ASE_MT
);
4772 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4782 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4792 gen_helper_mtc0_context(cpu_env
, arg
);
4796 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4797 rn
= "ContextConfig";
4806 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4810 check_insn(ctx
, ISA_MIPS32R2
);
4811 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4821 gen_helper_mtc0_wired(cpu_env
, arg
);
4825 check_insn(ctx
, ISA_MIPS32R2
);
4826 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4830 check_insn(ctx
, ISA_MIPS32R2
);
4831 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4835 check_insn(ctx
, ISA_MIPS32R2
);
4836 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4840 check_insn(ctx
, ISA_MIPS32R2
);
4841 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4845 check_insn(ctx
, ISA_MIPS32R2
);
4846 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4856 check_insn(ctx
, ISA_MIPS32R2
);
4857 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4871 gen_helper_mtc0_count(cpu_env
, arg
);
4874 /* 6,7 are implementation dependent */
4882 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4892 gen_helper_mtc0_compare(cpu_env
, arg
);
4895 /* 6,7 are implementation dependent */
4903 save_cpu_state(ctx
, 1);
4904 gen_helper_mtc0_status(cpu_env
, arg
);
4905 /* BS_STOP isn't good enough here, hflags may have changed. */
4906 gen_save_pc(ctx
->pc
+ 4);
4907 ctx
->bstate
= BS_EXCP
;
4911 check_insn(ctx
, ISA_MIPS32R2
);
4912 gen_helper_mtc0_intctl(cpu_env
, arg
);
4913 /* Stop translation as we may have switched the execution mode */
4914 ctx
->bstate
= BS_STOP
;
4918 check_insn(ctx
, ISA_MIPS32R2
);
4919 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4920 /* Stop translation as we may have switched the execution mode */
4921 ctx
->bstate
= BS_STOP
;
4925 check_insn(ctx
, ISA_MIPS32R2
);
4926 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4927 /* Stop translation as we may have switched the execution mode */
4928 ctx
->bstate
= BS_STOP
;
4938 save_cpu_state(ctx
, 1);
4939 gen_helper_mtc0_cause(cpu_env
, arg
);
4949 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4963 check_insn(ctx
, ISA_MIPS32R2
);
4964 gen_helper_mtc0_ebase(cpu_env
, arg
);
4974 gen_helper_mtc0_config0(cpu_env
, arg
);
4976 /* Stop translation as we may have switched the execution mode */
4977 ctx
->bstate
= BS_STOP
;
4980 /* ignored, read only */
4984 gen_helper_mtc0_config2(cpu_env
, arg
);
4986 /* Stop translation as we may have switched the execution mode */
4987 ctx
->bstate
= BS_STOP
;
4990 /* ignored, read only */
4993 /* 4,5 are reserved */
4994 /* 6,7 are implementation dependent */
5004 rn
= "Invalid config selector";
5011 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5021 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5031 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5041 #if defined(TARGET_MIPS64)
5042 check_insn(ctx
, ISA_MIPS3
);
5043 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5052 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5055 gen_helper_mtc0_framemask(cpu_env
, arg
);
5064 rn
= "Diagnostic"; /* implementation dependent */
5069 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5070 /* BS_STOP isn't good enough here, hflags may have changed. */
5071 gen_save_pc(ctx
->pc
+ 4);
5072 ctx
->bstate
= BS_EXCP
;
5076 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5077 rn
= "TraceControl";
5078 /* Stop translation as we may have switched the execution mode */
5079 ctx
->bstate
= BS_STOP
;
5082 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5083 rn
= "TraceControl2";
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx
->bstate
= BS_STOP
;
5088 /* Stop translation as we may have switched the execution mode */
5089 ctx
->bstate
= BS_STOP
;
5090 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5091 rn
= "UserTraceData";
5092 /* Stop translation as we may have switched the execution mode */
5093 ctx
->bstate
= BS_STOP
;
5096 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx
->bstate
= BS_STOP
;
5109 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5119 gen_helper_mtc0_performance0(cpu_env
, arg
);
5120 rn
= "Performance0";
5123 // gen_helper_mtc0_performance1(arg);
5124 rn
= "Performance1";
5127 // gen_helper_mtc0_performance2(arg);
5128 rn
= "Performance2";
5131 // gen_helper_mtc0_performance3(arg);
5132 rn
= "Performance3";
5135 // gen_helper_mtc0_performance4(arg);
5136 rn
= "Performance4";
5139 // gen_helper_mtc0_performance5(arg);
5140 rn
= "Performance5";
5143 // gen_helper_mtc0_performance6(arg);
5144 rn
= "Performance6";
5147 // gen_helper_mtc0_performance7(arg);
5148 rn
= "Performance7";
5174 gen_helper_mtc0_taglo(cpu_env
, arg
);
5181 gen_helper_mtc0_datalo(cpu_env
, arg
);
5194 gen_helper_mtc0_taghi(cpu_env
, arg
);
5201 gen_helper_mtc0_datahi(cpu_env
, arg
);
5212 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5223 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5229 /* Stop translation as we may have switched the execution mode */
5230 ctx
->bstate
= BS_STOP
;
5235 (void)rn
; /* avoid a compiler warning */
5236 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5237 /* For simplicity assume that all writes can cause interrupts. */
5240 ctx
->bstate
= BS_STOP
;
5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5246 generate_exception(ctx
, EXCP_RI
);
5249 #if defined(TARGET_MIPS64)
5250 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5252 const char *rn
= "invalid";
5255 check_insn(ctx
, ISA_MIPS64
);
5261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5265 check_insn(ctx
, ASE_MT
);
5266 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5270 check_insn(ctx
, ASE_MT
);
5271 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5275 check_insn(ctx
, ASE_MT
);
5276 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5286 gen_helper_mfc0_random(arg
, cpu_env
);
5290 check_insn(ctx
, ASE_MT
);
5291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5295 check_insn(ctx
, ASE_MT
);
5296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5300 check_insn(ctx
, ASE_MT
);
5301 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5305 check_insn(ctx
, ASE_MT
);
5306 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5310 check_insn(ctx
, ASE_MT
);
5311 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5315 check_insn(ctx
, ASE_MT
);
5316 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5317 rn
= "VPEScheFBack";
5320 check_insn(ctx
, ASE_MT
);
5321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5331 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5335 check_insn(ctx
, ASE_MT
);
5336 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5340 check_insn(ctx
, ASE_MT
);
5341 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5345 check_insn(ctx
, ASE_MT
);
5346 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5350 check_insn(ctx
, ASE_MT
);
5351 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5355 check_insn(ctx
, ASE_MT
);
5356 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5360 check_insn(ctx
, ASE_MT
);
5361 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5365 check_insn(ctx
, ASE_MT
);
5366 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5376 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5386 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5390 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5391 rn
= "ContextConfig";
5400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5404 check_insn(ctx
, ISA_MIPS32R2
);
5405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5419 check_insn(ctx
, ISA_MIPS32R2
);
5420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5424 check_insn(ctx
, ISA_MIPS32R2
);
5425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5429 check_insn(ctx
, ISA_MIPS32R2
);
5430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5434 check_insn(ctx
, ISA_MIPS32R2
);
5435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5439 check_insn(ctx
, ISA_MIPS32R2
);
5440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5450 check_insn(ctx
, ISA_MIPS32R2
);
5451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5461 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5471 /* Mark as an IO operation because we read the time. */
5474 gen_helper_mfc0_count(arg
, cpu_env
);
5478 /* Break the TB to be able to take timer interrupts immediately
5479 after reading count. */
5480 ctx
->bstate
= BS_STOP
;
5483 /* 6,7 are implementation dependent */
5491 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5501 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5504 /* 6,7 are implementation dependent */
5512 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5516 check_insn(ctx
, ISA_MIPS32R2
);
5517 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5521 check_insn(ctx
, ISA_MIPS32R2
);
5522 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5526 check_insn(ctx
, ISA_MIPS32R2
);
5527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5547 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5557 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5561 check_insn(ctx
, ISA_MIPS32R2
);
5562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5572 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5584 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5587 /* 6,7 are implementation dependent */
5589 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5603 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5613 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5623 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5633 check_insn(ctx
, ISA_MIPS3
);
5634 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5642 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5645 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5653 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5654 rn
= "'Diagnostic"; /* implementation dependent */
5659 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5663 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5664 rn
= "TraceControl";
5667 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5668 rn
= "TraceControl2";
5671 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5672 rn
= "UserTraceData";
5675 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5686 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5696 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5697 rn
= "Performance0";
5700 // gen_helper_dmfc0_performance1(arg);
5701 rn
= "Performance1";
5704 // gen_helper_dmfc0_performance2(arg);
5705 rn
= "Performance2";
5708 // gen_helper_dmfc0_performance3(arg);
5709 rn
= "Performance3";
5712 // gen_helper_dmfc0_performance4(arg);
5713 rn
= "Performance4";
5716 // gen_helper_dmfc0_performance5(arg);
5717 rn
= "Performance5";
5720 // gen_helper_dmfc0_performance6(arg);
5721 rn
= "Performance6";
5724 // gen_helper_dmfc0_performance7(arg);
5725 rn
= "Performance7";
5732 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5739 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5752 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5772 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5789 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5800 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5810 (void)rn
; /* avoid a compiler warning */
5811 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5815 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5816 generate_exception(ctx
, EXCP_RI
);
5819 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5821 const char *rn
= "invalid";
5824 check_insn(ctx
, ISA_MIPS64
);
5833 gen_helper_mtc0_index(cpu_env
, arg
);
5837 check_insn(ctx
, ASE_MT
);
5838 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5842 check_insn(ctx
, ASE_MT
);
5847 check_insn(ctx
, ASE_MT
);
5862 check_insn(ctx
, ASE_MT
);
5863 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5867 check_insn(ctx
, ASE_MT
);
5868 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5872 check_insn(ctx
, ASE_MT
);
5873 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5877 check_insn(ctx
, ASE_MT
);
5878 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5882 check_insn(ctx
, ASE_MT
);
5883 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5887 check_insn(ctx
, ASE_MT
);
5888 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5889 rn
= "VPEScheFBack";
5892 check_insn(ctx
, ASE_MT
);
5893 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5903 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5907 check_insn(ctx
, ASE_MT
);
5908 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5912 check_insn(ctx
, ASE_MT
);
5913 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5917 check_insn(ctx
, ASE_MT
);
5918 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5922 check_insn(ctx
, ASE_MT
);
5923 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5927 check_insn(ctx
, ASE_MT
);
5928 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5932 check_insn(ctx
, ASE_MT
);
5933 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5937 check_insn(ctx
, ASE_MT
);
5938 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5948 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5958 gen_helper_mtc0_context(cpu_env
, arg
);
5962 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5963 rn
= "ContextConfig";
5972 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5976 check_insn(ctx
, ISA_MIPS32R2
);
5977 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5987 gen_helper_mtc0_wired(cpu_env
, arg
);
5991 check_insn(ctx
, ISA_MIPS32R2
);
5992 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5996 check_insn(ctx
, ISA_MIPS32R2
);
5997 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6001 check_insn(ctx
, ISA_MIPS32R2
);
6002 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6006 check_insn(ctx
, ISA_MIPS32R2
);
6007 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6011 check_insn(ctx
, ISA_MIPS32R2
);
6012 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6022 check_insn(ctx
, ISA_MIPS32R2
);
6023 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6037 gen_helper_mtc0_count(cpu_env
, arg
);
6040 /* 6,7 are implementation dependent */
6044 /* Stop translation as we may have switched the execution mode */
6045 ctx
->bstate
= BS_STOP
;
6050 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6060 gen_helper_mtc0_compare(cpu_env
, arg
);
6063 /* 6,7 are implementation dependent */
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx
->bstate
= BS_STOP
;
6073 save_cpu_state(ctx
, 1);
6074 gen_helper_mtc0_status(cpu_env
, arg
);
6075 /* BS_STOP isn't good enough here, hflags may have changed. */
6076 gen_save_pc(ctx
->pc
+ 4);
6077 ctx
->bstate
= BS_EXCP
;
6081 check_insn(ctx
, ISA_MIPS32R2
);
6082 gen_helper_mtc0_intctl(cpu_env
, arg
);
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx
->bstate
= BS_STOP
;
6088 check_insn(ctx
, ISA_MIPS32R2
);
6089 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx
->bstate
= BS_STOP
;
6095 check_insn(ctx
, ISA_MIPS32R2
);
6096 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx
->bstate
= BS_STOP
;
6108 save_cpu_state(ctx
, 1);
6109 /* Mark as an IO operation because we may trigger a software
6114 gen_helper_mtc0_cause(cpu_env
, arg
);
6118 /* Stop translation as we may have triggered an intetrupt */
6119 ctx
->bstate
= BS_STOP
;
6129 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6143 check_insn(ctx
, ISA_MIPS32R2
);
6144 gen_helper_mtc0_ebase(cpu_env
, arg
);
6154 gen_helper_mtc0_config0(cpu_env
, arg
);
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx
->bstate
= BS_STOP
;
6160 /* ignored, read only */
6164 gen_helper_mtc0_config2(cpu_env
, arg
);
6166 /* Stop translation as we may have switched the execution mode */
6167 ctx
->bstate
= BS_STOP
;
6173 /* 6,7 are implementation dependent */
6175 rn
= "Invalid config selector";
6182 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6192 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6202 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6212 check_insn(ctx
, ISA_MIPS3
);
6213 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6221 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6224 gen_helper_mtc0_framemask(cpu_env
, arg
);
6233 rn
= "Diagnostic"; /* implementation dependent */
6238 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6239 /* BS_STOP isn't good enough here, hflags may have changed. */
6240 gen_save_pc(ctx
->pc
+ 4);
6241 ctx
->bstate
= BS_EXCP
;
6245 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx
->bstate
= BS_STOP
;
6248 rn
= "TraceControl";
6251 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6252 /* Stop translation as we may have switched the execution mode */
6253 ctx
->bstate
= BS_STOP
;
6254 rn
= "TraceControl2";
6257 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6258 /* Stop translation as we may have switched the execution mode */
6259 ctx
->bstate
= BS_STOP
;
6260 rn
= "UserTraceData";
6263 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6264 /* Stop translation as we may have switched the execution mode */
6265 ctx
->bstate
= BS_STOP
;
6276 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6286 gen_helper_mtc0_performance0(cpu_env
, arg
);
6287 rn
= "Performance0";
6290 // gen_helper_mtc0_performance1(cpu_env, arg);
6291 rn
= "Performance1";
6294 // gen_helper_mtc0_performance2(cpu_env, arg);
6295 rn
= "Performance2";
6298 // gen_helper_mtc0_performance3(cpu_env, arg);
6299 rn
= "Performance3";
6302 // gen_helper_mtc0_performance4(cpu_env, arg);
6303 rn
= "Performance4";
6306 // gen_helper_mtc0_performance5(cpu_env, arg);
6307 rn
= "Performance5";
6310 // gen_helper_mtc0_performance6(cpu_env, arg);
6311 rn
= "Performance6";
6314 // gen_helper_mtc0_performance7(cpu_env, arg);
6315 rn
= "Performance7";
6341 gen_helper_mtc0_taglo(cpu_env
, arg
);
6348 gen_helper_mtc0_datalo(cpu_env
, arg
);
6361 gen_helper_mtc0_taghi(cpu_env
, arg
);
6368 gen_helper_mtc0_datahi(cpu_env
, arg
);
6379 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6390 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6396 /* Stop translation as we may have switched the execution mode */
6397 ctx
->bstate
= BS_STOP
;
6402 (void)rn
; /* avoid a compiler warning */
6403 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6404 /* For simplicity assume that all writes can cause interrupts. */
6407 ctx
->bstate
= BS_STOP
;
6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6413 generate_exception(ctx
, EXCP_RI
);
6415 #endif /* TARGET_MIPS64 */
6417 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6418 int u
, int sel
, int h
)
6420 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6421 TCGv t0
= tcg_temp_local_new();
6423 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6424 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6425 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6426 tcg_gen_movi_tl(t0
, -1);
6427 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6428 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6429 tcg_gen_movi_tl(t0
, -1);
6435 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6438 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6448 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6451 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6454 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6457 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6460 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6463 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6466 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6469 gen_mfc0(ctx
, t0
, rt
, sel
);
6476 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6479 gen_mfc0(ctx
, t0
, rt
, sel
);
6485 gen_helper_mftc0_status(t0
, cpu_env
);
6488 gen_mfc0(ctx
, t0
, rt
, sel
);
6494 gen_helper_mftc0_cause(t0
, cpu_env
);
6504 gen_helper_mftc0_epc(t0
, cpu_env
);
6514 gen_helper_mftc0_ebase(t0
, cpu_env
);
6524 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6534 gen_helper_mftc0_debug(t0
, cpu_env
);
6537 gen_mfc0(ctx
, t0
, rt
, sel
);
6542 gen_mfc0(ctx
, t0
, rt
, sel
);
6544 } else switch (sel
) {
6545 /* GPR registers. */
6547 gen_helper_1e0i(mftgpr
, t0
, rt
);
6549 /* Auxiliary CPU registers */
6553 gen_helper_1e0i(mftlo
, t0
, 0);
6556 gen_helper_1e0i(mfthi
, t0
, 0);
6559 gen_helper_1e0i(mftacx
, t0
, 0);
6562 gen_helper_1e0i(mftlo
, t0
, 1);
6565 gen_helper_1e0i(mfthi
, t0
, 1);
6568 gen_helper_1e0i(mftacx
, t0
, 1);
6571 gen_helper_1e0i(mftlo
, t0
, 2);
6574 gen_helper_1e0i(mfthi
, t0
, 2);
6577 gen_helper_1e0i(mftacx
, t0
, 2);
6580 gen_helper_1e0i(mftlo
, t0
, 3);
6583 gen_helper_1e0i(mfthi
, t0
, 3);
6586 gen_helper_1e0i(mftacx
, t0
, 3);
6589 gen_helper_mftdsp(t0
, cpu_env
);
6595 /* Floating point (COP1). */
6597 /* XXX: For now we support only a single FPU context. */
6599 TCGv_i32 fp0
= tcg_temp_new_i32();
6601 gen_load_fpr32(fp0
, rt
);
6602 tcg_gen_ext_i32_tl(t0
, fp0
);
6603 tcg_temp_free_i32(fp0
);
6605 TCGv_i32 fp0
= tcg_temp_new_i32();
6607 gen_load_fpr32h(fp0
, rt
);
6608 tcg_gen_ext_i32_tl(t0
, fp0
);
6609 tcg_temp_free_i32(fp0
);
6613 /* XXX: For now we support only a single FPU context. */
6614 gen_helper_1e0i(cfc1
, t0
, rt
);
6616 /* COP2: Not implemented. */
6623 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6624 gen_store_gpr(t0
, rd
);
6630 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6631 generate_exception(ctx
, EXCP_RI
);
6634 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6635 int u
, int sel
, int h
)
6637 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6638 TCGv t0
= tcg_temp_local_new();
6640 gen_load_gpr(t0
, rt
);
6641 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6642 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6643 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6645 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6646 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6653 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6656 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6666 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6669 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6672 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6675 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6678 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6681 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6684 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6687 gen_mtc0(ctx
, t0
, rd
, sel
);
6694 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6697 gen_mtc0(ctx
, t0
, rd
, sel
);
6703 gen_helper_mttc0_status(cpu_env
, t0
);
6706 gen_mtc0(ctx
, t0
, rd
, sel
);
6712 gen_helper_mttc0_cause(cpu_env
, t0
);
6722 gen_helper_mttc0_ebase(cpu_env
, t0
);
6732 gen_helper_mttc0_debug(cpu_env
, t0
);
6735 gen_mtc0(ctx
, t0
, rd
, sel
);
6740 gen_mtc0(ctx
, t0
, rd
, sel
);
6742 } else switch (sel
) {
6743 /* GPR registers. */
6745 gen_helper_0e1i(mttgpr
, t0
, rd
);
6747 /* Auxiliary CPU registers */
6751 gen_helper_0e1i(mttlo
, t0
, 0);
6754 gen_helper_0e1i(mtthi
, t0
, 0);
6757 gen_helper_0e1i(mttacx
, t0
, 0);
6760 gen_helper_0e1i(mttlo
, t0
, 1);
6763 gen_helper_0e1i(mtthi
, t0
, 1);
6766 gen_helper_0e1i(mttacx
, t0
, 1);
6769 gen_helper_0e1i(mttlo
, t0
, 2);
6772 gen_helper_0e1i(mtthi
, t0
, 2);
6775 gen_helper_0e1i(mttacx
, t0
, 2);
6778 gen_helper_0e1i(mttlo
, t0
, 3);
6781 gen_helper_0e1i(mtthi
, t0
, 3);
6784 gen_helper_0e1i(mttacx
, t0
, 3);
6787 gen_helper_mttdsp(cpu_env
, t0
);
6793 /* Floating point (COP1). */
6795 /* XXX: For now we support only a single FPU context. */
6797 TCGv_i32 fp0
= tcg_temp_new_i32();
6799 tcg_gen_trunc_tl_i32(fp0
, t0
);
6800 gen_store_fpr32(fp0
, rd
);
6801 tcg_temp_free_i32(fp0
);
6803 TCGv_i32 fp0
= tcg_temp_new_i32();
6805 tcg_gen_trunc_tl_i32(fp0
, t0
);
6806 gen_store_fpr32h(fp0
, rd
);
6807 tcg_temp_free_i32(fp0
);
6811 /* XXX: For now we support only a single FPU context. */
6812 gen_helper_0e1i(ctc1
, t0
, rd
);
6814 /* COP2: Not implemented. */
6821 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6827 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6828 generate_exception(ctx
, EXCP_RI
);
6831 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6833 const char *opn
= "ldst";
6835 check_cp0_enabled(ctx
);
6842 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6847 TCGv t0
= tcg_temp_new();
6849 gen_load_gpr(t0
, rt
);
6850 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6855 #if defined(TARGET_MIPS64)
6857 check_insn(ctx
, ISA_MIPS3
);
6862 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6866 check_insn(ctx
, ISA_MIPS3
);
6868 TCGv t0
= tcg_temp_new();
6870 gen_load_gpr(t0
, rt
);
6871 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6878 check_insn(ctx
, ASE_MT
);
6883 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6884 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6888 check_insn(ctx
, ASE_MT
);
6889 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6890 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6895 if (!env
->tlb
->helper_tlbwi
)
6897 gen_helper_tlbwi(cpu_env
);
6901 if (!env
->tlb
->helper_tlbwr
)
6903 gen_helper_tlbwr(cpu_env
);
6907 if (!env
->tlb
->helper_tlbp
)
6909 gen_helper_tlbp(cpu_env
);
6913 if (!env
->tlb
->helper_tlbr
)
6915 gen_helper_tlbr(cpu_env
);
6919 check_insn(ctx
, ISA_MIPS2
);
6920 gen_helper_eret(cpu_env
);
6921 ctx
->bstate
= BS_EXCP
;
6925 check_insn(ctx
, ISA_MIPS32
);
6926 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6928 generate_exception(ctx
, EXCP_RI
);
6930 gen_helper_deret(cpu_env
);
6931 ctx
->bstate
= BS_EXCP
;
6936 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6937 /* If we get an exception, we want to restart at next instruction */
6939 save_cpu_state(ctx
, 1);
6941 gen_helper_wait(cpu_env
);
6942 ctx
->bstate
= BS_EXCP
;
6947 generate_exception(ctx
, EXCP_RI
);
6950 (void)opn
; /* avoid a compiler warning */
6951 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6953 #endif /* !CONFIG_USER_ONLY */
6955 /* CP1 Branches (before delay slot) */
6956 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6957 int32_t cc
, int32_t offset
)
6959 target_ulong btarget
;
6960 const char *opn
= "cp1 cond branch";
6961 TCGv_i32 t0
= tcg_temp_new_i32();
6964 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6966 btarget
= ctx
->pc
+ 4 + offset
;
6970 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6971 tcg_gen_not_i32(t0
, t0
);
6972 tcg_gen_andi_i32(t0
, t0
, 1);
6973 tcg_gen_extu_i32_tl(bcond
, t0
);
6977 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6978 tcg_gen_not_i32(t0
, t0
);
6979 tcg_gen_andi_i32(t0
, t0
, 1);
6980 tcg_gen_extu_i32_tl(bcond
, t0
);
6984 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6985 tcg_gen_andi_i32(t0
, t0
, 1);
6986 tcg_gen_extu_i32_tl(bcond
, t0
);
6990 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6991 tcg_gen_andi_i32(t0
, t0
, 1);
6992 tcg_gen_extu_i32_tl(bcond
, t0
);
6995 ctx
->hflags
|= MIPS_HFLAG_BL
;
6999 TCGv_i32 t1
= tcg_temp_new_i32();
7000 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7001 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7002 tcg_gen_nand_i32(t0
, t0
, t1
);
7003 tcg_temp_free_i32(t1
);
7004 tcg_gen_andi_i32(t0
, t0
, 1);
7005 tcg_gen_extu_i32_tl(bcond
, t0
);
7011 TCGv_i32 t1
= tcg_temp_new_i32();
7012 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7013 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7014 tcg_gen_or_i32(t0
, t0
, t1
);
7015 tcg_temp_free_i32(t1
);
7016 tcg_gen_andi_i32(t0
, t0
, 1);
7017 tcg_gen_extu_i32_tl(bcond
, t0
);
7023 TCGv_i32 t1
= tcg_temp_new_i32();
7024 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7025 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7026 tcg_gen_and_i32(t0
, t0
, t1
);
7027 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7028 tcg_gen_and_i32(t0
, t0
, t1
);
7029 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7030 tcg_gen_nand_i32(t0
, t0
, t1
);
7031 tcg_temp_free_i32(t1
);
7032 tcg_gen_andi_i32(t0
, t0
, 1);
7033 tcg_gen_extu_i32_tl(bcond
, t0
);
7039 TCGv_i32 t1
= tcg_temp_new_i32();
7040 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7041 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7042 tcg_gen_or_i32(t0
, t0
, t1
);
7043 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7044 tcg_gen_or_i32(t0
, t0
, t1
);
7045 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7046 tcg_gen_or_i32(t0
, t0
, t1
);
7047 tcg_temp_free_i32(t1
);
7048 tcg_gen_andi_i32(t0
, t0
, 1);
7049 tcg_gen_extu_i32_tl(bcond
, t0
);
7053 ctx
->hflags
|= MIPS_HFLAG_BC
;
7057 generate_exception (ctx
, EXCP_RI
);
7060 (void)opn
; /* avoid a compiler warning */
7061 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7062 ctx
->hflags
, btarget
);
7063 ctx
->btarget
= btarget
;
7066 tcg_temp_free_i32(t0
);
7069 /* Coprocessor 1 (FPU) */
7071 #define FOP(func, fmt) (((fmt) << 21) | (func))
7074 OPC_ADD_S
= FOP(0, FMT_S
),
7075 OPC_SUB_S
= FOP(1, FMT_S
),
7076 OPC_MUL_S
= FOP(2, FMT_S
),
7077 OPC_DIV_S
= FOP(3, FMT_S
),
7078 OPC_SQRT_S
= FOP(4, FMT_S
),
7079 OPC_ABS_S
= FOP(5, FMT_S
),
7080 OPC_MOV_S
= FOP(6, FMT_S
),
7081 OPC_NEG_S
= FOP(7, FMT_S
),
7082 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7083 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7084 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7085 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7086 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7087 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7088 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7089 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7090 OPC_MOVCF_S
= FOP(17, FMT_S
),
7091 OPC_MOVZ_S
= FOP(18, FMT_S
),
7092 OPC_MOVN_S
= FOP(19, FMT_S
),
7093 OPC_RECIP_S
= FOP(21, FMT_S
),
7094 OPC_RSQRT_S
= FOP(22, FMT_S
),
7095 OPC_RECIP2_S
= FOP(28, FMT_S
),
7096 OPC_RECIP1_S
= FOP(29, FMT_S
),
7097 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7098 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7099 OPC_CVT_D_S
= FOP(33, FMT_S
),
7100 OPC_CVT_W_S
= FOP(36, FMT_S
),
7101 OPC_CVT_L_S
= FOP(37, FMT_S
),
7102 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7103 OPC_CMP_F_S
= FOP (48, FMT_S
),
7104 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7105 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7106 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7107 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7108 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7109 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7110 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7111 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7112 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7113 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7114 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7115 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7116 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7117 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7118 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7120 OPC_ADD_D
= FOP(0, FMT_D
),
7121 OPC_SUB_D
= FOP(1, FMT_D
),
7122 OPC_MUL_D
= FOP(2, FMT_D
),
7123 OPC_DIV_D
= FOP(3, FMT_D
),
7124 OPC_SQRT_D
= FOP(4, FMT_D
),
7125 OPC_ABS_D
= FOP(5, FMT_D
),
7126 OPC_MOV_D
= FOP(6, FMT_D
),
7127 OPC_NEG_D
= FOP(7, FMT_D
),
7128 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7129 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7130 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7131 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7132 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7133 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7134 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7135 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7136 OPC_MOVCF_D
= FOP(17, FMT_D
),
7137 OPC_MOVZ_D
= FOP(18, FMT_D
),
7138 OPC_MOVN_D
= FOP(19, FMT_D
),
7139 OPC_RECIP_D
= FOP(21, FMT_D
),
7140 OPC_RSQRT_D
= FOP(22, FMT_D
),
7141 OPC_RECIP2_D
= FOP(28, FMT_D
),
7142 OPC_RECIP1_D
= FOP(29, FMT_D
),
7143 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7144 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7145 OPC_CVT_S_D
= FOP(32, FMT_D
),
7146 OPC_CVT_W_D
= FOP(36, FMT_D
),
7147 OPC_CVT_L_D
= FOP(37, FMT_D
),
7148 OPC_CMP_F_D
= FOP (48, FMT_D
),
7149 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7150 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7151 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7152 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7153 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7154 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7155 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7156 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7157 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7158 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7159 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7160 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7161 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7162 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7163 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7165 OPC_CVT_S_W
= FOP(32, FMT_W
),
7166 OPC_CVT_D_W
= FOP(33, FMT_W
),
7167 OPC_CVT_S_L
= FOP(32, FMT_L
),
7168 OPC_CVT_D_L
= FOP(33, FMT_L
),
7169 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7171 OPC_ADD_PS
= FOP(0, FMT_PS
),
7172 OPC_SUB_PS
= FOP(1, FMT_PS
),
7173 OPC_MUL_PS
= FOP(2, FMT_PS
),
7174 OPC_DIV_PS
= FOP(3, FMT_PS
),
7175 OPC_ABS_PS
= FOP(5, FMT_PS
),
7176 OPC_MOV_PS
= FOP(6, FMT_PS
),
7177 OPC_NEG_PS
= FOP(7, FMT_PS
),
7178 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7179 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7180 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7181 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7182 OPC_MULR_PS
= FOP(26, FMT_PS
),
7183 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7184 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7185 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7186 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7188 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7189 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7190 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7191 OPC_PLL_PS
= FOP(44, FMT_PS
),
7192 OPC_PLU_PS
= FOP(45, FMT_PS
),
7193 OPC_PUL_PS
= FOP(46, FMT_PS
),
7194 OPC_PUU_PS
= FOP(47, FMT_PS
),
7195 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7196 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7197 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7198 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7199 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7200 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7201 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7202 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7203 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7204 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7205 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7206 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7207 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7208 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7209 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7210 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7213 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7215 const char *opn
= "cp1 move";
7216 TCGv t0
= tcg_temp_new();
7221 TCGv_i32 fp0
= tcg_temp_new_i32();
7223 gen_load_fpr32(fp0
, fs
);
7224 tcg_gen_ext_i32_tl(t0
, fp0
);
7225 tcg_temp_free_i32(fp0
);
7227 gen_store_gpr(t0
, rt
);
7231 gen_load_gpr(t0
, rt
);
7233 TCGv_i32 fp0
= tcg_temp_new_i32();
7235 tcg_gen_trunc_tl_i32(fp0
, t0
);
7236 gen_store_fpr32(fp0
, fs
);
7237 tcg_temp_free_i32(fp0
);
7242 gen_helper_1e0i(cfc1
, t0
, fs
);
7243 gen_store_gpr(t0
, rt
);
7247 gen_load_gpr(t0
, rt
);
7248 gen_helper_0e1i(ctc1
, t0
, fs
);
7251 #if defined(TARGET_MIPS64)
7253 gen_load_fpr64(ctx
, t0
, fs
);
7254 gen_store_gpr(t0
, rt
);
7258 gen_load_gpr(t0
, rt
);
7259 gen_store_fpr64(ctx
, t0
, fs
);
7265 TCGv_i32 fp0
= tcg_temp_new_i32();
7267 gen_load_fpr32h(fp0
, fs
);
7268 tcg_gen_ext_i32_tl(t0
, fp0
);
7269 tcg_temp_free_i32(fp0
);
7271 gen_store_gpr(t0
, rt
);
7275 gen_load_gpr(t0
, rt
);
7277 TCGv_i32 fp0
= tcg_temp_new_i32();
7279 tcg_gen_trunc_tl_i32(fp0
, t0
);
7280 gen_store_fpr32h(fp0
, fs
);
7281 tcg_temp_free_i32(fp0
);
7287 generate_exception (ctx
, EXCP_RI
);
7290 (void)opn
; /* avoid a compiler warning */
7291 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7297 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7313 l1
= gen_new_label();
7314 t0
= tcg_temp_new_i32();
7315 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7316 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7317 tcg_temp_free_i32(t0
);
7319 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7321 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7326 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7329 TCGv_i32 t0
= tcg_temp_new_i32();
7330 int l1
= gen_new_label();
7337 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7338 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7339 gen_load_fpr32(t0
, fs
);
7340 gen_store_fpr32(t0
, fd
);
7342 tcg_temp_free_i32(t0
);
7345 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7348 TCGv_i32 t0
= tcg_temp_new_i32();
7350 int l1
= gen_new_label();
7357 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7358 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7359 tcg_temp_free_i32(t0
);
7360 fp0
= tcg_temp_new_i64();
7361 gen_load_fpr64(ctx
, fp0
, fs
);
7362 gen_store_fpr64(ctx
, fp0
, fd
);
7363 tcg_temp_free_i64(fp0
);
7367 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7370 TCGv_i32 t0
= tcg_temp_new_i32();
7371 int l1
= gen_new_label();
7372 int l2
= gen_new_label();
7379 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7380 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7381 gen_load_fpr32(t0
, fs
);
7382 gen_store_fpr32(t0
, fd
);
7385 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7386 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7387 gen_load_fpr32h(t0
, fs
);
7388 gen_store_fpr32h(t0
, fd
);
7389 tcg_temp_free_i32(t0
);
7394 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7395 int ft
, int fs
, int fd
, int cc
)
7397 const char *opn
= "farith";
7398 const char *condnames
[] = {
7416 const char *condnames_abs
[] = {
7434 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7435 uint32_t func
= ctx
->opcode
& 0x3f;
7440 TCGv_i32 fp0
= tcg_temp_new_i32();
7441 TCGv_i32 fp1
= tcg_temp_new_i32();
7443 gen_load_fpr32(fp0
, fs
);
7444 gen_load_fpr32(fp1
, ft
);
7445 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7446 tcg_temp_free_i32(fp1
);
7447 gen_store_fpr32(fp0
, fd
);
7448 tcg_temp_free_i32(fp0
);
7455 TCGv_i32 fp0
= tcg_temp_new_i32();
7456 TCGv_i32 fp1
= tcg_temp_new_i32();
7458 gen_load_fpr32(fp0
, fs
);
7459 gen_load_fpr32(fp1
, ft
);
7460 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7461 tcg_temp_free_i32(fp1
);
7462 gen_store_fpr32(fp0
, fd
);
7463 tcg_temp_free_i32(fp0
);
7470 TCGv_i32 fp0
= tcg_temp_new_i32();
7471 TCGv_i32 fp1
= tcg_temp_new_i32();
7473 gen_load_fpr32(fp0
, fs
);
7474 gen_load_fpr32(fp1
, ft
);
7475 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7476 tcg_temp_free_i32(fp1
);
7477 gen_store_fpr32(fp0
, fd
);
7478 tcg_temp_free_i32(fp0
);
7485 TCGv_i32 fp0
= tcg_temp_new_i32();
7486 TCGv_i32 fp1
= tcg_temp_new_i32();
7488 gen_load_fpr32(fp0
, fs
);
7489 gen_load_fpr32(fp1
, ft
);
7490 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7491 tcg_temp_free_i32(fp1
);
7492 gen_store_fpr32(fp0
, fd
);
7493 tcg_temp_free_i32(fp0
);
7500 TCGv_i32 fp0
= tcg_temp_new_i32();
7502 gen_load_fpr32(fp0
, fs
);
7503 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7504 gen_store_fpr32(fp0
, fd
);
7505 tcg_temp_free_i32(fp0
);
7511 TCGv_i32 fp0
= tcg_temp_new_i32();
7513 gen_load_fpr32(fp0
, fs
);
7514 gen_helper_float_abs_s(fp0
, fp0
);
7515 gen_store_fpr32(fp0
, fd
);
7516 tcg_temp_free_i32(fp0
);
7522 TCGv_i32 fp0
= tcg_temp_new_i32();
7524 gen_load_fpr32(fp0
, fs
);
7525 gen_store_fpr32(fp0
, fd
);
7526 tcg_temp_free_i32(fp0
);
7532 TCGv_i32 fp0
= tcg_temp_new_i32();
7534 gen_load_fpr32(fp0
, fs
);
7535 gen_helper_float_chs_s(fp0
, fp0
);
7536 gen_store_fpr32(fp0
, fd
);
7537 tcg_temp_free_i32(fp0
);
7542 check_cp1_64bitmode(ctx
);
7544 TCGv_i32 fp32
= tcg_temp_new_i32();
7545 TCGv_i64 fp64
= tcg_temp_new_i64();
7547 gen_load_fpr32(fp32
, fs
);
7548 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7549 tcg_temp_free_i32(fp32
);
7550 gen_store_fpr64(ctx
, fp64
, fd
);
7551 tcg_temp_free_i64(fp64
);
7556 check_cp1_64bitmode(ctx
);
7558 TCGv_i32 fp32
= tcg_temp_new_i32();
7559 TCGv_i64 fp64
= tcg_temp_new_i64();
7561 gen_load_fpr32(fp32
, fs
);
7562 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7563 tcg_temp_free_i32(fp32
);
7564 gen_store_fpr64(ctx
, fp64
, fd
);
7565 tcg_temp_free_i64(fp64
);
7570 check_cp1_64bitmode(ctx
);
7572 TCGv_i32 fp32
= tcg_temp_new_i32();
7573 TCGv_i64 fp64
= tcg_temp_new_i64();
7575 gen_load_fpr32(fp32
, fs
);
7576 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7577 tcg_temp_free_i32(fp32
);
7578 gen_store_fpr64(ctx
, fp64
, fd
);
7579 tcg_temp_free_i64(fp64
);
7584 check_cp1_64bitmode(ctx
);
7586 TCGv_i32 fp32
= tcg_temp_new_i32();
7587 TCGv_i64 fp64
= tcg_temp_new_i64();
7589 gen_load_fpr32(fp32
, fs
);
7590 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7591 tcg_temp_free_i32(fp32
);
7592 gen_store_fpr64(ctx
, fp64
, fd
);
7593 tcg_temp_free_i64(fp64
);
7599 TCGv_i32 fp0
= tcg_temp_new_i32();
7601 gen_load_fpr32(fp0
, fs
);
7602 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7603 gen_store_fpr32(fp0
, fd
);
7604 tcg_temp_free_i32(fp0
);
7610 TCGv_i32 fp0
= tcg_temp_new_i32();
7612 gen_load_fpr32(fp0
, fs
);
7613 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7614 gen_store_fpr32(fp0
, fd
);
7615 tcg_temp_free_i32(fp0
);
7621 TCGv_i32 fp0
= tcg_temp_new_i32();
7623 gen_load_fpr32(fp0
, fs
);
7624 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7625 gen_store_fpr32(fp0
, fd
);
7626 tcg_temp_free_i32(fp0
);
7632 TCGv_i32 fp0
= tcg_temp_new_i32();
7634 gen_load_fpr32(fp0
, fs
);
7635 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7636 gen_store_fpr32(fp0
, fd
);
7637 tcg_temp_free_i32(fp0
);
7642 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7647 int l1
= gen_new_label();
7651 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7653 fp0
= tcg_temp_new_i32();
7654 gen_load_fpr32(fp0
, fs
);
7655 gen_store_fpr32(fp0
, fd
);
7656 tcg_temp_free_i32(fp0
);
7663 int l1
= gen_new_label();
7667 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7668 fp0
= tcg_temp_new_i32();
7669 gen_load_fpr32(fp0
, fs
);
7670 gen_store_fpr32(fp0
, fd
);
7671 tcg_temp_free_i32(fp0
);
7680 TCGv_i32 fp0
= tcg_temp_new_i32();
7682 gen_load_fpr32(fp0
, fs
);
7683 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7684 gen_store_fpr32(fp0
, fd
);
7685 tcg_temp_free_i32(fp0
);
7692 TCGv_i32 fp0
= tcg_temp_new_i32();
7694 gen_load_fpr32(fp0
, fs
);
7695 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7696 gen_store_fpr32(fp0
, fd
);
7697 tcg_temp_free_i32(fp0
);
7702 check_cp1_64bitmode(ctx
);
7704 TCGv_i32 fp0
= tcg_temp_new_i32();
7705 TCGv_i32 fp1
= tcg_temp_new_i32();
7707 gen_load_fpr32(fp0
, fs
);
7708 gen_load_fpr32(fp1
, ft
);
7709 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7710 tcg_temp_free_i32(fp1
);
7711 gen_store_fpr32(fp0
, fd
);
7712 tcg_temp_free_i32(fp0
);
7717 check_cp1_64bitmode(ctx
);
7719 TCGv_i32 fp0
= tcg_temp_new_i32();
7721 gen_load_fpr32(fp0
, fs
);
7722 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7723 gen_store_fpr32(fp0
, fd
);
7724 tcg_temp_free_i32(fp0
);
7729 check_cp1_64bitmode(ctx
);
7731 TCGv_i32 fp0
= tcg_temp_new_i32();
7733 gen_load_fpr32(fp0
, fs
);
7734 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7735 gen_store_fpr32(fp0
, fd
);
7736 tcg_temp_free_i32(fp0
);
7741 check_cp1_64bitmode(ctx
);
7743 TCGv_i32 fp0
= tcg_temp_new_i32();
7744 TCGv_i32 fp1
= tcg_temp_new_i32();
7746 gen_load_fpr32(fp0
, fs
);
7747 gen_load_fpr32(fp1
, ft
);
7748 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7749 tcg_temp_free_i32(fp1
);
7750 gen_store_fpr32(fp0
, fd
);
7751 tcg_temp_free_i32(fp0
);
7756 check_cp1_registers(ctx
, fd
);
7758 TCGv_i32 fp32
= tcg_temp_new_i32();
7759 TCGv_i64 fp64
= tcg_temp_new_i64();
7761 gen_load_fpr32(fp32
, fs
);
7762 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7763 tcg_temp_free_i32(fp32
);
7764 gen_store_fpr64(ctx
, fp64
, fd
);
7765 tcg_temp_free_i64(fp64
);
7771 TCGv_i32 fp0
= tcg_temp_new_i32();
7773 gen_load_fpr32(fp0
, fs
);
7774 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7775 gen_store_fpr32(fp0
, fd
);
7776 tcg_temp_free_i32(fp0
);
7781 check_cp1_64bitmode(ctx
);
7783 TCGv_i32 fp32
= tcg_temp_new_i32();
7784 TCGv_i64 fp64
= tcg_temp_new_i64();
7786 gen_load_fpr32(fp32
, fs
);
7787 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7788 tcg_temp_free_i32(fp32
);
7789 gen_store_fpr64(ctx
, fp64
, fd
);
7790 tcg_temp_free_i64(fp64
);
7795 check_cp1_64bitmode(ctx
);
7797 TCGv_i64 fp64
= tcg_temp_new_i64();
7798 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7799 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7801 gen_load_fpr32(fp32_0
, fs
);
7802 gen_load_fpr32(fp32_1
, ft
);
7803 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7804 tcg_temp_free_i32(fp32_1
);
7805 tcg_temp_free_i32(fp32_0
);
7806 gen_store_fpr64(ctx
, fp64
, fd
);
7807 tcg_temp_free_i64(fp64
);
7820 case OPC_CMP_NGLE_S
:
7827 if (ctx
->opcode
& (1 << 6)) {
7828 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7829 opn
= condnames_abs
[func
-48];
7831 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7832 opn
= condnames
[func
-48];
7836 check_cp1_registers(ctx
, fs
| ft
| fd
);
7838 TCGv_i64 fp0
= tcg_temp_new_i64();
7839 TCGv_i64 fp1
= tcg_temp_new_i64();
7841 gen_load_fpr64(ctx
, fp0
, fs
);
7842 gen_load_fpr64(ctx
, fp1
, ft
);
7843 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7844 tcg_temp_free_i64(fp1
);
7845 gen_store_fpr64(ctx
, fp0
, fd
);
7846 tcg_temp_free_i64(fp0
);
7852 check_cp1_registers(ctx
, fs
| ft
| fd
);
7854 TCGv_i64 fp0
= tcg_temp_new_i64();
7855 TCGv_i64 fp1
= tcg_temp_new_i64();
7857 gen_load_fpr64(ctx
, fp0
, fs
);
7858 gen_load_fpr64(ctx
, fp1
, ft
);
7859 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7860 tcg_temp_free_i64(fp1
);
7861 gen_store_fpr64(ctx
, fp0
, fd
);
7862 tcg_temp_free_i64(fp0
);
7868 check_cp1_registers(ctx
, fs
| ft
| fd
);
7870 TCGv_i64 fp0
= tcg_temp_new_i64();
7871 TCGv_i64 fp1
= tcg_temp_new_i64();
7873 gen_load_fpr64(ctx
, fp0
, fs
);
7874 gen_load_fpr64(ctx
, fp1
, ft
);
7875 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7876 tcg_temp_free_i64(fp1
);
7877 gen_store_fpr64(ctx
, fp0
, fd
);
7878 tcg_temp_free_i64(fp0
);
7884 check_cp1_registers(ctx
, fs
| ft
| fd
);
7886 TCGv_i64 fp0
= tcg_temp_new_i64();
7887 TCGv_i64 fp1
= tcg_temp_new_i64();
7889 gen_load_fpr64(ctx
, fp0
, fs
);
7890 gen_load_fpr64(ctx
, fp1
, ft
);
7891 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7892 tcg_temp_free_i64(fp1
);
7893 gen_store_fpr64(ctx
, fp0
, fd
);
7894 tcg_temp_free_i64(fp0
);
7900 check_cp1_registers(ctx
, fs
| fd
);
7902 TCGv_i64 fp0
= tcg_temp_new_i64();
7904 gen_load_fpr64(ctx
, fp0
, fs
);
7905 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7906 gen_store_fpr64(ctx
, fp0
, fd
);
7907 tcg_temp_free_i64(fp0
);
7912 check_cp1_registers(ctx
, fs
| fd
);
7914 TCGv_i64 fp0
= tcg_temp_new_i64();
7916 gen_load_fpr64(ctx
, fp0
, fs
);
7917 gen_helper_float_abs_d(fp0
, fp0
);
7918 gen_store_fpr64(ctx
, fp0
, fd
);
7919 tcg_temp_free_i64(fp0
);
7924 check_cp1_registers(ctx
, fs
| fd
);
7926 TCGv_i64 fp0
= tcg_temp_new_i64();
7928 gen_load_fpr64(ctx
, fp0
, fs
);
7929 gen_store_fpr64(ctx
, fp0
, fd
);
7930 tcg_temp_free_i64(fp0
);
7935 check_cp1_registers(ctx
, fs
| fd
);
7937 TCGv_i64 fp0
= tcg_temp_new_i64();
7939 gen_load_fpr64(ctx
, fp0
, fs
);
7940 gen_helper_float_chs_d(fp0
, fp0
);
7941 gen_store_fpr64(ctx
, fp0
, fd
);
7942 tcg_temp_free_i64(fp0
);
7947 check_cp1_64bitmode(ctx
);
7949 TCGv_i64 fp0
= tcg_temp_new_i64();
7951 gen_load_fpr64(ctx
, fp0
, fs
);
7952 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7953 gen_store_fpr64(ctx
, fp0
, fd
);
7954 tcg_temp_free_i64(fp0
);
7959 check_cp1_64bitmode(ctx
);
7961 TCGv_i64 fp0
= tcg_temp_new_i64();
7963 gen_load_fpr64(ctx
, fp0
, fs
);
7964 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7965 gen_store_fpr64(ctx
, fp0
, fd
);
7966 tcg_temp_free_i64(fp0
);
7971 check_cp1_64bitmode(ctx
);
7973 TCGv_i64 fp0
= tcg_temp_new_i64();
7975 gen_load_fpr64(ctx
, fp0
, fs
);
7976 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
7977 gen_store_fpr64(ctx
, fp0
, fd
);
7978 tcg_temp_free_i64(fp0
);
7983 check_cp1_64bitmode(ctx
);
7985 TCGv_i64 fp0
= tcg_temp_new_i64();
7987 gen_load_fpr64(ctx
, fp0
, fs
);
7988 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
7989 gen_store_fpr64(ctx
, fp0
, fd
);
7990 tcg_temp_free_i64(fp0
);
7995 check_cp1_registers(ctx
, fs
);
7997 TCGv_i32 fp32
= tcg_temp_new_i32();
7998 TCGv_i64 fp64
= tcg_temp_new_i64();
8000 gen_load_fpr64(ctx
, fp64
, fs
);
8001 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8002 tcg_temp_free_i64(fp64
);
8003 gen_store_fpr32(fp32
, fd
);
8004 tcg_temp_free_i32(fp32
);
8009 check_cp1_registers(ctx
, fs
);
8011 TCGv_i32 fp32
= tcg_temp_new_i32();
8012 TCGv_i64 fp64
= tcg_temp_new_i64();
8014 gen_load_fpr64(ctx
, fp64
, fs
);
8015 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8016 tcg_temp_free_i64(fp64
);
8017 gen_store_fpr32(fp32
, fd
);
8018 tcg_temp_free_i32(fp32
);
8023 check_cp1_registers(ctx
, fs
);
8025 TCGv_i32 fp32
= tcg_temp_new_i32();
8026 TCGv_i64 fp64
= tcg_temp_new_i64();
8028 gen_load_fpr64(ctx
, fp64
, fs
);
8029 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8030 tcg_temp_free_i64(fp64
);
8031 gen_store_fpr32(fp32
, fd
);
8032 tcg_temp_free_i32(fp32
);
8037 check_cp1_registers(ctx
, fs
);
8039 TCGv_i32 fp32
= tcg_temp_new_i32();
8040 TCGv_i64 fp64
= tcg_temp_new_i64();
8042 gen_load_fpr64(ctx
, fp64
, fs
);
8043 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8044 tcg_temp_free_i64(fp64
);
8045 gen_store_fpr32(fp32
, fd
);
8046 tcg_temp_free_i32(fp32
);
8051 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8056 int l1
= gen_new_label();
8060 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8062 fp0
= tcg_temp_new_i64();
8063 gen_load_fpr64(ctx
, fp0
, fs
);
8064 gen_store_fpr64(ctx
, fp0
, fd
);
8065 tcg_temp_free_i64(fp0
);
8072 int l1
= gen_new_label();
8076 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8077 fp0
= tcg_temp_new_i64();
8078 gen_load_fpr64(ctx
, fp0
, fs
);
8079 gen_store_fpr64(ctx
, fp0
, fd
);
8080 tcg_temp_free_i64(fp0
);
8087 check_cp1_64bitmode(ctx
);
8089 TCGv_i64 fp0
= tcg_temp_new_i64();
8091 gen_load_fpr64(ctx
, fp0
, fs
);
8092 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8093 gen_store_fpr64(ctx
, fp0
, fd
);
8094 tcg_temp_free_i64(fp0
);
8099 check_cp1_64bitmode(ctx
);
8101 TCGv_i64 fp0
= tcg_temp_new_i64();
8103 gen_load_fpr64(ctx
, fp0
, fs
);
8104 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8105 gen_store_fpr64(ctx
, fp0
, fd
);
8106 tcg_temp_free_i64(fp0
);
8111 check_cp1_64bitmode(ctx
);
8113 TCGv_i64 fp0
= tcg_temp_new_i64();
8114 TCGv_i64 fp1
= tcg_temp_new_i64();
8116 gen_load_fpr64(ctx
, fp0
, fs
);
8117 gen_load_fpr64(ctx
, fp1
, ft
);
8118 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8119 tcg_temp_free_i64(fp1
);
8120 gen_store_fpr64(ctx
, fp0
, fd
);
8121 tcg_temp_free_i64(fp0
);
8126 check_cp1_64bitmode(ctx
);
8128 TCGv_i64 fp0
= tcg_temp_new_i64();
8130 gen_load_fpr64(ctx
, fp0
, fs
);
8131 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8132 gen_store_fpr64(ctx
, fp0
, fd
);
8133 tcg_temp_free_i64(fp0
);
8138 check_cp1_64bitmode(ctx
);
8140 TCGv_i64 fp0
= tcg_temp_new_i64();
8142 gen_load_fpr64(ctx
, fp0
, fs
);
8143 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8144 gen_store_fpr64(ctx
, fp0
, fd
);
8145 tcg_temp_free_i64(fp0
);
8150 check_cp1_64bitmode(ctx
);
8152 TCGv_i64 fp0
= tcg_temp_new_i64();
8153 TCGv_i64 fp1
= tcg_temp_new_i64();
8155 gen_load_fpr64(ctx
, fp0
, fs
);
8156 gen_load_fpr64(ctx
, fp1
, ft
);
8157 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8158 tcg_temp_free_i64(fp1
);
8159 gen_store_fpr64(ctx
, fp0
, fd
);
8160 tcg_temp_free_i64(fp0
);
8173 case OPC_CMP_NGLE_D
:
8180 if (ctx
->opcode
& (1 << 6)) {
8181 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8182 opn
= condnames_abs
[func
-48];
8184 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8185 opn
= condnames
[func
-48];
8189 check_cp1_registers(ctx
, fs
);
8191 TCGv_i32 fp32
= tcg_temp_new_i32();
8192 TCGv_i64 fp64
= tcg_temp_new_i64();
8194 gen_load_fpr64(ctx
, fp64
, fs
);
8195 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8196 tcg_temp_free_i64(fp64
);
8197 gen_store_fpr32(fp32
, fd
);
8198 tcg_temp_free_i32(fp32
);
8203 check_cp1_registers(ctx
, fs
);
8205 TCGv_i32 fp32
= tcg_temp_new_i32();
8206 TCGv_i64 fp64
= tcg_temp_new_i64();
8208 gen_load_fpr64(ctx
, fp64
, fs
);
8209 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8210 tcg_temp_free_i64(fp64
);
8211 gen_store_fpr32(fp32
, fd
);
8212 tcg_temp_free_i32(fp32
);
8217 check_cp1_64bitmode(ctx
);
8219 TCGv_i64 fp0
= tcg_temp_new_i64();
8221 gen_load_fpr64(ctx
, fp0
, fs
);
8222 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8223 gen_store_fpr64(ctx
, fp0
, fd
);
8224 tcg_temp_free_i64(fp0
);
8230 TCGv_i32 fp0
= tcg_temp_new_i32();
8232 gen_load_fpr32(fp0
, fs
);
8233 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8234 gen_store_fpr32(fp0
, fd
);
8235 tcg_temp_free_i32(fp0
);
8240 check_cp1_registers(ctx
, fd
);
8242 TCGv_i32 fp32
= tcg_temp_new_i32();
8243 TCGv_i64 fp64
= tcg_temp_new_i64();
8245 gen_load_fpr32(fp32
, fs
);
8246 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8247 tcg_temp_free_i32(fp32
);
8248 gen_store_fpr64(ctx
, fp64
, fd
);
8249 tcg_temp_free_i64(fp64
);
8254 check_cp1_64bitmode(ctx
);
8256 TCGv_i32 fp32
= tcg_temp_new_i32();
8257 TCGv_i64 fp64
= tcg_temp_new_i64();
8259 gen_load_fpr64(ctx
, fp64
, fs
);
8260 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8261 tcg_temp_free_i64(fp64
);
8262 gen_store_fpr32(fp32
, fd
);
8263 tcg_temp_free_i32(fp32
);
8268 check_cp1_64bitmode(ctx
);
8270 TCGv_i64 fp0
= tcg_temp_new_i64();
8272 gen_load_fpr64(ctx
, fp0
, fs
);
8273 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8274 gen_store_fpr64(ctx
, fp0
, fd
);
8275 tcg_temp_free_i64(fp0
);
8280 check_cp1_64bitmode(ctx
);
8282 TCGv_i64 fp0
= tcg_temp_new_i64();
8284 gen_load_fpr64(ctx
, fp0
, fs
);
8285 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8286 gen_store_fpr64(ctx
, fp0
, fd
);
8287 tcg_temp_free_i64(fp0
);
8292 check_cp1_64bitmode(ctx
);
8294 TCGv_i64 fp0
= tcg_temp_new_i64();
8295 TCGv_i64 fp1
= tcg_temp_new_i64();
8297 gen_load_fpr64(ctx
, fp0
, fs
);
8298 gen_load_fpr64(ctx
, fp1
, ft
);
8299 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8300 tcg_temp_free_i64(fp1
);
8301 gen_store_fpr64(ctx
, fp0
, fd
);
8302 tcg_temp_free_i64(fp0
);
8307 check_cp1_64bitmode(ctx
);
8309 TCGv_i64 fp0
= tcg_temp_new_i64();
8310 TCGv_i64 fp1
= tcg_temp_new_i64();
8312 gen_load_fpr64(ctx
, fp0
, fs
);
8313 gen_load_fpr64(ctx
, fp1
, ft
);
8314 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8315 tcg_temp_free_i64(fp1
);
8316 gen_store_fpr64(ctx
, fp0
, fd
);
8317 tcg_temp_free_i64(fp0
);
8322 check_cp1_64bitmode(ctx
);
8324 TCGv_i64 fp0
= tcg_temp_new_i64();
8325 TCGv_i64 fp1
= tcg_temp_new_i64();
8327 gen_load_fpr64(ctx
, fp0
, fs
);
8328 gen_load_fpr64(ctx
, fp1
, ft
);
8329 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8330 tcg_temp_free_i64(fp1
);
8331 gen_store_fpr64(ctx
, fp0
, fd
);
8332 tcg_temp_free_i64(fp0
);
8337 check_cp1_64bitmode(ctx
);
8339 TCGv_i64 fp0
= tcg_temp_new_i64();
8341 gen_load_fpr64(ctx
, fp0
, fs
);
8342 gen_helper_float_abs_ps(fp0
, fp0
);
8343 gen_store_fpr64(ctx
, fp0
, fd
);
8344 tcg_temp_free_i64(fp0
);
8349 check_cp1_64bitmode(ctx
);
8351 TCGv_i64 fp0
= tcg_temp_new_i64();
8353 gen_load_fpr64(ctx
, fp0
, fs
);
8354 gen_store_fpr64(ctx
, fp0
, fd
);
8355 tcg_temp_free_i64(fp0
);
8360 check_cp1_64bitmode(ctx
);
8362 TCGv_i64 fp0
= tcg_temp_new_i64();
8364 gen_load_fpr64(ctx
, fp0
, fs
);
8365 gen_helper_float_chs_ps(fp0
, fp0
);
8366 gen_store_fpr64(ctx
, fp0
, fd
);
8367 tcg_temp_free_i64(fp0
);
8372 check_cp1_64bitmode(ctx
);
8373 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8377 check_cp1_64bitmode(ctx
);
8379 int l1
= gen_new_label();
8383 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8384 fp0
= tcg_temp_new_i64();
8385 gen_load_fpr64(ctx
, fp0
, fs
);
8386 gen_store_fpr64(ctx
, fp0
, fd
);
8387 tcg_temp_free_i64(fp0
);
8393 check_cp1_64bitmode(ctx
);
8395 int l1
= gen_new_label();
8399 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8400 fp0
= tcg_temp_new_i64();
8401 gen_load_fpr64(ctx
, fp0
, fs
);
8402 gen_store_fpr64(ctx
, fp0
, fd
);
8403 tcg_temp_free_i64(fp0
);
8410 check_cp1_64bitmode(ctx
);
8412 TCGv_i64 fp0
= tcg_temp_new_i64();
8413 TCGv_i64 fp1
= tcg_temp_new_i64();
8415 gen_load_fpr64(ctx
, fp0
, ft
);
8416 gen_load_fpr64(ctx
, fp1
, fs
);
8417 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8418 tcg_temp_free_i64(fp1
);
8419 gen_store_fpr64(ctx
, fp0
, fd
);
8420 tcg_temp_free_i64(fp0
);
8425 check_cp1_64bitmode(ctx
);
8427 TCGv_i64 fp0
= tcg_temp_new_i64();
8428 TCGv_i64 fp1
= tcg_temp_new_i64();
8430 gen_load_fpr64(ctx
, fp0
, ft
);
8431 gen_load_fpr64(ctx
, fp1
, fs
);
8432 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8433 tcg_temp_free_i64(fp1
);
8434 gen_store_fpr64(ctx
, fp0
, fd
);
8435 tcg_temp_free_i64(fp0
);
8440 check_cp1_64bitmode(ctx
);
8442 TCGv_i64 fp0
= tcg_temp_new_i64();
8443 TCGv_i64 fp1
= tcg_temp_new_i64();
8445 gen_load_fpr64(ctx
, fp0
, fs
);
8446 gen_load_fpr64(ctx
, fp1
, ft
);
8447 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8448 tcg_temp_free_i64(fp1
);
8449 gen_store_fpr64(ctx
, fp0
, fd
);
8450 tcg_temp_free_i64(fp0
);
8455 check_cp1_64bitmode(ctx
);
8457 TCGv_i64 fp0
= tcg_temp_new_i64();
8459 gen_load_fpr64(ctx
, fp0
, fs
);
8460 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8461 gen_store_fpr64(ctx
, fp0
, fd
);
8462 tcg_temp_free_i64(fp0
);
8467 check_cp1_64bitmode(ctx
);
8469 TCGv_i64 fp0
= tcg_temp_new_i64();
8471 gen_load_fpr64(ctx
, fp0
, fs
);
8472 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8473 gen_store_fpr64(ctx
, fp0
, fd
);
8474 tcg_temp_free_i64(fp0
);
8479 check_cp1_64bitmode(ctx
);
8481 TCGv_i64 fp0
= tcg_temp_new_i64();
8482 TCGv_i64 fp1
= tcg_temp_new_i64();
8484 gen_load_fpr64(ctx
, fp0
, fs
);
8485 gen_load_fpr64(ctx
, fp1
, ft
);
8486 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8487 tcg_temp_free_i64(fp1
);
8488 gen_store_fpr64(ctx
, fp0
, fd
);
8489 tcg_temp_free_i64(fp0
);
8494 check_cp1_64bitmode(ctx
);
8496 TCGv_i32 fp0
= tcg_temp_new_i32();
8498 gen_load_fpr32h(fp0
, fs
);
8499 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8500 gen_store_fpr32(fp0
, fd
);
8501 tcg_temp_free_i32(fp0
);
8506 check_cp1_64bitmode(ctx
);
8508 TCGv_i64 fp0
= tcg_temp_new_i64();
8510 gen_load_fpr64(ctx
, fp0
, fs
);
8511 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8512 gen_store_fpr64(ctx
, fp0
, fd
);
8513 tcg_temp_free_i64(fp0
);
8518 check_cp1_64bitmode(ctx
);
8520 TCGv_i32 fp0
= tcg_temp_new_i32();
8522 gen_load_fpr32(fp0
, fs
);
8523 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8524 gen_store_fpr32(fp0
, fd
);
8525 tcg_temp_free_i32(fp0
);
8530 check_cp1_64bitmode(ctx
);
8532 TCGv_i32 fp0
= tcg_temp_new_i32();
8533 TCGv_i32 fp1
= tcg_temp_new_i32();
8535 gen_load_fpr32(fp0
, fs
);
8536 gen_load_fpr32(fp1
, ft
);
8537 gen_store_fpr32h(fp0
, fd
);
8538 gen_store_fpr32(fp1
, fd
);
8539 tcg_temp_free_i32(fp0
);
8540 tcg_temp_free_i32(fp1
);
8545 check_cp1_64bitmode(ctx
);
8547 TCGv_i32 fp0
= tcg_temp_new_i32();
8548 TCGv_i32 fp1
= tcg_temp_new_i32();
8550 gen_load_fpr32(fp0
, fs
);
8551 gen_load_fpr32h(fp1
, ft
);
8552 gen_store_fpr32(fp1
, fd
);
8553 gen_store_fpr32h(fp0
, fd
);
8554 tcg_temp_free_i32(fp0
);
8555 tcg_temp_free_i32(fp1
);
8560 check_cp1_64bitmode(ctx
);
8562 TCGv_i32 fp0
= tcg_temp_new_i32();
8563 TCGv_i32 fp1
= tcg_temp_new_i32();
8565 gen_load_fpr32h(fp0
, fs
);
8566 gen_load_fpr32(fp1
, ft
);
8567 gen_store_fpr32(fp1
, fd
);
8568 gen_store_fpr32h(fp0
, fd
);
8569 tcg_temp_free_i32(fp0
);
8570 tcg_temp_free_i32(fp1
);
8575 check_cp1_64bitmode(ctx
);
8577 TCGv_i32 fp0
= tcg_temp_new_i32();
8578 TCGv_i32 fp1
= tcg_temp_new_i32();
8580 gen_load_fpr32h(fp0
, fs
);
8581 gen_load_fpr32h(fp1
, ft
);
8582 gen_store_fpr32(fp1
, fd
);
8583 gen_store_fpr32h(fp0
, fd
);
8584 tcg_temp_free_i32(fp0
);
8585 tcg_temp_free_i32(fp1
);
8592 case OPC_CMP_UEQ_PS
:
8593 case OPC_CMP_OLT_PS
:
8594 case OPC_CMP_ULT_PS
:
8595 case OPC_CMP_OLE_PS
:
8596 case OPC_CMP_ULE_PS
:
8598 case OPC_CMP_NGLE_PS
:
8599 case OPC_CMP_SEQ_PS
:
8600 case OPC_CMP_NGL_PS
:
8602 case OPC_CMP_NGE_PS
:
8604 case OPC_CMP_NGT_PS
:
8605 if (ctx
->opcode
& (1 << 6)) {
8606 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8607 opn
= condnames_abs
[func
-48];
8609 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8610 opn
= condnames
[func
-48];
8615 generate_exception (ctx
, EXCP_RI
);
8618 (void)opn
; /* avoid a compiler warning */
8621 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8624 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8627 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8632 /* Coprocessor 3 (FPU) */
8633 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8634 int fd
, int fs
, int base
, int index
)
8636 const char *opn
= "extended float load/store";
8638 TCGv t0
= tcg_temp_new();
8641 gen_load_gpr(t0
, index
);
8642 } else if (index
== 0) {
8643 gen_load_gpr(t0
, base
);
8645 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8647 /* Don't do NOP if destination is zero: we must perform the actual
8653 TCGv_i32 fp0
= tcg_temp_new_i32();
8655 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
8656 tcg_gen_trunc_tl_i32(fp0
, t0
);
8657 gen_store_fpr32(fp0
, fd
);
8658 tcg_temp_free_i32(fp0
);
8664 check_cp1_registers(ctx
, fd
);
8666 TCGv_i64 fp0
= tcg_temp_new_i64();
8668 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8669 gen_store_fpr64(ctx
, fp0
, fd
);
8670 tcg_temp_free_i64(fp0
);
8675 check_cp1_64bitmode(ctx
);
8676 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8678 TCGv_i64 fp0
= tcg_temp_new_i64();
8680 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8681 gen_store_fpr64(ctx
, fp0
, fd
);
8682 tcg_temp_free_i64(fp0
);
8689 TCGv_i32 fp0
= tcg_temp_new_i32();
8690 TCGv t1
= tcg_temp_new();
8692 gen_load_fpr32(fp0
, fs
);
8693 tcg_gen_extu_i32_tl(t1
, fp0
);
8694 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
8695 tcg_temp_free_i32(fp0
);
8703 check_cp1_registers(ctx
, fs
);
8705 TCGv_i64 fp0
= tcg_temp_new_i64();
8707 gen_load_fpr64(ctx
, fp0
, fs
);
8708 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8709 tcg_temp_free_i64(fp0
);
8715 check_cp1_64bitmode(ctx
);
8716 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8718 TCGv_i64 fp0
= tcg_temp_new_i64();
8720 gen_load_fpr64(ctx
, fp0
, fs
);
8721 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8722 tcg_temp_free_i64(fp0
);
8729 (void)opn
; (void)store
; /* avoid compiler warnings */
8730 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8731 regnames
[index
], regnames
[base
]);
8734 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8735 int fd
, int fr
, int fs
, int ft
)
8737 const char *opn
= "flt3_arith";
8741 check_cp1_64bitmode(ctx
);
8743 TCGv t0
= tcg_temp_local_new();
8744 TCGv_i32 fp
= tcg_temp_new_i32();
8745 TCGv_i32 fph
= tcg_temp_new_i32();
8746 int l1
= gen_new_label();
8747 int l2
= gen_new_label();
8749 gen_load_gpr(t0
, fr
);
8750 tcg_gen_andi_tl(t0
, t0
, 0x7);
8752 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8753 gen_load_fpr32(fp
, fs
);
8754 gen_load_fpr32h(fph
, fs
);
8755 gen_store_fpr32(fp
, fd
);
8756 gen_store_fpr32h(fph
, fd
);
8759 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8761 #ifdef TARGET_WORDS_BIGENDIAN
8762 gen_load_fpr32(fp
, fs
);
8763 gen_load_fpr32h(fph
, ft
);
8764 gen_store_fpr32h(fp
, fd
);
8765 gen_store_fpr32(fph
, fd
);
8767 gen_load_fpr32h(fph
, fs
);
8768 gen_load_fpr32(fp
, ft
);
8769 gen_store_fpr32(fph
, fd
);
8770 gen_store_fpr32h(fp
, fd
);
8773 tcg_temp_free_i32(fp
);
8774 tcg_temp_free_i32(fph
);
8781 TCGv_i32 fp0
= tcg_temp_new_i32();
8782 TCGv_i32 fp1
= tcg_temp_new_i32();
8783 TCGv_i32 fp2
= tcg_temp_new_i32();
8785 gen_load_fpr32(fp0
, fs
);
8786 gen_load_fpr32(fp1
, ft
);
8787 gen_load_fpr32(fp2
, fr
);
8788 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8789 tcg_temp_free_i32(fp0
);
8790 tcg_temp_free_i32(fp1
);
8791 gen_store_fpr32(fp2
, fd
);
8792 tcg_temp_free_i32(fp2
);
8798 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8800 TCGv_i64 fp0
= tcg_temp_new_i64();
8801 TCGv_i64 fp1
= tcg_temp_new_i64();
8802 TCGv_i64 fp2
= tcg_temp_new_i64();
8804 gen_load_fpr64(ctx
, fp0
, fs
);
8805 gen_load_fpr64(ctx
, fp1
, ft
);
8806 gen_load_fpr64(ctx
, fp2
, fr
);
8807 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8808 tcg_temp_free_i64(fp0
);
8809 tcg_temp_free_i64(fp1
);
8810 gen_store_fpr64(ctx
, fp2
, fd
);
8811 tcg_temp_free_i64(fp2
);
8816 check_cp1_64bitmode(ctx
);
8818 TCGv_i64 fp0
= tcg_temp_new_i64();
8819 TCGv_i64 fp1
= tcg_temp_new_i64();
8820 TCGv_i64 fp2
= tcg_temp_new_i64();
8822 gen_load_fpr64(ctx
, fp0
, fs
);
8823 gen_load_fpr64(ctx
, fp1
, ft
);
8824 gen_load_fpr64(ctx
, fp2
, fr
);
8825 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8826 tcg_temp_free_i64(fp0
);
8827 tcg_temp_free_i64(fp1
);
8828 gen_store_fpr64(ctx
, fp2
, fd
);
8829 tcg_temp_free_i64(fp2
);
8836 TCGv_i32 fp0
= tcg_temp_new_i32();
8837 TCGv_i32 fp1
= tcg_temp_new_i32();
8838 TCGv_i32 fp2
= tcg_temp_new_i32();
8840 gen_load_fpr32(fp0
, fs
);
8841 gen_load_fpr32(fp1
, ft
);
8842 gen_load_fpr32(fp2
, fr
);
8843 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8844 tcg_temp_free_i32(fp0
);
8845 tcg_temp_free_i32(fp1
);
8846 gen_store_fpr32(fp2
, fd
);
8847 tcg_temp_free_i32(fp2
);
8853 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8855 TCGv_i64 fp0
= tcg_temp_new_i64();
8856 TCGv_i64 fp1
= tcg_temp_new_i64();
8857 TCGv_i64 fp2
= tcg_temp_new_i64();
8859 gen_load_fpr64(ctx
, fp0
, fs
);
8860 gen_load_fpr64(ctx
, fp1
, ft
);
8861 gen_load_fpr64(ctx
, fp2
, fr
);
8862 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8863 tcg_temp_free_i64(fp0
);
8864 tcg_temp_free_i64(fp1
);
8865 gen_store_fpr64(ctx
, fp2
, fd
);
8866 tcg_temp_free_i64(fp2
);
8871 check_cp1_64bitmode(ctx
);
8873 TCGv_i64 fp0
= tcg_temp_new_i64();
8874 TCGv_i64 fp1
= tcg_temp_new_i64();
8875 TCGv_i64 fp2
= tcg_temp_new_i64();
8877 gen_load_fpr64(ctx
, fp0
, fs
);
8878 gen_load_fpr64(ctx
, fp1
, ft
);
8879 gen_load_fpr64(ctx
, fp2
, fr
);
8880 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8881 tcg_temp_free_i64(fp0
);
8882 tcg_temp_free_i64(fp1
);
8883 gen_store_fpr64(ctx
, fp2
, fd
);
8884 tcg_temp_free_i64(fp2
);
8891 TCGv_i32 fp0
= tcg_temp_new_i32();
8892 TCGv_i32 fp1
= tcg_temp_new_i32();
8893 TCGv_i32 fp2
= tcg_temp_new_i32();
8895 gen_load_fpr32(fp0
, fs
);
8896 gen_load_fpr32(fp1
, ft
);
8897 gen_load_fpr32(fp2
, fr
);
8898 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8899 tcg_temp_free_i32(fp0
);
8900 tcg_temp_free_i32(fp1
);
8901 gen_store_fpr32(fp2
, fd
);
8902 tcg_temp_free_i32(fp2
);
8908 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8910 TCGv_i64 fp0
= tcg_temp_new_i64();
8911 TCGv_i64 fp1
= tcg_temp_new_i64();
8912 TCGv_i64 fp2
= tcg_temp_new_i64();
8914 gen_load_fpr64(ctx
, fp0
, fs
);
8915 gen_load_fpr64(ctx
, fp1
, ft
);
8916 gen_load_fpr64(ctx
, fp2
, fr
);
8917 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8918 tcg_temp_free_i64(fp0
);
8919 tcg_temp_free_i64(fp1
);
8920 gen_store_fpr64(ctx
, fp2
, fd
);
8921 tcg_temp_free_i64(fp2
);
8926 check_cp1_64bitmode(ctx
);
8928 TCGv_i64 fp0
= tcg_temp_new_i64();
8929 TCGv_i64 fp1
= tcg_temp_new_i64();
8930 TCGv_i64 fp2
= tcg_temp_new_i64();
8932 gen_load_fpr64(ctx
, fp0
, fs
);
8933 gen_load_fpr64(ctx
, fp1
, ft
);
8934 gen_load_fpr64(ctx
, fp2
, fr
);
8935 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8936 tcg_temp_free_i64(fp0
);
8937 tcg_temp_free_i64(fp1
);
8938 gen_store_fpr64(ctx
, fp2
, fd
);
8939 tcg_temp_free_i64(fp2
);
8946 TCGv_i32 fp0
= tcg_temp_new_i32();
8947 TCGv_i32 fp1
= tcg_temp_new_i32();
8948 TCGv_i32 fp2
= tcg_temp_new_i32();
8950 gen_load_fpr32(fp0
, fs
);
8951 gen_load_fpr32(fp1
, ft
);
8952 gen_load_fpr32(fp2
, fr
);
8953 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8954 tcg_temp_free_i32(fp0
);
8955 tcg_temp_free_i32(fp1
);
8956 gen_store_fpr32(fp2
, fd
);
8957 tcg_temp_free_i32(fp2
);
8963 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8965 TCGv_i64 fp0
= tcg_temp_new_i64();
8966 TCGv_i64 fp1
= tcg_temp_new_i64();
8967 TCGv_i64 fp2
= tcg_temp_new_i64();
8969 gen_load_fpr64(ctx
, fp0
, fs
);
8970 gen_load_fpr64(ctx
, fp1
, ft
);
8971 gen_load_fpr64(ctx
, fp2
, fr
);
8972 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8973 tcg_temp_free_i64(fp0
);
8974 tcg_temp_free_i64(fp1
);
8975 gen_store_fpr64(ctx
, fp2
, fd
);
8976 tcg_temp_free_i64(fp2
);
8981 check_cp1_64bitmode(ctx
);
8983 TCGv_i64 fp0
= tcg_temp_new_i64();
8984 TCGv_i64 fp1
= tcg_temp_new_i64();
8985 TCGv_i64 fp2
= tcg_temp_new_i64();
8987 gen_load_fpr64(ctx
, fp0
, fs
);
8988 gen_load_fpr64(ctx
, fp1
, ft
);
8989 gen_load_fpr64(ctx
, fp2
, fr
);
8990 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8991 tcg_temp_free_i64(fp0
);
8992 tcg_temp_free_i64(fp1
);
8993 gen_store_fpr64(ctx
, fp2
, fd
);
8994 tcg_temp_free_i64(fp2
);
9000 generate_exception (ctx
, EXCP_RI
);
9003 (void)opn
; /* avoid a compiler warning */
9004 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9005 fregnames
[fs
], fregnames
[ft
]);
9008 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9012 #if !defined(CONFIG_USER_ONLY)
9013 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9014 Therefore only check the ISA in system mode. */
9015 check_insn(ctx
, ISA_MIPS32R2
);
9017 t0
= tcg_temp_new();
9021 save_cpu_state(ctx
, 1);
9022 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9023 gen_store_gpr(t0
, rt
);
9026 save_cpu_state(ctx
, 1);
9027 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9028 gen_store_gpr(t0
, rt
);
9031 save_cpu_state(ctx
, 1);
9032 gen_helper_rdhwr_cc(t0
, cpu_env
);
9033 gen_store_gpr(t0
, rt
);
9036 save_cpu_state(ctx
, 1);
9037 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9038 gen_store_gpr(t0
, rt
);
9041 #if defined(CONFIG_USER_ONLY)
9042 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9043 gen_store_gpr(t0
, rt
);
9046 /* XXX: Some CPUs implement this in hardware.
9047 Not supported yet. */
9049 default: /* Invalid */
9050 MIPS_INVAL("rdhwr");
9051 generate_exception(ctx
, EXCP_RI
);
9057 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9059 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9060 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9061 /* Branches completion */
9062 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9063 ctx
->bstate
= BS_BRANCH
;
9064 save_cpu_state(ctx
, 0);
9065 /* FIXME: Need to clear can_do_io. */
9066 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9068 /* unconditional branch */
9069 MIPS_DEBUG("unconditional branch");
9070 if (proc_hflags
& MIPS_HFLAG_BX
) {
9071 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9073 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9076 /* blikely taken case */
9077 MIPS_DEBUG("blikely branch taken");
9078 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9081 /* Conditional branch */
9082 MIPS_DEBUG("conditional branch");
9084 int l1
= gen_new_label();
9086 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9087 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9089 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9093 /* unconditional branch to register */
9094 MIPS_DEBUG("branch to register");
9095 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9096 TCGv t0
= tcg_temp_new();
9097 TCGv_i32 t1
= tcg_temp_new_i32();
9099 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9100 tcg_gen_trunc_tl_i32(t1
, t0
);
9102 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9103 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9104 tcg_gen_or_i32(hflags
, hflags
, t1
);
9105 tcg_temp_free_i32(t1
);
9107 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9109 tcg_gen_mov_tl(cpu_PC
, btarget
);
9111 if (ctx
->singlestep_enabled
) {
9112 save_cpu_state(ctx
, 0);
9113 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9118 MIPS_DEBUG("unknown branch");
9124 /* ISA extensions (ASEs) */
9125 /* MIPS16 extension to MIPS32 */
9127 /* MIPS16 major opcodes */
9129 M16_OPC_ADDIUSP
= 0x00,
9130 M16_OPC_ADDIUPC
= 0x01,
9133 M16_OPC_BEQZ
= 0x04,
9134 M16_OPC_BNEQZ
= 0x05,
9135 M16_OPC_SHIFT
= 0x06,
9137 M16_OPC_RRIA
= 0x08,
9138 M16_OPC_ADDIU8
= 0x09,
9139 M16_OPC_SLTI
= 0x0a,
9140 M16_OPC_SLTIU
= 0x0b,
9143 M16_OPC_CMPI
= 0x0e,
9147 M16_OPC_LWSP
= 0x12,
9151 M16_OPC_LWPC
= 0x16,
9155 M16_OPC_SWSP
= 0x1a,
9159 M16_OPC_EXTEND
= 0x1e,
9163 /* I8 funct field */
9182 /* RR funct field */
9216 /* I64 funct field */
9228 /* RR ry field for CNVT */
9230 RR_RY_CNVT_ZEB
= 0x0,
9231 RR_RY_CNVT_ZEH
= 0x1,
9232 RR_RY_CNVT_ZEW
= 0x2,
9233 RR_RY_CNVT_SEB
= 0x4,
9234 RR_RY_CNVT_SEH
= 0x5,
9235 RR_RY_CNVT_SEW
= 0x6,
9238 static int xlat (int r
)
9240 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9245 static void gen_mips16_save (DisasContext
*ctx
,
9246 int xsregs
, int aregs
,
9247 int do_ra
, int do_s0
, int do_s1
,
9250 TCGv t0
= tcg_temp_new();
9251 TCGv t1
= tcg_temp_new();
9281 generate_exception(ctx
, EXCP_RI
);
9287 gen_base_offset_addr(ctx
, t0
, 29, 12);
9288 gen_load_gpr(t1
, 7);
9289 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9292 gen_base_offset_addr(ctx
, t0
, 29, 8);
9293 gen_load_gpr(t1
, 6);
9294 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9297 gen_base_offset_addr(ctx
, t0
, 29, 4);
9298 gen_load_gpr(t1
, 5);
9299 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9302 gen_base_offset_addr(ctx
, t0
, 29, 0);
9303 gen_load_gpr(t1
, 4);
9304 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9307 gen_load_gpr(t0
, 29);
9309 #define DECR_AND_STORE(reg) do { \
9310 tcg_gen_subi_tl(t0, t0, 4); \
9311 gen_load_gpr(t1, reg); \
9312 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9376 generate_exception(ctx
, EXCP_RI
);
9392 #undef DECR_AND_STORE
9394 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9399 static void gen_mips16_restore (DisasContext
*ctx
,
9400 int xsregs
, int aregs
,
9401 int do_ra
, int do_s0
, int do_s1
,
9405 TCGv t0
= tcg_temp_new();
9406 TCGv t1
= tcg_temp_new();
9408 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9410 #define DECR_AND_LOAD(reg) do { \
9411 tcg_gen_subi_tl(t0, t0, 4); \
9412 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9413 gen_store_gpr(t1, reg); \
9477 generate_exception(ctx
, EXCP_RI
);
9493 #undef DECR_AND_LOAD
9495 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9500 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9501 int is_64_bit
, int extended
)
9505 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9506 generate_exception(ctx
, EXCP_RI
);
9510 t0
= tcg_temp_new();
9512 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9513 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9515 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9521 #if defined(TARGET_MIPS64)
9522 static void decode_i64_mips16 (DisasContext
*ctx
,
9523 int ry
, int funct
, int16_t offset
,
9529 offset
= extended
? offset
: offset
<< 3;
9530 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9534 offset
= extended
? offset
: offset
<< 3;
9535 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9539 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9540 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9544 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9545 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9548 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9549 generate_exception(ctx
, EXCP_RI
);
9551 offset
= extended
? offset
: offset
<< 3;
9552 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9557 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9558 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9562 offset
= extended
? offset
: offset
<< 2;
9563 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9567 offset
= extended
? offset
: offset
<< 2;
9568 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9574 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9576 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9577 int op
, rx
, ry
, funct
, sa
;
9578 int16_t imm
, offset
;
9580 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9581 op
= (ctx
->opcode
>> 11) & 0x1f;
9582 sa
= (ctx
->opcode
>> 22) & 0x1f;
9583 funct
= (ctx
->opcode
>> 8) & 0x7;
9584 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9585 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9586 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9587 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9588 | (ctx
->opcode
& 0x1f));
9590 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9593 case M16_OPC_ADDIUSP
:
9594 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9596 case M16_OPC_ADDIUPC
:
9597 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9600 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9601 /* No delay slot, so just process as a normal instruction */
9604 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9605 /* No delay slot, so just process as a normal instruction */
9608 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9609 /* No delay slot, so just process as a normal instruction */
9612 switch (ctx
->opcode
& 0x3) {
9614 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9617 #if defined(TARGET_MIPS64)
9619 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9621 generate_exception(ctx
, EXCP_RI
);
9625 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9628 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9632 #if defined(TARGET_MIPS64)
9635 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9639 imm
= ctx
->opcode
& 0xf;
9640 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9641 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9642 imm
= (int16_t) (imm
<< 1) >> 1;
9643 if ((ctx
->opcode
>> 4) & 0x1) {
9644 #if defined(TARGET_MIPS64)
9646 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9648 generate_exception(ctx
, EXCP_RI
);
9651 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9654 case M16_OPC_ADDIU8
:
9655 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9658 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9661 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9666 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9669 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9672 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9675 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9679 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9680 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9681 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9682 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9683 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9684 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9685 | (ctx
->opcode
& 0xf)) << 3;
9687 if (ctx
->opcode
& (1 << 7)) {
9688 gen_mips16_save(ctx
, xsregs
, aregs
,
9689 do_ra
, do_s0
, do_s1
,
9692 gen_mips16_restore(ctx
, xsregs
, aregs
,
9693 do_ra
, do_s0
, do_s1
,
9699 generate_exception(ctx
, EXCP_RI
);
9704 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9707 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9709 #if defined(TARGET_MIPS64)
9711 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9715 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9718 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9721 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9724 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9727 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9730 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9733 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9735 #if defined(TARGET_MIPS64)
9737 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9741 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9744 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9747 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9750 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9752 #if defined(TARGET_MIPS64)
9754 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9758 generate_exception(ctx
, EXCP_RI
);
9765 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9769 int op
, cnvt_op
, op1
, offset
;
9773 op
= (ctx
->opcode
>> 11) & 0x1f;
9774 sa
= (ctx
->opcode
>> 2) & 0x7;
9775 sa
= sa
== 0 ? 8 : sa
;
9776 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9777 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9778 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9779 op1
= offset
= ctx
->opcode
& 0x1f;
9784 case M16_OPC_ADDIUSP
:
9786 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9788 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9791 case M16_OPC_ADDIUPC
:
9792 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9795 offset
= (ctx
->opcode
& 0x7ff) << 1;
9796 offset
= (int16_t)(offset
<< 4) >> 4;
9797 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9798 /* No delay slot, so just process as a normal instruction */
9801 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9802 offset
= (((ctx
->opcode
& 0x1f) << 21)
9803 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9805 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9806 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9810 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9811 /* No delay slot, so just process as a normal instruction */
9814 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9815 /* No delay slot, so just process as a normal instruction */
9818 switch (ctx
->opcode
& 0x3) {
9820 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9823 #if defined(TARGET_MIPS64)
9825 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9827 generate_exception(ctx
, EXCP_RI
);
9831 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9834 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9838 #if defined(TARGET_MIPS64)
9841 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9846 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9848 if ((ctx
->opcode
>> 4) & 1) {
9849 #if defined(TARGET_MIPS64)
9851 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9853 generate_exception(ctx
, EXCP_RI
);
9856 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9860 case M16_OPC_ADDIU8
:
9862 int16_t imm
= (int8_t) ctx
->opcode
;
9864 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9869 int16_t imm
= (uint8_t) ctx
->opcode
;
9870 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9875 int16_t imm
= (uint8_t) ctx
->opcode
;
9876 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9883 funct
= (ctx
->opcode
>> 8) & 0x7;
9886 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9887 ((int8_t)ctx
->opcode
) << 1);
9890 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9891 ((int8_t)ctx
->opcode
) << 1);
9894 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9897 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9898 ((int8_t)ctx
->opcode
) << 3);
9902 int do_ra
= ctx
->opcode
& (1 << 6);
9903 int do_s0
= ctx
->opcode
& (1 << 5);
9904 int do_s1
= ctx
->opcode
& (1 << 4);
9905 int framesize
= ctx
->opcode
& 0xf;
9907 if (framesize
== 0) {
9910 framesize
= framesize
<< 3;
9913 if (ctx
->opcode
& (1 << 7)) {
9914 gen_mips16_save(ctx
, 0, 0,
9915 do_ra
, do_s0
, do_s1
, framesize
);
9917 gen_mips16_restore(ctx
, 0, 0,
9918 do_ra
, do_s0
, do_s1
, framesize
);
9924 int rz
= xlat(ctx
->opcode
& 0x7);
9926 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9927 ((ctx
->opcode
>> 5) & 0x7);
9928 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9932 reg32
= ctx
->opcode
& 0x1f;
9933 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9936 generate_exception(ctx
, EXCP_RI
);
9943 int16_t imm
= (uint8_t) ctx
->opcode
;
9945 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9950 int16_t imm
= (uint8_t) ctx
->opcode
;
9951 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9954 #if defined(TARGET_MIPS64)
9957 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9961 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9964 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9967 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9970 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
9973 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9976 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
9979 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
9981 #if defined (TARGET_MIPS64)
9984 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
9988 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9991 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
9994 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9997 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10001 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10004 switch (ctx
->opcode
& 0x3) {
10006 mips32_op
= OPC_ADDU
;
10009 mips32_op
= OPC_SUBU
;
10011 #if defined(TARGET_MIPS64)
10013 mips32_op
= OPC_DADDU
;
10014 check_mips_64(ctx
);
10017 mips32_op
= OPC_DSUBU
;
10018 check_mips_64(ctx
);
10022 generate_exception(ctx
, EXCP_RI
);
10026 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10035 int nd
= (ctx
->opcode
>> 7) & 0x1;
10036 int link
= (ctx
->opcode
>> 6) & 0x1;
10037 int ra
= (ctx
->opcode
>> 5) & 0x1;
10040 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10045 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10049 /* XXX: not clear which exception should be raised
10050 * when in debug mode...
10052 check_insn(ctx
, ISA_MIPS32
);
10053 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10054 generate_exception(ctx
, EXCP_DBp
);
10056 generate_exception(ctx
, EXCP_DBp
);
10060 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10063 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10066 generate_exception(ctx
, EXCP_BREAK
);
10069 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10072 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10075 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10077 #if defined (TARGET_MIPS64)
10079 check_mips_64(ctx
);
10080 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10084 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10087 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10090 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10093 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10096 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10099 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10102 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10106 case RR_RY_CNVT_ZEB
:
10107 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10109 case RR_RY_CNVT_ZEH
:
10110 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10112 case RR_RY_CNVT_SEB
:
10113 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10115 case RR_RY_CNVT_SEH
:
10116 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10118 #if defined (TARGET_MIPS64)
10119 case RR_RY_CNVT_ZEW
:
10120 check_mips_64(ctx
);
10121 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10123 case RR_RY_CNVT_SEW
:
10124 check_mips_64(ctx
);
10125 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10129 generate_exception(ctx
, EXCP_RI
);
10134 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10136 #if defined (TARGET_MIPS64)
10138 check_mips_64(ctx
);
10139 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10142 check_mips_64(ctx
);
10143 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10146 check_mips_64(ctx
);
10147 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10150 check_mips_64(ctx
);
10151 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10155 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10158 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10161 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10164 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10166 #if defined (TARGET_MIPS64)
10168 check_mips_64(ctx
);
10169 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10172 check_mips_64(ctx
);
10173 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10176 check_mips_64(ctx
);
10177 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10180 check_mips_64(ctx
);
10181 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10185 generate_exception(ctx
, EXCP_RI
);
10189 case M16_OPC_EXTEND
:
10190 decode_extended_mips16_opc(env
, ctx
);
10193 #if defined(TARGET_MIPS64)
10195 funct
= (ctx
->opcode
>> 8) & 0x7;
10196 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10200 generate_exception(ctx
, EXCP_RI
);
10207 /* microMIPS extension to MIPS32/MIPS64 */
10210 * microMIPS32/microMIPS64 major opcodes
10212 * 1. MIPS Architecture for Programmers Volume II-B:
10213 * The microMIPS32 Instruction Set (Revision 3.05)
10215 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10217 * 2. MIPS Architecture For Programmers Volume II-A:
10218 * The MIPS64 Instruction Set (Revision 3.51)
10246 POOL32S
= 0x16, /* MIPS64 */
10247 DADDIU32
= 0x17, /* MIPS64 */
10249 /* 0x1f is reserved */
10258 /* 0x20 is reserved */
10268 /* 0x28 and 0x29 are reserved */
10278 /* 0x30 and 0x31 are reserved */
10285 SD32
= 0x36, /* MIPS64 */
10286 LD32
= 0x37, /* MIPS64 */
10288 /* 0x38 and 0x39 are reserved */
10299 /* POOL32A encoding of minor opcode field */
10302 /* These opcodes are distinguished only by bits 9..6; those bits are
10303 * what are recorded below. */
10329 /* The following can be distinguished by their lower 6 bits. */
10335 /* POOL32AXF encoding of minor opcode field extension */
10338 * 1. MIPS Architecture for Programmers Volume II-B:
10339 * The microMIPS32 Instruction Set (Revision 3.05)
10341 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10343 * 2. MIPS Architecture for Programmers VolumeIV-e:
10344 * The MIPS DSP Application-Specific Extension
10345 * to the microMIPS32 Architecture (Revision 2.34)
10347 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10362 /* begin of microMIPS32 DSP */
10364 /* bits 13..12 for 0x01 */
10370 /* bits 13..12 for 0x2a */
10376 /* bits 13..12 for 0x32 */
10380 /* end of microMIPS32 DSP */
10382 /* bits 15..12 for 0x2c */
10398 /* bits 15..12 for 0x34 */
10406 /* bits 15..12 for 0x3c */
10408 JR
= 0x0, /* alias */
10413 /* bits 15..12 for 0x05 */
10417 /* bits 15..12 for 0x0d */
10427 /* bits 15..12 for 0x15 */
10433 /* bits 15..12 for 0x1d */
10437 /* bits 15..12 for 0x2d */
10442 /* bits 15..12 for 0x35 */
10449 /* POOL32B encoding of minor opcode field (bits 15..12) */
10465 /* POOL32C encoding of minor opcode field (bits 15..12) */
10473 /* 0xa is reserved */
10480 /* 0x6 is reserved */
10486 /* POOL32F encoding of minor opcode field (bits 5..0) */
10489 /* These are the bit 7..6 values */
10500 /* These are the bit 8..6 values */
10544 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10548 /* POOL32Fxf encoding of minor opcode extension field */
10586 /* POOL32I encoding of minor opcode field (bits 25..21) */
10611 /* These overlap and are distinguished by bit16 of the instruction */
10620 /* POOL16A encoding of minor opcode field */
10627 /* POOL16B encoding of minor opcode field */
10634 /* POOL16C encoding of minor opcode field */
10654 /* POOL16D encoding of minor opcode field */
10661 /* POOL16E encoding of minor opcode field */
10668 static int mmreg (int r
)
10670 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10675 /* Used for 16-bit store instructions. */
10676 static int mmreg2 (int r
)
10678 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10683 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10684 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10685 #define uMIPS_RS2(op) uMIPS_RS(op)
10686 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10687 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10688 #define uMIPS_RS5(op) (op & 0x1f)
10690 /* Signed immediate */
10691 #define SIMM(op, start, width) \
10692 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10695 /* Zero-extended immediate */
10696 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10698 static void gen_addiur1sp(DisasContext
*ctx
)
10700 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10702 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10705 static void gen_addiur2(DisasContext
*ctx
)
10707 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10708 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10709 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10711 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10714 static void gen_addiusp(DisasContext
*ctx
)
10716 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10719 if (encoded
<= 1) {
10720 decoded
= 256 + encoded
;
10721 } else if (encoded
<= 255) {
10723 } else if (encoded
<= 509) {
10724 decoded
= encoded
- 512;
10726 decoded
= encoded
- 768;
10729 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10732 static void gen_addius5(DisasContext
*ctx
)
10734 int imm
= SIMM(ctx
->opcode
, 1, 4);
10735 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10737 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10740 static void gen_andi16(DisasContext
*ctx
)
10742 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10743 31, 32, 63, 64, 255, 32768, 65535 };
10744 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10745 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10746 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10748 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10751 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10752 int base
, int16_t offset
)
10754 const char *opn
= "ldst_multiple";
10758 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10759 generate_exception(ctx
, EXCP_RI
);
10763 t0
= tcg_temp_new();
10765 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10767 t1
= tcg_const_tl(reglist
);
10768 t2
= tcg_const_i32(ctx
->mem_idx
);
10770 save_cpu_state(ctx
, 1);
10773 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10777 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10780 #ifdef TARGET_MIPS64
10782 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10786 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10792 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10795 tcg_temp_free_i32(t2
);
10799 static void gen_pool16c_insn(DisasContext
*ctx
)
10801 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10802 int rs
= mmreg(ctx
->opcode
& 0x7);
10805 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10810 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10816 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10822 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10828 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10835 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10836 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10838 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10847 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10848 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10850 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10857 int reg
= ctx
->opcode
& 0x1f;
10859 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10865 int reg
= ctx
->opcode
& 0x1f;
10867 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10868 /* Let normal delay slot handling in our caller take us
10869 to the branch target. */
10881 int reg
= ctx
->opcode
& 0x1f;
10883 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10888 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10892 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10895 generate_exception(ctx
, EXCP_BREAK
);
10898 /* XXX: not clear which exception should be raised
10899 * when in debug mode...
10901 check_insn(ctx
, ISA_MIPS32
);
10902 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10903 generate_exception(ctx
, EXCP_DBp
);
10905 generate_exception(ctx
, EXCP_DBp
);
10908 case JRADDIUSP
+ 0:
10909 case JRADDIUSP
+ 1:
10911 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10913 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10914 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10915 /* Let normal delay slot handling in our caller take us
10916 to the branch target. */
10920 generate_exception(ctx
, EXCP_RI
);
10925 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10927 TCGv t0
= tcg_temp_new();
10928 TCGv t1
= tcg_temp_new();
10930 gen_load_gpr(t0
, base
);
10933 gen_load_gpr(t1
, index
);
10934 tcg_gen_shli_tl(t1
, t1
, 2);
10935 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10938 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10939 gen_store_gpr(t1
, rd
);
10945 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10946 int base
, int16_t offset
)
10948 const char *opn
= "ldst_pair";
10951 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10952 generate_exception(ctx
, EXCP_RI
);
10956 t0
= tcg_temp_new();
10957 t1
= tcg_temp_new();
10959 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10964 generate_exception(ctx
, EXCP_RI
);
10967 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10968 gen_store_gpr(t1
, rd
);
10969 tcg_gen_movi_tl(t1
, 4);
10970 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10971 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10972 gen_store_gpr(t1
, rd
+1);
10976 gen_load_gpr(t1
, rd
);
10977 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
10978 tcg_gen_movi_tl(t1
, 4);
10979 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10980 gen_load_gpr(t1
, rd
+1);
10981 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
10984 #ifdef TARGET_MIPS64
10987 generate_exception(ctx
, EXCP_RI
);
10990 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
10991 gen_store_gpr(t1
, rd
);
10992 tcg_gen_movi_tl(t1
, 8);
10993 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10994 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
10995 gen_store_gpr(t1
, rd
+1);
10999 gen_load_gpr(t1
, rd
);
11000 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11001 tcg_gen_movi_tl(t1
, 8);
11002 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11003 gen_load_gpr(t1
, rd
+1);
11004 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11009 (void)opn
; /* avoid a compiler warning */
11010 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11015 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11017 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11018 int minor
= (ctx
->opcode
>> 12) & 0xf;
11019 uint32_t mips32_op
;
11021 switch (extension
) {
11023 mips32_op
= OPC_TEQ
;
11026 mips32_op
= OPC_TGE
;
11029 mips32_op
= OPC_TGEU
;
11032 mips32_op
= OPC_TLT
;
11035 mips32_op
= OPC_TLTU
;
11038 mips32_op
= OPC_TNE
;
11040 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11042 #ifndef CONFIG_USER_ONLY
11045 check_cp0_enabled(ctx
);
11047 /* Treat as NOP. */
11050 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11054 check_cp0_enabled(ctx
);
11056 TCGv t0
= tcg_temp_new();
11058 gen_load_gpr(t0
, rt
);
11059 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11067 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11070 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11073 mips32_op
= OPC_CLO
;
11076 mips32_op
= OPC_CLZ
;
11078 check_insn(ctx
, ISA_MIPS32
);
11079 gen_cl(ctx
, mips32_op
, rt
, rs
);
11082 gen_rdhwr(ctx
, rt
, rs
);
11085 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11088 mips32_op
= OPC_MULT
;
11091 mips32_op
= OPC_MULTU
;
11094 mips32_op
= OPC_DIV
;
11097 mips32_op
= OPC_DIVU
;
11100 check_insn(ctx
, ISA_MIPS32
);
11101 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11104 mips32_op
= OPC_MADD
;
11107 mips32_op
= OPC_MADDU
;
11110 mips32_op
= OPC_MSUB
;
11113 mips32_op
= OPC_MSUBU
;
11115 check_insn(ctx
, ISA_MIPS32
);
11116 gen_muldiv(ctx
, mips32_op
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11119 goto pool32axf_invalid
;
11130 generate_exception_err(ctx
, EXCP_CpU
, 2);
11133 goto pool32axf_invalid
;
11140 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11144 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11147 goto pool32axf_invalid
;
11153 check_cp0_enabled(ctx
);
11154 check_insn(ctx
, ISA_MIPS32R2
);
11155 gen_load_srsgpr(rt
, rs
);
11158 check_cp0_enabled(ctx
);
11159 check_insn(ctx
, ISA_MIPS32R2
);
11160 gen_store_srsgpr(rt
, rs
);
11163 goto pool32axf_invalid
;
11166 #ifndef CONFIG_USER_ONLY
11170 mips32_op
= OPC_TLBP
;
11173 mips32_op
= OPC_TLBR
;
11176 mips32_op
= OPC_TLBWI
;
11179 mips32_op
= OPC_TLBWR
;
11182 mips32_op
= OPC_WAIT
;
11185 mips32_op
= OPC_DERET
;
11188 mips32_op
= OPC_ERET
;
11190 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11193 goto pool32axf_invalid
;
11199 check_cp0_enabled(ctx
);
11201 TCGv t0
= tcg_temp_new();
11203 save_cpu_state(ctx
, 1);
11204 gen_helper_di(t0
, cpu_env
);
11205 gen_store_gpr(t0
, rs
);
11206 /* Stop translation as we may have switched the execution mode */
11207 ctx
->bstate
= BS_STOP
;
11212 check_cp0_enabled(ctx
);
11214 TCGv t0
= tcg_temp_new();
11216 save_cpu_state(ctx
, 1);
11217 gen_helper_ei(t0
, cpu_env
);
11218 gen_store_gpr(t0
, rs
);
11219 /* Stop translation as we may have switched the execution mode */
11220 ctx
->bstate
= BS_STOP
;
11225 goto pool32axf_invalid
;
11235 generate_exception(ctx
, EXCP_SYSCALL
);
11236 ctx
->bstate
= BS_STOP
;
11239 check_insn(ctx
, ISA_MIPS32
);
11240 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11241 generate_exception(ctx
, EXCP_DBp
);
11243 generate_exception(ctx
, EXCP_DBp
);
11247 goto pool32axf_invalid
;
11251 switch (minor
& 3) {
11253 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11256 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11259 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11262 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11265 goto pool32axf_invalid
;
11270 MIPS_INVAL("pool32axf");
11271 generate_exception(ctx
, EXCP_RI
);
11276 /* Values for microMIPS fmt field. Variable-width, depending on which
11277 formats the instruction supports. */
11296 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11298 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11299 uint32_t mips32_op
;
11301 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11302 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11303 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11305 switch (extension
) {
11306 case FLOAT_1BIT_FMT(CFC1
, 0):
11307 mips32_op
= OPC_CFC1
;
11309 case FLOAT_1BIT_FMT(CTC1
, 0):
11310 mips32_op
= OPC_CTC1
;
11312 case FLOAT_1BIT_FMT(MFC1
, 0):
11313 mips32_op
= OPC_MFC1
;
11315 case FLOAT_1BIT_FMT(MTC1
, 0):
11316 mips32_op
= OPC_MTC1
;
11318 case FLOAT_1BIT_FMT(MFHC1
, 0):
11319 mips32_op
= OPC_MFHC1
;
11321 case FLOAT_1BIT_FMT(MTHC1
, 0):
11322 mips32_op
= OPC_MTHC1
;
11324 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11327 /* Reciprocal square root */
11328 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11329 mips32_op
= OPC_RSQRT_S
;
11331 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11332 mips32_op
= OPC_RSQRT_D
;
11336 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11337 mips32_op
= OPC_SQRT_S
;
11339 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11340 mips32_op
= OPC_SQRT_D
;
11344 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11345 mips32_op
= OPC_RECIP_S
;
11347 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11348 mips32_op
= OPC_RECIP_D
;
11352 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11353 mips32_op
= OPC_FLOOR_L_S
;
11355 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11356 mips32_op
= OPC_FLOOR_L_D
;
11358 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11359 mips32_op
= OPC_FLOOR_W_S
;
11361 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11362 mips32_op
= OPC_FLOOR_W_D
;
11366 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11367 mips32_op
= OPC_CEIL_L_S
;
11369 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11370 mips32_op
= OPC_CEIL_L_D
;
11372 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11373 mips32_op
= OPC_CEIL_W_S
;
11375 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11376 mips32_op
= OPC_CEIL_W_D
;
11380 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11381 mips32_op
= OPC_TRUNC_L_S
;
11383 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11384 mips32_op
= OPC_TRUNC_L_D
;
11386 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11387 mips32_op
= OPC_TRUNC_W_S
;
11389 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11390 mips32_op
= OPC_TRUNC_W_D
;
11394 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11395 mips32_op
= OPC_ROUND_L_S
;
11397 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11398 mips32_op
= OPC_ROUND_L_D
;
11400 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11401 mips32_op
= OPC_ROUND_W_S
;
11403 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11404 mips32_op
= OPC_ROUND_W_D
;
11407 /* Integer to floating-point conversion */
11408 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11409 mips32_op
= OPC_CVT_L_S
;
11411 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11412 mips32_op
= OPC_CVT_L_D
;
11414 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11415 mips32_op
= OPC_CVT_W_S
;
11417 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11418 mips32_op
= OPC_CVT_W_D
;
11421 /* Paired-foo conversions */
11422 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11423 mips32_op
= OPC_CVT_S_PL
;
11425 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11426 mips32_op
= OPC_CVT_S_PU
;
11428 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11429 mips32_op
= OPC_CVT_PW_PS
;
11431 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11432 mips32_op
= OPC_CVT_PS_PW
;
11435 /* Floating-point moves */
11436 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11437 mips32_op
= OPC_MOV_S
;
11439 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11440 mips32_op
= OPC_MOV_D
;
11442 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11443 mips32_op
= OPC_MOV_PS
;
11446 /* Absolute value */
11447 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11448 mips32_op
= OPC_ABS_S
;
11450 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11451 mips32_op
= OPC_ABS_D
;
11453 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11454 mips32_op
= OPC_ABS_PS
;
11458 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11459 mips32_op
= OPC_NEG_S
;
11461 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11462 mips32_op
= OPC_NEG_D
;
11464 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11465 mips32_op
= OPC_NEG_PS
;
11468 /* Reciprocal square root step */
11469 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11470 mips32_op
= OPC_RSQRT1_S
;
11472 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11473 mips32_op
= OPC_RSQRT1_D
;
11475 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11476 mips32_op
= OPC_RSQRT1_PS
;
11479 /* Reciprocal step */
11480 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11481 mips32_op
= OPC_RECIP1_S
;
11483 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11484 mips32_op
= OPC_RECIP1_S
;
11486 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11487 mips32_op
= OPC_RECIP1_PS
;
11490 /* Conversions from double */
11491 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11492 mips32_op
= OPC_CVT_D_S
;
11494 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11495 mips32_op
= OPC_CVT_D_W
;
11497 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11498 mips32_op
= OPC_CVT_D_L
;
11501 /* Conversions from single */
11502 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11503 mips32_op
= OPC_CVT_S_D
;
11505 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11506 mips32_op
= OPC_CVT_S_W
;
11508 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11509 mips32_op
= OPC_CVT_S_L
;
11511 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11514 /* Conditional moves on floating-point codes */
11515 case COND_FLOAT_MOV(MOVT
, 0):
11516 case COND_FLOAT_MOV(MOVT
, 1):
11517 case COND_FLOAT_MOV(MOVT
, 2):
11518 case COND_FLOAT_MOV(MOVT
, 3):
11519 case COND_FLOAT_MOV(MOVT
, 4):
11520 case COND_FLOAT_MOV(MOVT
, 5):
11521 case COND_FLOAT_MOV(MOVT
, 6):
11522 case COND_FLOAT_MOV(MOVT
, 7):
11523 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11525 case COND_FLOAT_MOV(MOVF
, 0):
11526 case COND_FLOAT_MOV(MOVF
, 1):
11527 case COND_FLOAT_MOV(MOVF
, 2):
11528 case COND_FLOAT_MOV(MOVF
, 3):
11529 case COND_FLOAT_MOV(MOVF
, 4):
11530 case COND_FLOAT_MOV(MOVF
, 5):
11531 case COND_FLOAT_MOV(MOVF
, 6):
11532 case COND_FLOAT_MOV(MOVF
, 7):
11533 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11536 MIPS_INVAL("pool32fxf");
11537 generate_exception(ctx
, EXCP_RI
);
11542 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11547 int rt
, rs
, rd
, rr
;
11549 uint32_t op
, minor
, mips32_op
;
11550 uint32_t cond
, fmt
, cc
;
11552 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11553 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11555 rt
= (ctx
->opcode
>> 21) & 0x1f;
11556 rs
= (ctx
->opcode
>> 16) & 0x1f;
11557 rd
= (ctx
->opcode
>> 11) & 0x1f;
11558 rr
= (ctx
->opcode
>> 6) & 0x1f;
11559 imm
= (int16_t) ctx
->opcode
;
11561 op
= (ctx
->opcode
>> 26) & 0x3f;
11564 minor
= ctx
->opcode
& 0x3f;
11567 minor
= (ctx
->opcode
>> 6) & 0xf;
11570 mips32_op
= OPC_SLL
;
11573 mips32_op
= OPC_SRA
;
11576 mips32_op
= OPC_SRL
;
11579 mips32_op
= OPC_ROTR
;
11581 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11584 goto pool32a_invalid
;
11588 minor
= (ctx
->opcode
>> 6) & 0xf;
11592 mips32_op
= OPC_ADD
;
11595 mips32_op
= OPC_ADDU
;
11598 mips32_op
= OPC_SUB
;
11601 mips32_op
= OPC_SUBU
;
11604 mips32_op
= OPC_MUL
;
11606 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11610 mips32_op
= OPC_SLLV
;
11613 mips32_op
= OPC_SRLV
;
11616 mips32_op
= OPC_SRAV
;
11619 mips32_op
= OPC_ROTRV
;
11621 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11623 /* Logical operations */
11625 mips32_op
= OPC_AND
;
11628 mips32_op
= OPC_OR
;
11631 mips32_op
= OPC_NOR
;
11634 mips32_op
= OPC_XOR
;
11636 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11638 /* Set less than */
11640 mips32_op
= OPC_SLT
;
11643 mips32_op
= OPC_SLTU
;
11645 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11648 goto pool32a_invalid
;
11652 minor
= (ctx
->opcode
>> 6) & 0xf;
11654 /* Conditional moves */
11656 mips32_op
= OPC_MOVN
;
11659 mips32_op
= OPC_MOVZ
;
11661 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11664 gen_ldxs(ctx
, rs
, rt
, rd
);
11667 goto pool32a_invalid
;
11671 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11674 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11677 gen_pool32axf(env
, ctx
, rt
, rs
);
11680 generate_exception(ctx
, EXCP_BREAK
);
11684 MIPS_INVAL("pool32a");
11685 generate_exception(ctx
, EXCP_RI
);
11690 minor
= (ctx
->opcode
>> 12) & 0xf;
11693 check_cp0_enabled(ctx
);
11694 /* Treat as no-op. */
11698 /* COP2: Not implemented. */
11699 generate_exception_err(ctx
, EXCP_CpU
, 2);
11703 #ifdef TARGET_MIPS64
11707 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11711 #ifdef TARGET_MIPS64
11715 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11718 MIPS_INVAL("pool32b");
11719 generate_exception(ctx
, EXCP_RI
);
11724 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11725 minor
= ctx
->opcode
& 0x3f;
11726 check_cp1_enabled(ctx
);
11729 mips32_op
= OPC_ALNV_PS
;
11732 mips32_op
= OPC_MADD_S
;
11735 mips32_op
= OPC_MADD_D
;
11738 mips32_op
= OPC_MADD_PS
;
11741 mips32_op
= OPC_MSUB_S
;
11744 mips32_op
= OPC_MSUB_D
;
11747 mips32_op
= OPC_MSUB_PS
;
11750 mips32_op
= OPC_NMADD_S
;
11753 mips32_op
= OPC_NMADD_D
;
11756 mips32_op
= OPC_NMADD_PS
;
11759 mips32_op
= OPC_NMSUB_S
;
11762 mips32_op
= OPC_NMSUB_D
;
11765 mips32_op
= OPC_NMSUB_PS
;
11767 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11769 case CABS_COND_FMT
:
11770 cond
= (ctx
->opcode
>> 6) & 0xf;
11771 cc
= (ctx
->opcode
>> 13) & 0x7;
11772 fmt
= (ctx
->opcode
>> 10) & 0x3;
11775 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11778 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11781 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11784 goto pool32f_invalid
;
11788 cond
= (ctx
->opcode
>> 6) & 0xf;
11789 cc
= (ctx
->opcode
>> 13) & 0x7;
11790 fmt
= (ctx
->opcode
>> 10) & 0x3;
11793 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11796 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11799 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11802 goto pool32f_invalid
;
11806 gen_pool32fxf(ctx
, rt
, rs
);
11810 switch ((ctx
->opcode
>> 6) & 0x7) {
11812 mips32_op
= OPC_PLL_PS
;
11815 mips32_op
= OPC_PLU_PS
;
11818 mips32_op
= OPC_PUL_PS
;
11821 mips32_op
= OPC_PUU_PS
;
11824 mips32_op
= OPC_CVT_PS_S
;
11826 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11829 goto pool32f_invalid
;
11834 switch ((ctx
->opcode
>> 6) & 0x7) {
11836 mips32_op
= OPC_LWXC1
;
11839 mips32_op
= OPC_SWXC1
;
11842 mips32_op
= OPC_LDXC1
;
11845 mips32_op
= OPC_SDXC1
;
11848 mips32_op
= OPC_LUXC1
;
11851 mips32_op
= OPC_SUXC1
;
11853 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11856 goto pool32f_invalid
;
11861 fmt
= (ctx
->opcode
>> 9) & 0x3;
11862 switch ((ctx
->opcode
>> 6) & 0x7) {
11866 mips32_op
= OPC_RSQRT2_S
;
11869 mips32_op
= OPC_RSQRT2_D
;
11872 mips32_op
= OPC_RSQRT2_PS
;
11875 goto pool32f_invalid
;
11881 mips32_op
= OPC_RECIP2_S
;
11884 mips32_op
= OPC_RECIP2_D
;
11887 mips32_op
= OPC_RECIP2_PS
;
11890 goto pool32f_invalid
;
11894 mips32_op
= OPC_ADDR_PS
;
11897 mips32_op
= OPC_MULR_PS
;
11899 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11902 goto pool32f_invalid
;
11906 /* MOV[FT].fmt and PREFX */
11907 cc
= (ctx
->opcode
>> 13) & 0x7;
11908 fmt
= (ctx
->opcode
>> 9) & 0x3;
11909 switch ((ctx
->opcode
>> 6) & 0x7) {
11913 gen_movcf_s(rs
, rt
, cc
, 0);
11916 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11919 gen_movcf_ps(rs
, rt
, cc
, 0);
11922 goto pool32f_invalid
;
11928 gen_movcf_s(rs
, rt
, cc
, 1);
11931 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11934 gen_movcf_ps(rs
, rt
, cc
, 1);
11937 goto pool32f_invalid
;
11943 goto pool32f_invalid
;
11946 #define FINSN_3ARG_SDPS(prfx) \
11947 switch ((ctx->opcode >> 8) & 0x3) { \
11949 mips32_op = OPC_##prfx##_S; \
11952 mips32_op = OPC_##prfx##_D; \
11954 case FMT_SDPS_PS: \
11955 mips32_op = OPC_##prfx##_PS; \
11958 goto pool32f_invalid; \
11961 /* regular FP ops */
11962 switch ((ctx
->opcode
>> 6) & 0x3) {
11964 FINSN_3ARG_SDPS(ADD
);
11967 FINSN_3ARG_SDPS(SUB
);
11970 FINSN_3ARG_SDPS(MUL
);
11973 fmt
= (ctx
->opcode
>> 8) & 0x3;
11975 mips32_op
= OPC_DIV_D
;
11976 } else if (fmt
== 0) {
11977 mips32_op
= OPC_DIV_S
;
11979 goto pool32f_invalid
;
11983 goto pool32f_invalid
;
11988 switch ((ctx
->opcode
>> 6) & 0x3) {
11990 FINSN_3ARG_SDPS(MOVN
);
11993 FINSN_3ARG_SDPS(MOVZ
);
11996 goto pool32f_invalid
;
12000 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12004 MIPS_INVAL("pool32f");
12005 generate_exception(ctx
, EXCP_RI
);
12009 generate_exception_err(ctx
, EXCP_CpU
, 1);
12013 minor
= (ctx
->opcode
>> 21) & 0x1f;
12016 mips32_op
= OPC_BLTZ
;
12019 mips32_op
= OPC_BLTZAL
;
12022 mips32_op
= OPC_BLTZALS
;
12025 mips32_op
= OPC_BGEZ
;
12028 mips32_op
= OPC_BGEZAL
;
12031 mips32_op
= OPC_BGEZALS
;
12034 mips32_op
= OPC_BLEZ
;
12037 mips32_op
= OPC_BGTZ
;
12039 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12044 mips32_op
= OPC_TLTI
;
12047 mips32_op
= OPC_TGEI
;
12050 mips32_op
= OPC_TLTIU
;
12053 mips32_op
= OPC_TGEIU
;
12056 mips32_op
= OPC_TNEI
;
12059 mips32_op
= OPC_TEQI
;
12061 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12066 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12067 4, rs
, 0, imm
<< 1);
12068 /* Compact branches don't have a delay slot, so just let
12069 the normal delay slot handling take us to the branch
12073 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12079 /* COP2: Not implemented. */
12080 generate_exception_err(ctx
, EXCP_CpU
, 2);
12083 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12086 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12089 mips32_op
= OPC_BC1FANY4
;
12092 mips32_op
= OPC_BC1TANY4
;
12095 check_insn(ctx
, ASE_MIPS3D
);
12098 gen_compute_branch1(ctx
, mips32_op
,
12099 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12103 /* MIPS DSP: not implemented */
12106 MIPS_INVAL("pool32i");
12107 generate_exception(ctx
, EXCP_RI
);
12112 minor
= (ctx
->opcode
>> 12) & 0xf;
12115 mips32_op
= OPC_LWL
;
12118 mips32_op
= OPC_SWL
;
12121 mips32_op
= OPC_LWR
;
12124 mips32_op
= OPC_SWR
;
12126 #if defined(TARGET_MIPS64)
12128 mips32_op
= OPC_LDL
;
12131 mips32_op
= OPC_SDL
;
12134 mips32_op
= OPC_LDR
;
12137 mips32_op
= OPC_SDR
;
12140 mips32_op
= OPC_LWU
;
12143 mips32_op
= OPC_LLD
;
12147 mips32_op
= OPC_LL
;
12150 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12153 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12156 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12158 #if defined(TARGET_MIPS64)
12160 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12164 /* Treat as no-op */
12167 MIPS_INVAL("pool32c");
12168 generate_exception(ctx
, EXCP_RI
);
12173 mips32_op
= OPC_ADDI
;
12176 mips32_op
= OPC_ADDIU
;
12178 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12181 /* Logical operations */
12183 mips32_op
= OPC_ORI
;
12186 mips32_op
= OPC_XORI
;
12189 mips32_op
= OPC_ANDI
;
12191 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12194 /* Set less than immediate */
12196 mips32_op
= OPC_SLTI
;
12199 mips32_op
= OPC_SLTIU
;
12201 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12204 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12205 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12208 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12209 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12212 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12215 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12218 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12219 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12222 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12223 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12225 /* Floating point (COP1) */
12227 mips32_op
= OPC_LWC1
;
12230 mips32_op
= OPC_LDC1
;
12233 mips32_op
= OPC_SWC1
;
12236 mips32_op
= OPC_SDC1
;
12238 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12242 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12243 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12245 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12248 /* Loads and stores */
12250 mips32_op
= OPC_LB
;
12253 mips32_op
= OPC_LBU
;
12256 mips32_op
= OPC_LH
;
12259 mips32_op
= OPC_LHU
;
12262 mips32_op
= OPC_LW
;
12264 #ifdef TARGET_MIPS64
12266 mips32_op
= OPC_LD
;
12269 mips32_op
= OPC_SD
;
12273 mips32_op
= OPC_SB
;
12276 mips32_op
= OPC_SH
;
12279 mips32_op
= OPC_SW
;
12282 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12285 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12288 generate_exception(ctx
, EXCP_RI
);
12293 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12297 /* make sure instructions are on a halfword boundary */
12298 if (ctx
->pc
& 0x1) {
12299 env
->CP0_BadVAddr
= ctx
->pc
;
12300 generate_exception(ctx
, EXCP_AdEL
);
12301 ctx
->bstate
= BS_STOP
;
12305 op
= (ctx
->opcode
>> 10) & 0x3f;
12306 /* Enforce properly-sized instructions in a delay slot */
12307 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12308 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12346 if (bits
& MIPS_HFLAG_BDS16
) {
12347 generate_exception(ctx
, EXCP_RI
);
12348 /* Just stop translation; the user is confused. */
12349 ctx
->bstate
= BS_STOP
;
12374 if (bits
& MIPS_HFLAG_BDS32
) {
12375 generate_exception(ctx
, EXCP_RI
);
12376 /* Just stop translation; the user is confused. */
12377 ctx
->bstate
= BS_STOP
;
12388 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12389 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12390 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12393 switch (ctx
->opcode
& 0x1) {
12402 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12407 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12408 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12409 int amount
= (ctx
->opcode
>> 1) & 0x7;
12411 amount
= amount
== 0 ? 8 : amount
;
12413 switch (ctx
->opcode
& 0x1) {
12422 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12426 gen_pool16c_insn(ctx
);
12430 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12431 int rb
= 28; /* GP */
12432 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12434 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12438 if (ctx
->opcode
& 1) {
12439 generate_exception(ctx
, EXCP_RI
);
12442 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12443 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12444 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12445 int rd
, rs
, re
, rt
;
12446 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12447 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12448 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12450 rd
= rd_enc
[enc_dest
];
12451 re
= re_enc
[enc_dest
];
12452 rs
= rs_rt_enc
[enc_rs
];
12453 rt
= rs_rt_enc
[enc_rt
];
12455 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12456 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12461 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12462 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12463 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12464 offset
= (offset
== 0xf ? -1 : offset
);
12466 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12471 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12472 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12473 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12475 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12480 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12481 int rb
= 29; /* SP */
12482 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12484 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12489 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12490 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12491 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12493 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12498 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12499 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12500 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12502 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12507 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12508 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12509 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12511 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12516 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12517 int rb
= 29; /* SP */
12518 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12520 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12525 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12526 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12527 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12529 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12534 int rd
= uMIPS_RD5(ctx
->opcode
);
12535 int rs
= uMIPS_RS5(ctx
->opcode
);
12537 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12544 switch (ctx
->opcode
& 0x1) {
12554 switch (ctx
->opcode
& 0x1) {
12559 gen_addiur1sp(ctx
);
12564 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12565 SIMM(ctx
->opcode
, 0, 10) << 1);
12569 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12570 mmreg(uMIPS_RD(ctx
->opcode
)),
12571 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12575 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12576 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12578 imm
= (imm
== 0x7f ? -1 : imm
);
12579 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12589 generate_exception(ctx
, EXCP_RI
);
12592 decode_micromips32_opc (env
, ctx
, op
);
12599 /* SmartMIPS extension to MIPS32 */
12601 #if defined(TARGET_MIPS64)
12603 /* MDMX extension to MIPS64 */
12607 /* MIPSDSP functions. */
12608 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12609 int rd
, int base
, int offset
)
12611 const char *opn
= "ldx";
12615 t0
= tcg_temp_new();
12618 gen_load_gpr(t0
, offset
);
12619 } else if (offset
== 0) {
12620 gen_load_gpr(t0
, base
);
12622 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12627 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
12628 gen_store_gpr(t0
, rd
);
12632 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
12633 gen_store_gpr(t0
, rd
);
12637 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
12638 gen_store_gpr(t0
, rd
);
12641 #if defined(TARGET_MIPS64)
12643 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
12644 gen_store_gpr(t0
, rd
);
12649 (void)opn
; /* avoid a compiler warning */
12650 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12651 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12655 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12656 int ret
, int v1
, int v2
)
12658 const char *opn
= "mipsdsp arith";
12663 /* Treat as NOP. */
12668 v1_t
= tcg_temp_new();
12669 v2_t
= tcg_temp_new();
12671 gen_load_gpr(v1_t
, v1
);
12672 gen_load_gpr(v2_t
, v2
);
12675 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12676 case OPC_MULT_G_2E
:
12680 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12682 case OPC_ADDUH_R_QB
:
12683 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12686 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12688 case OPC_ADDQH_R_PH
:
12689 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12692 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12694 case OPC_ADDQH_R_W
:
12695 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12698 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12700 case OPC_SUBUH_R_QB
:
12701 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12704 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12706 case OPC_SUBQH_R_PH
:
12707 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12710 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12712 case OPC_SUBQH_R_W
:
12713 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12717 case OPC_ABSQ_S_PH_DSP
:
12719 case OPC_ABSQ_S_QB
:
12721 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12723 case OPC_ABSQ_S_PH
:
12725 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12729 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12731 case OPC_PRECEQ_W_PHL
:
12733 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12734 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12736 case OPC_PRECEQ_W_PHR
:
12738 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12739 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12740 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12742 case OPC_PRECEQU_PH_QBL
:
12744 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12746 case OPC_PRECEQU_PH_QBR
:
12748 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12750 case OPC_PRECEQU_PH_QBLA
:
12752 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12754 case OPC_PRECEQU_PH_QBRA
:
12756 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12758 case OPC_PRECEU_PH_QBL
:
12760 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12762 case OPC_PRECEU_PH_QBR
:
12764 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12766 case OPC_PRECEU_PH_QBLA
:
12768 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12770 case OPC_PRECEU_PH_QBRA
:
12772 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12776 case OPC_ADDU_QB_DSP
:
12780 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12782 case OPC_ADDQ_S_PH
:
12784 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12788 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12792 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12794 case OPC_ADDU_S_QB
:
12796 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12800 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12802 case OPC_ADDU_S_PH
:
12804 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12808 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12810 case OPC_SUBQ_S_PH
:
12812 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12816 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12820 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12822 case OPC_SUBU_S_QB
:
12824 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12828 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12830 case OPC_SUBU_S_PH
:
12832 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12836 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12840 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12844 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12846 case OPC_RADDU_W_QB
:
12848 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12852 case OPC_CMPU_EQ_QB_DSP
:
12854 case OPC_PRECR_QB_PH
:
12856 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12858 case OPC_PRECRQ_QB_PH
:
12860 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12862 case OPC_PRECR_SRA_PH_W
:
12865 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12866 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12868 tcg_temp_free_i32(sa_t
);
12871 case OPC_PRECR_SRA_R_PH_W
:
12874 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12875 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12877 tcg_temp_free_i32(sa_t
);
12880 case OPC_PRECRQ_PH_W
:
12882 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12884 case OPC_PRECRQ_RS_PH_W
:
12886 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12888 case OPC_PRECRQU_S_QB_PH
:
12890 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12894 #ifdef TARGET_MIPS64
12895 case OPC_ABSQ_S_QH_DSP
:
12897 case OPC_PRECEQ_L_PWL
:
12899 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12901 case OPC_PRECEQ_L_PWR
:
12903 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12905 case OPC_PRECEQ_PW_QHL
:
12907 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12909 case OPC_PRECEQ_PW_QHR
:
12911 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12913 case OPC_PRECEQ_PW_QHLA
:
12915 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12917 case OPC_PRECEQ_PW_QHRA
:
12919 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12921 case OPC_PRECEQU_QH_OBL
:
12923 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12925 case OPC_PRECEQU_QH_OBR
:
12927 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12929 case OPC_PRECEQU_QH_OBLA
:
12931 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12933 case OPC_PRECEQU_QH_OBRA
:
12935 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12937 case OPC_PRECEU_QH_OBL
:
12939 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12941 case OPC_PRECEU_QH_OBR
:
12943 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
12945 case OPC_PRECEU_QH_OBLA
:
12947 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
12949 case OPC_PRECEU_QH_OBRA
:
12951 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
12953 case OPC_ABSQ_S_OB
:
12955 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
12957 case OPC_ABSQ_S_PW
:
12959 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
12961 case OPC_ABSQ_S_QH
:
12963 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
12967 case OPC_ADDU_OB_DSP
:
12969 case OPC_RADDU_L_OB
:
12971 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
12975 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12977 case OPC_SUBQ_S_PW
:
12979 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12983 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12985 case OPC_SUBQ_S_QH
:
12987 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12991 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12993 case OPC_SUBU_S_OB
:
12995 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12999 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13001 case OPC_SUBU_S_QH
:
13003 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13007 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13009 case OPC_SUBUH_R_OB
:
13011 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13015 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13017 case OPC_ADDQ_S_PW
:
13019 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13023 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13025 case OPC_ADDQ_S_QH
:
13027 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13031 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13033 case OPC_ADDU_S_OB
:
13035 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13039 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13041 case OPC_ADDU_S_QH
:
13043 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13047 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13049 case OPC_ADDUH_R_OB
:
13051 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13055 case OPC_CMPU_EQ_OB_DSP
:
13057 case OPC_PRECR_OB_QH
:
13059 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13061 case OPC_PRECR_SRA_QH_PW
:
13064 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13065 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13066 tcg_temp_free_i32(ret_t
);
13069 case OPC_PRECR_SRA_R_QH_PW
:
13072 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13073 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13074 tcg_temp_free_i32(sa_v
);
13077 case OPC_PRECRQ_OB_QH
:
13079 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13081 case OPC_PRECRQ_PW_L
:
13083 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13085 case OPC_PRECRQ_QH_PW
:
13087 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13089 case OPC_PRECRQ_RS_QH_PW
:
13091 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13093 case OPC_PRECRQU_S_OB_QH
:
13095 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13102 tcg_temp_free(v1_t
);
13103 tcg_temp_free(v2_t
);
13105 (void)opn
; /* avoid a compiler warning */
13106 MIPS_DEBUG("%s", opn
);
13109 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13110 int ret
, int v1
, int v2
)
13113 const char *opn
= "mipsdsp shift";
13119 /* Treat as NOP. */
13124 t0
= tcg_temp_new();
13125 v1_t
= tcg_temp_new();
13126 v2_t
= tcg_temp_new();
13128 tcg_gen_movi_tl(t0
, v1
);
13129 gen_load_gpr(v1_t
, v1
);
13130 gen_load_gpr(v2_t
, v2
);
13133 case OPC_SHLL_QB_DSP
:
13135 op2
= MASK_SHLL_QB(ctx
->opcode
);
13139 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13143 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13147 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13151 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13153 case OPC_SHLL_S_PH
:
13155 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13157 case OPC_SHLLV_S_PH
:
13159 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13163 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13165 case OPC_SHLLV_S_W
:
13167 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13171 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13175 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13179 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13183 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13187 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13189 case OPC_SHRA_R_QB
:
13191 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13195 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13197 case OPC_SHRAV_R_QB
:
13199 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13203 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13205 case OPC_SHRA_R_PH
:
13207 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13211 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13213 case OPC_SHRAV_R_PH
:
13215 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13219 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13221 case OPC_SHRAV_R_W
:
13223 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13225 default: /* Invalid */
13226 MIPS_INVAL("MASK SHLL.QB");
13227 generate_exception(ctx
, EXCP_RI
);
13232 #ifdef TARGET_MIPS64
13233 case OPC_SHLL_OB_DSP
:
13234 op2
= MASK_SHLL_OB(ctx
->opcode
);
13238 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13242 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13244 case OPC_SHLL_S_PW
:
13246 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13248 case OPC_SHLLV_S_PW
:
13250 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13254 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13258 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13262 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13266 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13268 case OPC_SHLL_S_QH
:
13270 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13272 case OPC_SHLLV_S_QH
:
13274 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13278 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13282 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13284 case OPC_SHRA_R_OB
:
13286 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13288 case OPC_SHRAV_R_OB
:
13290 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13294 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13298 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13300 case OPC_SHRA_R_PW
:
13302 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13304 case OPC_SHRAV_R_PW
:
13306 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13310 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13314 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13316 case OPC_SHRA_R_QH
:
13318 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13320 case OPC_SHRAV_R_QH
:
13322 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13326 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13330 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13334 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13338 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13340 default: /* Invalid */
13341 MIPS_INVAL("MASK SHLL.OB");
13342 generate_exception(ctx
, EXCP_RI
);
13350 tcg_temp_free(v1_t
);
13351 tcg_temp_free(v2_t
);
13352 (void)opn
; /* avoid a compiler warning */
13353 MIPS_DEBUG("%s", opn
);
13356 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13357 int ret
, int v1
, int v2
, int check_ret
)
13359 const char *opn
= "mipsdsp multiply";
13364 if ((ret
== 0) && (check_ret
== 1)) {
13365 /* Treat as NOP. */
13370 t0
= tcg_temp_new_i32();
13371 v1_t
= tcg_temp_new();
13372 v2_t
= tcg_temp_new();
13374 tcg_gen_movi_i32(t0
, ret
);
13375 gen_load_gpr(v1_t
, v1
);
13376 gen_load_gpr(v2_t
, v2
);
13379 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13380 * the same mask and op1. */
13381 case OPC_MULT_G_2E
:
13385 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13388 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13391 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13393 case OPC_MULQ_RS_W
:
13394 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13398 case OPC_DPA_W_PH_DSP
:
13400 case OPC_DPAU_H_QBL
:
13402 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13404 case OPC_DPAU_H_QBR
:
13406 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13408 case OPC_DPSU_H_QBL
:
13410 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13412 case OPC_DPSU_H_QBR
:
13414 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13418 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13420 case OPC_DPAX_W_PH
:
13422 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13424 case OPC_DPAQ_S_W_PH
:
13426 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13428 case OPC_DPAQX_S_W_PH
:
13430 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13432 case OPC_DPAQX_SA_W_PH
:
13434 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13438 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13440 case OPC_DPSX_W_PH
:
13442 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13444 case OPC_DPSQ_S_W_PH
:
13446 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13448 case OPC_DPSQX_S_W_PH
:
13450 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13452 case OPC_DPSQX_SA_W_PH
:
13454 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13456 case OPC_MULSAQ_S_W_PH
:
13458 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13460 case OPC_DPAQ_SA_L_W
:
13462 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13464 case OPC_DPSQ_SA_L_W
:
13466 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13468 case OPC_MAQ_S_W_PHL
:
13470 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13472 case OPC_MAQ_S_W_PHR
:
13474 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13476 case OPC_MAQ_SA_W_PHL
:
13478 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13480 case OPC_MAQ_SA_W_PHR
:
13482 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13484 case OPC_MULSA_W_PH
:
13486 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13490 #ifdef TARGET_MIPS64
13491 case OPC_DPAQ_W_QH_DSP
:
13493 int ac
= ret
& 0x03;
13494 tcg_gen_movi_i32(t0
, ac
);
13499 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13503 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13507 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13511 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13515 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13517 case OPC_DPAQ_S_W_QH
:
13519 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13521 case OPC_DPAQ_SA_L_PW
:
13523 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13525 case OPC_DPAU_H_OBL
:
13527 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13529 case OPC_DPAU_H_OBR
:
13531 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13535 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13537 case OPC_DPSQ_S_W_QH
:
13539 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13541 case OPC_DPSQ_SA_L_PW
:
13543 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13545 case OPC_DPSU_H_OBL
:
13547 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13549 case OPC_DPSU_H_OBR
:
13551 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13553 case OPC_MAQ_S_L_PWL
:
13555 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13557 case OPC_MAQ_S_L_PWR
:
13559 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13561 case OPC_MAQ_S_W_QHLL
:
13563 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13565 case OPC_MAQ_SA_W_QHLL
:
13567 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13569 case OPC_MAQ_S_W_QHLR
:
13571 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13573 case OPC_MAQ_SA_W_QHLR
:
13575 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13577 case OPC_MAQ_S_W_QHRL
:
13579 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13581 case OPC_MAQ_SA_W_QHRL
:
13583 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13585 case OPC_MAQ_S_W_QHRR
:
13587 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13589 case OPC_MAQ_SA_W_QHRR
:
13591 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13593 case OPC_MULSAQ_S_L_PW
:
13595 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13597 case OPC_MULSAQ_S_W_QH
:
13599 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13605 case OPC_ADDU_QB_DSP
:
13607 case OPC_MULEU_S_PH_QBL
:
13609 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13611 case OPC_MULEU_S_PH_QBR
:
13613 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13615 case OPC_MULQ_RS_PH
:
13617 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13619 case OPC_MULEQ_S_W_PHL
:
13621 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13623 case OPC_MULEQ_S_W_PHR
:
13625 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13627 case OPC_MULQ_S_PH
:
13629 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13633 #ifdef TARGET_MIPS64
13634 case OPC_ADDU_OB_DSP
:
13636 case OPC_MULEQ_S_PW_QHL
:
13638 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13640 case OPC_MULEQ_S_PW_QHR
:
13642 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13644 case OPC_MULEU_S_QH_OBL
:
13646 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13648 case OPC_MULEU_S_QH_OBR
:
13650 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13652 case OPC_MULQ_RS_QH
:
13654 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13661 tcg_temp_free_i32(t0
);
13662 tcg_temp_free(v1_t
);
13663 tcg_temp_free(v2_t
);
13665 (void)opn
; /* avoid a compiler warning */
13666 MIPS_DEBUG("%s", opn
);
13670 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13673 const char *opn
= "mipsdsp Bit/ Manipulation";
13679 /* Treat as NOP. */
13684 t0
= tcg_temp_new();
13685 val_t
= tcg_temp_new();
13686 gen_load_gpr(val_t
, val
);
13689 case OPC_ABSQ_S_PH_DSP
:
13693 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13698 target_long result
;
13699 imm
= (ctx
->opcode
>> 16) & 0xFF;
13700 result
= (uint32_t)imm
<< 24 |
13701 (uint32_t)imm
<< 16 |
13702 (uint32_t)imm
<< 8 |
13704 result
= (int32_t)result
;
13705 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13710 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13711 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13712 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13713 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13714 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13715 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13720 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13721 imm
= (int16_t)(imm
<< 6) >> 6;
13722 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13723 (target_long
)((int32_t)imm
<< 16 | \
13729 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13730 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13731 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13732 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13736 #ifdef TARGET_MIPS64
13737 case OPC_ABSQ_S_QH_DSP
:
13744 imm
= (ctx
->opcode
>> 16) & 0xFF;
13745 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13746 temp
= (temp
<< 16) | temp
;
13747 temp
= (temp
<< 32) | temp
;
13748 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13756 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13757 imm
= (int16_t)(imm
<< 6) >> 6;
13758 temp
= ((target_long
)imm
<< 32) \
13759 | ((target_long
)imm
& 0xFFFFFFFF);
13760 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13768 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13769 imm
= (int16_t)(imm
<< 6) >> 6;
13771 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13772 ((uint64_t)(uint16_t)imm
<< 32) |
13773 ((uint64_t)(uint16_t)imm
<< 16) |
13774 (uint64_t)(uint16_t)imm
;
13775 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13780 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13781 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13782 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13783 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13784 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13785 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13786 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13790 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13791 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13792 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13796 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13797 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13798 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13799 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13800 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13807 tcg_temp_free(val_t
);
13809 (void)opn
; /* avoid a compiler warning */
13810 MIPS_DEBUG("%s", opn
);
13813 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13814 uint32_t op1
, uint32_t op2
,
13815 int ret
, int v1
, int v2
, int check_ret
)
13817 const char *opn
= "mipsdsp add compare pick";
13822 if ((ret
== 0) && (check_ret
== 1)) {
13823 /* Treat as NOP. */
13828 t1
= tcg_temp_new();
13829 v1_t
= tcg_temp_new();
13830 v2_t
= tcg_temp_new();
13832 gen_load_gpr(v1_t
, v1
);
13833 gen_load_gpr(v2_t
, v2
);
13836 case OPC_CMPU_EQ_QB_DSP
:
13838 case OPC_CMPU_EQ_QB
:
13840 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13842 case OPC_CMPU_LT_QB
:
13844 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13846 case OPC_CMPU_LE_QB
:
13848 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13850 case OPC_CMPGU_EQ_QB
:
13852 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13854 case OPC_CMPGU_LT_QB
:
13856 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13858 case OPC_CMPGU_LE_QB
:
13860 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13862 case OPC_CMPGDU_EQ_QB
:
13864 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13865 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13866 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13867 tcg_gen_shli_tl(t1
, t1
, 24);
13868 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13870 case OPC_CMPGDU_LT_QB
:
13872 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13873 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13874 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13875 tcg_gen_shli_tl(t1
, t1
, 24);
13876 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13878 case OPC_CMPGDU_LE_QB
:
13880 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13881 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13882 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13883 tcg_gen_shli_tl(t1
, t1
, 24);
13884 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13886 case OPC_CMP_EQ_PH
:
13888 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13890 case OPC_CMP_LT_PH
:
13892 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13894 case OPC_CMP_LE_PH
:
13896 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13900 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13904 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13906 case OPC_PACKRL_PH
:
13908 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13912 #ifdef TARGET_MIPS64
13913 case OPC_CMPU_EQ_OB_DSP
:
13915 case OPC_CMP_EQ_PW
:
13917 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13919 case OPC_CMP_LT_PW
:
13921 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13923 case OPC_CMP_LE_PW
:
13925 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13927 case OPC_CMP_EQ_QH
:
13929 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13931 case OPC_CMP_LT_QH
:
13933 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13935 case OPC_CMP_LE_QH
:
13937 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13939 case OPC_CMPGDU_EQ_OB
:
13941 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13943 case OPC_CMPGDU_LT_OB
:
13945 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13947 case OPC_CMPGDU_LE_OB
:
13949 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13951 case OPC_CMPGU_EQ_OB
:
13953 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13955 case OPC_CMPGU_LT_OB
:
13957 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13959 case OPC_CMPGU_LE_OB
:
13961 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13963 case OPC_CMPU_EQ_OB
:
13965 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
13967 case OPC_CMPU_LT_OB
:
13969 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
13971 case OPC_CMPU_LE_OB
:
13973 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
13975 case OPC_PACKRL_PW
:
13977 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13981 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13985 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13989 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13997 tcg_temp_free(v1_t
);
13998 tcg_temp_free(v2_t
);
14000 (void)opn
; /* avoid a compiler warning */
14001 MIPS_DEBUG("%s", opn
);
14004 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14005 uint32_t op1
, int rt
, int rs
, int sa
)
14007 const char *opn
= "mipsdsp append/dappend";
14013 /* Treat as NOP. */
14018 t0
= tcg_temp_new();
14019 gen_load_gpr(t0
, rs
);
14022 case OPC_APPEND_DSP
:
14023 switch (MASK_APPEND(ctx
->opcode
)) {
14026 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14028 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14032 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14033 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14034 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14035 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14037 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14041 if (sa
!= 0 && sa
!= 2) {
14042 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14043 tcg_gen_ext32u_tl(t0
, t0
);
14044 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14045 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14047 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14049 default: /* Invalid */
14050 MIPS_INVAL("MASK APPEND");
14051 generate_exception(ctx
, EXCP_RI
);
14055 #ifdef TARGET_MIPS64
14056 case OPC_DAPPEND_DSP
:
14057 switch (MASK_DAPPEND(ctx
->opcode
)) {
14060 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14064 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14065 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14066 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14070 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14071 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14072 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14077 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14078 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14079 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14080 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14083 default: /* Invalid */
14084 MIPS_INVAL("MASK DAPPEND");
14085 generate_exception(ctx
, EXCP_RI
);
14092 (void)opn
; /* avoid a compiler warning */
14093 MIPS_DEBUG("%s", opn
);
14096 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14097 int ret
, int v1
, int v2
, int check_ret
)
14100 const char *opn
= "mipsdsp accumulator";
14107 if ((ret
== 0) && (check_ret
== 1)) {
14108 /* Treat as NOP. */
14113 t0
= tcg_temp_new();
14114 t1
= tcg_temp_new();
14115 v1_t
= tcg_temp_new();
14116 v2_t
= tcg_temp_new();
14118 gen_load_gpr(v1_t
, v1
);
14119 gen_load_gpr(v2_t
, v2
);
14122 case OPC_EXTR_W_DSP
:
14126 tcg_gen_movi_tl(t0
, v2
);
14127 tcg_gen_movi_tl(t1
, v1
);
14128 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14131 tcg_gen_movi_tl(t0
, v2
);
14132 tcg_gen_movi_tl(t1
, v1
);
14133 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14135 case OPC_EXTR_RS_W
:
14136 tcg_gen_movi_tl(t0
, v2
);
14137 tcg_gen_movi_tl(t1
, v1
);
14138 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14141 tcg_gen_movi_tl(t0
, v2
);
14142 tcg_gen_movi_tl(t1
, v1
);
14143 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14145 case OPC_EXTRV_S_H
:
14146 tcg_gen_movi_tl(t0
, v2
);
14147 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14150 tcg_gen_movi_tl(t0
, v2
);
14151 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14153 case OPC_EXTRV_R_W
:
14154 tcg_gen_movi_tl(t0
, v2
);
14155 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14157 case OPC_EXTRV_RS_W
:
14158 tcg_gen_movi_tl(t0
, v2
);
14159 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14162 tcg_gen_movi_tl(t0
, v2
);
14163 tcg_gen_movi_tl(t1
, v1
);
14164 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14167 tcg_gen_movi_tl(t0
, v2
);
14168 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14171 tcg_gen_movi_tl(t0
, v2
);
14172 tcg_gen_movi_tl(t1
, v1
);
14173 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14176 tcg_gen_movi_tl(t0
, v2
);
14177 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14180 imm
= (ctx
->opcode
>> 20) & 0x3F;
14181 tcg_gen_movi_tl(t0
, ret
);
14182 tcg_gen_movi_tl(t1
, imm
);
14183 gen_helper_shilo(t0
, t1
, cpu_env
);
14186 tcg_gen_movi_tl(t0
, ret
);
14187 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14190 tcg_gen_movi_tl(t0
, ret
);
14191 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14194 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14195 tcg_gen_movi_tl(t0
, imm
);
14196 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14199 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14200 tcg_gen_movi_tl(t0
, imm
);
14201 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14205 #ifdef TARGET_MIPS64
14206 case OPC_DEXTR_W_DSP
:
14210 tcg_gen_movi_tl(t0
, ret
);
14211 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14215 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14216 int ac
= (ctx
->opcode
>> 11) & 0x03;
14217 tcg_gen_movi_tl(t0
, shift
);
14218 tcg_gen_movi_tl(t1
, ac
);
14219 gen_helper_dshilo(t0
, t1
, cpu_env
);
14224 int ac
= (ctx
->opcode
>> 11) & 0x03;
14225 tcg_gen_movi_tl(t0
, ac
);
14226 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14230 tcg_gen_movi_tl(t0
, v2
);
14231 tcg_gen_movi_tl(t1
, v1
);
14233 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14236 tcg_gen_movi_tl(t0
, v2
);
14237 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14240 tcg_gen_movi_tl(t0
, v2
);
14241 tcg_gen_movi_tl(t1
, v1
);
14242 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14245 tcg_gen_movi_tl(t0
, v2
);
14246 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14249 tcg_gen_movi_tl(t0
, v2
);
14250 tcg_gen_movi_tl(t1
, v1
);
14251 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14253 case OPC_DEXTR_R_L
:
14254 tcg_gen_movi_tl(t0
, v2
);
14255 tcg_gen_movi_tl(t1
, v1
);
14256 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14258 case OPC_DEXTR_RS_L
:
14259 tcg_gen_movi_tl(t0
, v2
);
14260 tcg_gen_movi_tl(t1
, v1
);
14261 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14264 tcg_gen_movi_tl(t0
, v2
);
14265 tcg_gen_movi_tl(t1
, v1
);
14266 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14268 case OPC_DEXTR_R_W
:
14269 tcg_gen_movi_tl(t0
, v2
);
14270 tcg_gen_movi_tl(t1
, v1
);
14271 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14273 case OPC_DEXTR_RS_W
:
14274 tcg_gen_movi_tl(t0
, v2
);
14275 tcg_gen_movi_tl(t1
, v1
);
14276 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14278 case OPC_DEXTR_S_H
:
14279 tcg_gen_movi_tl(t0
, v2
);
14280 tcg_gen_movi_tl(t1
, v1
);
14281 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14283 case OPC_DEXTRV_S_H
:
14284 tcg_gen_movi_tl(t0
, v2
);
14285 tcg_gen_movi_tl(t1
, v1
);
14286 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14289 tcg_gen_movi_tl(t0
, v2
);
14290 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14292 case OPC_DEXTRV_R_L
:
14293 tcg_gen_movi_tl(t0
, v2
);
14294 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14296 case OPC_DEXTRV_RS_L
:
14297 tcg_gen_movi_tl(t0
, v2
);
14298 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14301 tcg_gen_movi_tl(t0
, v2
);
14302 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14304 case OPC_DEXTRV_R_W
:
14305 tcg_gen_movi_tl(t0
, v2
);
14306 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14308 case OPC_DEXTRV_RS_W
:
14309 tcg_gen_movi_tl(t0
, v2
);
14310 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14319 tcg_temp_free(v1_t
);
14320 tcg_temp_free(v2_t
);
14322 (void)opn
; /* avoid a compiler warning */
14323 MIPS_DEBUG("%s", opn
);
14326 /* End MIPSDSP functions. */
14328 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14331 int rs
, rt
, rd
, sa
;
14332 uint32_t op
, op1
, op2
;
14335 /* make sure instructions are on a word boundary */
14336 if (ctx
->pc
& 0x3) {
14337 env
->CP0_BadVAddr
= ctx
->pc
;
14338 generate_exception(ctx
, EXCP_AdEL
);
14342 /* Handle blikely not taken case */
14343 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14344 int l1
= gen_new_label();
14346 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14347 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14348 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14349 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14353 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14354 tcg_gen_debug_insn_start(ctx
->pc
);
14357 op
= MASK_OP_MAJOR(ctx
->opcode
);
14358 rs
= (ctx
->opcode
>> 21) & 0x1f;
14359 rt
= (ctx
->opcode
>> 16) & 0x1f;
14360 rd
= (ctx
->opcode
>> 11) & 0x1f;
14361 sa
= (ctx
->opcode
>> 6) & 0x1f;
14362 imm
= (int16_t)ctx
->opcode
;
14365 op1
= MASK_SPECIAL(ctx
->opcode
);
14367 case OPC_SLL
: /* Shift with immediate */
14369 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14372 switch ((ctx
->opcode
>> 21) & 0x1f) {
14374 /* rotr is decoded as srl on non-R2 CPUs */
14375 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14380 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14383 generate_exception(ctx
, EXCP_RI
);
14387 case OPC_MOVN
: /* Conditional move */
14389 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14390 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14391 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14393 case OPC_ADD
... OPC_SUBU
:
14394 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14396 case OPC_SLLV
: /* Shifts */
14398 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14401 switch ((ctx
->opcode
>> 6) & 0x1f) {
14403 /* rotrv is decoded as srlv on non-R2 CPUs */
14404 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14409 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14412 generate_exception(ctx
, EXCP_RI
);
14416 case OPC_SLT
: /* Set on less than */
14418 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14420 case OPC_AND
: /* Logic*/
14424 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14429 check_insn(ctx
, INSN_VR54XX
);
14430 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14431 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14433 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14438 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14440 case OPC_JR
... OPC_JALR
:
14441 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14443 case OPC_TGE
... OPC_TEQ
: /* Traps */
14445 gen_trap(ctx
, op1
, rs
, rt
, -1);
14447 case OPC_MFHI
: /* Move from HI/LO */
14449 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14452 case OPC_MTLO
: /* Move to HI/LO */
14453 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14455 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14456 #ifdef MIPS_STRICT_STANDARD
14457 MIPS_INVAL("PMON / selsl");
14458 generate_exception(ctx
, EXCP_RI
);
14460 gen_helper_0e0i(pmon
, sa
);
14464 generate_exception(ctx
, EXCP_SYSCALL
);
14465 ctx
->bstate
= BS_STOP
;
14468 generate_exception(ctx
, EXCP_BREAK
);
14471 #ifdef MIPS_STRICT_STANDARD
14472 MIPS_INVAL("SPIM");
14473 generate_exception(ctx
, EXCP_RI
);
14475 /* Implemented as RI exception for now. */
14476 MIPS_INVAL("spim (unofficial)");
14477 generate_exception(ctx
, EXCP_RI
);
14481 /* Treat as NOP. */
14485 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14486 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14487 check_cp1_enabled(ctx
);
14488 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14489 (ctx
->opcode
>> 16) & 1);
14491 generate_exception_err(ctx
, EXCP_CpU
, 1);
14495 #if defined(TARGET_MIPS64)
14496 /* MIPS64 specific opcodes */
14501 check_insn(ctx
, ISA_MIPS3
);
14502 check_mips_64(ctx
);
14503 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14506 switch ((ctx
->opcode
>> 21) & 0x1f) {
14508 /* drotr is decoded as dsrl on non-R2 CPUs */
14509 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14514 check_insn(ctx
, ISA_MIPS3
);
14515 check_mips_64(ctx
);
14516 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14519 generate_exception(ctx
, EXCP_RI
);
14524 switch ((ctx
->opcode
>> 21) & 0x1f) {
14526 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14527 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14532 check_insn(ctx
, ISA_MIPS3
);
14533 check_mips_64(ctx
);
14534 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14537 generate_exception(ctx
, EXCP_RI
);
14541 case OPC_DADD
... OPC_DSUBU
:
14542 check_insn(ctx
, ISA_MIPS3
);
14543 check_mips_64(ctx
);
14544 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14548 check_insn(ctx
, ISA_MIPS3
);
14549 check_mips_64(ctx
);
14550 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14553 switch ((ctx
->opcode
>> 6) & 0x1f) {
14555 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14556 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14561 check_insn(ctx
, ISA_MIPS3
);
14562 check_mips_64(ctx
);
14563 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14566 generate_exception(ctx
, EXCP_RI
);
14570 case OPC_DMULT
... OPC_DDIVU
:
14571 check_insn(ctx
, ISA_MIPS3
);
14572 check_mips_64(ctx
);
14573 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14576 default: /* Invalid */
14577 MIPS_INVAL("special");
14578 generate_exception(ctx
, EXCP_RI
);
14583 op1
= MASK_SPECIAL2(ctx
->opcode
);
14585 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14586 case OPC_MSUB
... OPC_MSUBU
:
14587 check_insn(ctx
, ISA_MIPS32
);
14588 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14591 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14595 check_insn(ctx
, ISA_MIPS32
);
14596 gen_cl(ctx
, op1
, rd
, rs
);
14599 /* XXX: not clear which exception should be raised
14600 * when in debug mode...
14602 check_insn(ctx
, ISA_MIPS32
);
14603 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14604 generate_exception(ctx
, EXCP_DBp
);
14606 generate_exception(ctx
, EXCP_DBp
);
14608 /* Treat as NOP. */
14611 case OPC_DIVU_G_2F
:
14612 case OPC_MULT_G_2F
:
14613 case OPC_MULTU_G_2F
:
14615 case OPC_MODU_G_2F
:
14616 check_insn(ctx
, INSN_LOONGSON2F
);
14617 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14619 #if defined(TARGET_MIPS64)
14622 check_insn(ctx
, ISA_MIPS64
);
14623 check_mips_64(ctx
);
14624 gen_cl(ctx
, op1
, rd
, rs
);
14626 case OPC_DMULT_G_2F
:
14627 case OPC_DMULTU_G_2F
:
14628 case OPC_DDIV_G_2F
:
14629 case OPC_DDIVU_G_2F
:
14630 case OPC_DMOD_G_2F
:
14631 case OPC_DMODU_G_2F
:
14632 check_insn(ctx
, INSN_LOONGSON2F
);
14633 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14636 default: /* Invalid */
14637 MIPS_INVAL("special2");
14638 generate_exception(ctx
, EXCP_RI
);
14643 op1
= MASK_SPECIAL3(ctx
->opcode
);
14647 check_insn(ctx
, ISA_MIPS32R2
);
14648 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14651 check_insn(ctx
, ISA_MIPS32R2
);
14652 op2
= MASK_BSHFL(ctx
->opcode
);
14653 gen_bshfl(ctx
, op2
, rt
, rd
);
14656 gen_rdhwr(ctx
, rt
, rd
);
14659 check_insn(ctx
, ASE_MT
);
14661 TCGv t0
= tcg_temp_new();
14662 TCGv t1
= tcg_temp_new();
14664 gen_load_gpr(t0
, rt
);
14665 gen_load_gpr(t1
, rs
);
14666 gen_helper_fork(t0
, t1
);
14672 check_insn(ctx
, ASE_MT
);
14674 TCGv t0
= tcg_temp_new();
14676 save_cpu_state(ctx
, 1);
14677 gen_load_gpr(t0
, rs
);
14678 gen_helper_yield(t0
, cpu_env
, t0
);
14679 gen_store_gpr(t0
, rd
);
14683 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14684 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14685 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14686 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14687 * the same mask and op1. */
14688 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14689 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14692 case OPC_ADDUH_R_QB
:
14694 case OPC_ADDQH_R_PH
:
14696 case OPC_ADDQH_R_W
:
14698 case OPC_SUBUH_R_QB
:
14700 case OPC_SUBQH_R_PH
:
14702 case OPC_SUBQH_R_W
:
14703 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14708 case OPC_MULQ_RS_W
:
14709 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14712 MIPS_INVAL("MASK ADDUH.QB");
14713 generate_exception(ctx
, EXCP_RI
);
14716 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14717 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14719 generate_exception(ctx
, EXCP_RI
);
14723 op2
= MASK_LX(ctx
->opcode
);
14725 #if defined(TARGET_MIPS64)
14731 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14733 default: /* Invalid */
14734 MIPS_INVAL("MASK LX");
14735 generate_exception(ctx
, EXCP_RI
);
14739 case OPC_ABSQ_S_PH_DSP
:
14740 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14742 case OPC_ABSQ_S_QB
:
14743 case OPC_ABSQ_S_PH
:
14745 case OPC_PRECEQ_W_PHL
:
14746 case OPC_PRECEQ_W_PHR
:
14747 case OPC_PRECEQU_PH_QBL
:
14748 case OPC_PRECEQU_PH_QBR
:
14749 case OPC_PRECEQU_PH_QBLA
:
14750 case OPC_PRECEQU_PH_QBRA
:
14751 case OPC_PRECEU_PH_QBL
:
14752 case OPC_PRECEU_PH_QBR
:
14753 case OPC_PRECEU_PH_QBLA
:
14754 case OPC_PRECEU_PH_QBRA
:
14755 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14762 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14765 MIPS_INVAL("MASK ABSQ_S.PH");
14766 generate_exception(ctx
, EXCP_RI
);
14770 case OPC_ADDU_QB_DSP
:
14771 op2
= MASK_ADDU_QB(ctx
->opcode
);
14774 case OPC_ADDQ_S_PH
:
14777 case OPC_ADDU_S_QB
:
14779 case OPC_ADDU_S_PH
:
14781 case OPC_SUBQ_S_PH
:
14784 case OPC_SUBU_S_QB
:
14786 case OPC_SUBU_S_PH
:
14790 case OPC_RADDU_W_QB
:
14791 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14793 case OPC_MULEU_S_PH_QBL
:
14794 case OPC_MULEU_S_PH_QBR
:
14795 case OPC_MULQ_RS_PH
:
14796 case OPC_MULEQ_S_W_PHL
:
14797 case OPC_MULEQ_S_W_PHR
:
14798 case OPC_MULQ_S_PH
:
14799 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14801 default: /* Invalid */
14802 MIPS_INVAL("MASK ADDU.QB");
14803 generate_exception(ctx
, EXCP_RI
);
14808 case OPC_CMPU_EQ_QB_DSP
:
14809 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14811 case OPC_PRECR_SRA_PH_W
:
14812 case OPC_PRECR_SRA_R_PH_W
:
14813 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14815 case OPC_PRECR_QB_PH
:
14816 case OPC_PRECRQ_QB_PH
:
14817 case OPC_PRECRQ_PH_W
:
14818 case OPC_PRECRQ_RS_PH_W
:
14819 case OPC_PRECRQU_S_QB_PH
:
14820 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14822 case OPC_CMPU_EQ_QB
:
14823 case OPC_CMPU_LT_QB
:
14824 case OPC_CMPU_LE_QB
:
14825 case OPC_CMP_EQ_PH
:
14826 case OPC_CMP_LT_PH
:
14827 case OPC_CMP_LE_PH
:
14828 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14830 case OPC_CMPGU_EQ_QB
:
14831 case OPC_CMPGU_LT_QB
:
14832 case OPC_CMPGU_LE_QB
:
14833 case OPC_CMPGDU_EQ_QB
:
14834 case OPC_CMPGDU_LT_QB
:
14835 case OPC_CMPGDU_LE_QB
:
14838 case OPC_PACKRL_PH
:
14839 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14841 default: /* Invalid */
14842 MIPS_INVAL("MASK CMPU.EQ.QB");
14843 generate_exception(ctx
, EXCP_RI
);
14847 case OPC_SHLL_QB_DSP
:
14848 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14850 case OPC_DPA_W_PH_DSP
:
14851 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14853 case OPC_DPAU_H_QBL
:
14854 case OPC_DPAU_H_QBR
:
14855 case OPC_DPSU_H_QBL
:
14856 case OPC_DPSU_H_QBR
:
14858 case OPC_DPAX_W_PH
:
14859 case OPC_DPAQ_S_W_PH
:
14860 case OPC_DPAQX_S_W_PH
:
14861 case OPC_DPAQX_SA_W_PH
:
14863 case OPC_DPSX_W_PH
:
14864 case OPC_DPSQ_S_W_PH
:
14865 case OPC_DPSQX_S_W_PH
:
14866 case OPC_DPSQX_SA_W_PH
:
14867 case OPC_MULSAQ_S_W_PH
:
14868 case OPC_DPAQ_SA_L_W
:
14869 case OPC_DPSQ_SA_L_W
:
14870 case OPC_MAQ_S_W_PHL
:
14871 case OPC_MAQ_S_W_PHR
:
14872 case OPC_MAQ_SA_W_PHL
:
14873 case OPC_MAQ_SA_W_PHR
:
14874 case OPC_MULSA_W_PH
:
14875 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14877 default: /* Invalid */
14878 MIPS_INVAL("MASK DPAW.PH");
14879 generate_exception(ctx
, EXCP_RI
);
14884 op2
= MASK_INSV(ctx
->opcode
);
14896 t0
= tcg_temp_new();
14897 t1
= tcg_temp_new();
14899 gen_load_gpr(t0
, rt
);
14900 gen_load_gpr(t1
, rs
);
14902 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14908 default: /* Invalid */
14909 MIPS_INVAL("MASK INSV");
14910 generate_exception(ctx
, EXCP_RI
);
14914 case OPC_APPEND_DSP
:
14915 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14917 case OPC_EXTR_W_DSP
:
14918 op2
= MASK_EXTR_W(ctx
->opcode
);
14922 case OPC_EXTR_RS_W
:
14924 case OPC_EXTRV_S_H
:
14926 case OPC_EXTRV_R_W
:
14927 case OPC_EXTRV_RS_W
:
14932 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14935 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14941 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14943 default: /* Invalid */
14944 MIPS_INVAL("MASK EXTR.W");
14945 generate_exception(ctx
, EXCP_RI
);
14949 #if defined(TARGET_MIPS64)
14950 case OPC_DEXTM
... OPC_DEXT
:
14951 case OPC_DINSM
... OPC_DINS
:
14952 check_insn(ctx
, ISA_MIPS64R2
);
14953 check_mips_64(ctx
);
14954 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14957 check_insn(ctx
, ISA_MIPS64R2
);
14958 check_mips_64(ctx
);
14959 op2
= MASK_DBSHFL(ctx
->opcode
);
14960 gen_bshfl(ctx
, op2
, rt
, rd
);
14962 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
14963 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
14964 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
14965 check_insn(ctx
, INSN_LOONGSON2E
);
14966 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14968 case OPC_ABSQ_S_QH_DSP
:
14969 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
14971 case OPC_PRECEQ_L_PWL
:
14972 case OPC_PRECEQ_L_PWR
:
14973 case OPC_PRECEQ_PW_QHL
:
14974 case OPC_PRECEQ_PW_QHR
:
14975 case OPC_PRECEQ_PW_QHLA
:
14976 case OPC_PRECEQ_PW_QHRA
:
14977 case OPC_PRECEQU_QH_OBL
:
14978 case OPC_PRECEQU_QH_OBR
:
14979 case OPC_PRECEQU_QH_OBLA
:
14980 case OPC_PRECEQU_QH_OBRA
:
14981 case OPC_PRECEU_QH_OBL
:
14982 case OPC_PRECEU_QH_OBR
:
14983 case OPC_PRECEU_QH_OBLA
:
14984 case OPC_PRECEU_QH_OBRA
:
14985 case OPC_ABSQ_S_OB
:
14986 case OPC_ABSQ_S_PW
:
14987 case OPC_ABSQ_S_QH
:
14988 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14996 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14998 default: /* Invalid */
14999 MIPS_INVAL("MASK ABSQ_S.QH");
15000 generate_exception(ctx
, EXCP_RI
);
15004 case OPC_ADDU_OB_DSP
:
15005 op2
= MASK_ADDU_OB(ctx
->opcode
);
15007 case OPC_RADDU_L_OB
:
15009 case OPC_SUBQ_S_PW
:
15011 case OPC_SUBQ_S_QH
:
15013 case OPC_SUBU_S_OB
:
15015 case OPC_SUBU_S_QH
:
15017 case OPC_SUBUH_R_OB
:
15019 case OPC_ADDQ_S_PW
:
15021 case OPC_ADDQ_S_QH
:
15023 case OPC_ADDU_S_OB
:
15025 case OPC_ADDU_S_QH
:
15027 case OPC_ADDUH_R_OB
:
15028 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15030 case OPC_MULEQ_S_PW_QHL
:
15031 case OPC_MULEQ_S_PW_QHR
:
15032 case OPC_MULEU_S_QH_OBL
:
15033 case OPC_MULEU_S_QH_OBR
:
15034 case OPC_MULQ_RS_QH
:
15035 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15037 default: /* Invalid */
15038 MIPS_INVAL("MASK ADDU.OB");
15039 generate_exception(ctx
, EXCP_RI
);
15043 case OPC_CMPU_EQ_OB_DSP
:
15044 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15046 case OPC_PRECR_SRA_QH_PW
:
15047 case OPC_PRECR_SRA_R_QH_PW
:
15048 /* Return value is rt. */
15049 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15051 case OPC_PRECR_OB_QH
:
15052 case OPC_PRECRQ_OB_QH
:
15053 case OPC_PRECRQ_PW_L
:
15054 case OPC_PRECRQ_QH_PW
:
15055 case OPC_PRECRQ_RS_QH_PW
:
15056 case OPC_PRECRQU_S_OB_QH
:
15057 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15059 case OPC_CMPU_EQ_OB
:
15060 case OPC_CMPU_LT_OB
:
15061 case OPC_CMPU_LE_OB
:
15062 case OPC_CMP_EQ_QH
:
15063 case OPC_CMP_LT_QH
:
15064 case OPC_CMP_LE_QH
:
15065 case OPC_CMP_EQ_PW
:
15066 case OPC_CMP_LT_PW
:
15067 case OPC_CMP_LE_PW
:
15068 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15070 case OPC_CMPGDU_EQ_OB
:
15071 case OPC_CMPGDU_LT_OB
:
15072 case OPC_CMPGDU_LE_OB
:
15073 case OPC_CMPGU_EQ_OB
:
15074 case OPC_CMPGU_LT_OB
:
15075 case OPC_CMPGU_LE_OB
:
15076 case OPC_PACKRL_PW
:
15080 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15082 default: /* Invalid */
15083 MIPS_INVAL("MASK CMPU_EQ.OB");
15084 generate_exception(ctx
, EXCP_RI
);
15088 case OPC_DAPPEND_DSP
:
15089 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15091 case OPC_DEXTR_W_DSP
:
15092 op2
= MASK_DEXTR_W(ctx
->opcode
);
15099 case OPC_DEXTR_R_L
:
15100 case OPC_DEXTR_RS_L
:
15102 case OPC_DEXTR_R_W
:
15103 case OPC_DEXTR_RS_W
:
15104 case OPC_DEXTR_S_H
:
15106 case OPC_DEXTRV_R_L
:
15107 case OPC_DEXTRV_RS_L
:
15108 case OPC_DEXTRV_S_H
:
15110 case OPC_DEXTRV_R_W
:
15111 case OPC_DEXTRV_RS_W
:
15112 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15117 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15119 default: /* Invalid */
15120 MIPS_INVAL("MASK EXTR.W");
15121 generate_exception(ctx
, EXCP_RI
);
15125 case OPC_DPAQ_W_QH_DSP
:
15126 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15128 case OPC_DPAU_H_OBL
:
15129 case OPC_DPAU_H_OBR
:
15130 case OPC_DPSU_H_OBL
:
15131 case OPC_DPSU_H_OBR
:
15133 case OPC_DPAQ_S_W_QH
:
15135 case OPC_DPSQ_S_W_QH
:
15136 case OPC_MULSAQ_S_W_QH
:
15137 case OPC_DPAQ_SA_L_PW
:
15138 case OPC_DPSQ_SA_L_PW
:
15139 case OPC_MULSAQ_S_L_PW
:
15140 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15142 case OPC_MAQ_S_W_QHLL
:
15143 case OPC_MAQ_S_W_QHLR
:
15144 case OPC_MAQ_S_W_QHRL
:
15145 case OPC_MAQ_S_W_QHRR
:
15146 case OPC_MAQ_SA_W_QHLL
:
15147 case OPC_MAQ_SA_W_QHLR
:
15148 case OPC_MAQ_SA_W_QHRL
:
15149 case OPC_MAQ_SA_W_QHRR
:
15150 case OPC_MAQ_S_L_PWL
:
15151 case OPC_MAQ_S_L_PWR
:
15156 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15158 default: /* Invalid */
15159 MIPS_INVAL("MASK DPAQ.W.QH");
15160 generate_exception(ctx
, EXCP_RI
);
15164 case OPC_DINSV_DSP
:
15165 op2
= MASK_INSV(ctx
->opcode
);
15177 t0
= tcg_temp_new();
15178 t1
= tcg_temp_new();
15180 gen_load_gpr(t0
, rt
);
15181 gen_load_gpr(t1
, rs
);
15183 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15186 default: /* Invalid */
15187 MIPS_INVAL("MASK DINSV");
15188 generate_exception(ctx
, EXCP_RI
);
15192 case OPC_SHLL_OB_DSP
:
15193 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15196 default: /* Invalid */
15197 MIPS_INVAL("special3");
15198 generate_exception(ctx
, EXCP_RI
);
15203 op1
= MASK_REGIMM(ctx
->opcode
);
15205 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15206 case OPC_BLTZAL
... OPC_BGEZALL
:
15207 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15209 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15211 gen_trap(ctx
, op1
, rs
, -1, imm
);
15214 check_insn(ctx
, ISA_MIPS32R2
);
15215 /* Treat as NOP. */
15217 case OPC_BPOSGE32
: /* MIPS DSP branch */
15218 #if defined(TARGET_MIPS64)
15222 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15224 default: /* Invalid */
15225 MIPS_INVAL("regimm");
15226 generate_exception(ctx
, EXCP_RI
);
15231 check_cp0_enabled(ctx
);
15232 op1
= MASK_CP0(ctx
->opcode
);
15238 #if defined(TARGET_MIPS64)
15242 #ifndef CONFIG_USER_ONLY
15243 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15244 #endif /* !CONFIG_USER_ONLY */
15246 case OPC_C0_FIRST
... OPC_C0_LAST
:
15247 #ifndef CONFIG_USER_ONLY
15248 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15249 #endif /* !CONFIG_USER_ONLY */
15252 #ifndef CONFIG_USER_ONLY
15254 TCGv t0
= tcg_temp_new();
15256 op2
= MASK_MFMC0(ctx
->opcode
);
15259 check_insn(ctx
, ASE_MT
);
15260 gen_helper_dmt(t0
);
15261 gen_store_gpr(t0
, rt
);
15264 check_insn(ctx
, ASE_MT
);
15265 gen_helper_emt(t0
);
15266 gen_store_gpr(t0
, rt
);
15269 check_insn(ctx
, ASE_MT
);
15270 gen_helper_dvpe(t0
, cpu_env
);
15271 gen_store_gpr(t0
, rt
);
15274 check_insn(ctx
, ASE_MT
);
15275 gen_helper_evpe(t0
, cpu_env
);
15276 gen_store_gpr(t0
, rt
);
15279 check_insn(ctx
, ISA_MIPS32R2
);
15280 save_cpu_state(ctx
, 1);
15281 gen_helper_di(t0
, cpu_env
);
15282 gen_store_gpr(t0
, rt
);
15283 /* Stop translation as we may have switched the execution mode */
15284 ctx
->bstate
= BS_STOP
;
15287 check_insn(ctx
, ISA_MIPS32R2
);
15288 save_cpu_state(ctx
, 1);
15289 gen_helper_ei(t0
, cpu_env
);
15290 gen_store_gpr(t0
, rt
);
15291 /* Stop translation as we may have switched the execution mode */
15292 ctx
->bstate
= BS_STOP
;
15294 default: /* Invalid */
15295 MIPS_INVAL("mfmc0");
15296 generate_exception(ctx
, EXCP_RI
);
15301 #endif /* !CONFIG_USER_ONLY */
15304 check_insn(ctx
, ISA_MIPS32R2
);
15305 gen_load_srsgpr(rt
, rd
);
15308 check_insn(ctx
, ISA_MIPS32R2
);
15309 gen_store_srsgpr(rt
, rd
);
15313 generate_exception(ctx
, EXCP_RI
);
15317 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15319 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15321 case OPC_SLTI
: /* Set on less than with immediate opcode */
15323 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15325 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15329 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15331 case OPC_J
... OPC_JAL
: /* Jump */
15332 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15333 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15335 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15336 case OPC_BEQL
... OPC_BGTZL
:
15337 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15339 case OPC_LB
... OPC_LWR
: /* Load and stores */
15341 gen_ld(ctx
, op
, rt
, rs
, imm
);
15343 case OPC_SB
... OPC_SW
:
15345 gen_st(ctx
, op
, rt
, rs
, imm
);
15348 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15351 check_cp0_enabled(ctx
);
15352 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15353 /* Treat as NOP. */
15356 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15357 /* Treat as NOP. */
15360 /* Floating point (COP1). */
15365 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15369 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15370 check_cp1_enabled(ctx
);
15371 op1
= MASK_CP1(ctx
->opcode
);
15375 check_insn(ctx
, ISA_MIPS32R2
);
15380 gen_cp1(ctx
, op1
, rt
, rd
);
15382 #if defined(TARGET_MIPS64)
15385 check_insn(ctx
, ISA_MIPS3
);
15386 gen_cp1(ctx
, op1
, rt
, rd
);
15392 check_insn(ctx
, ASE_MIPS3D
);
15395 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15396 (rt
>> 2) & 0x7, imm
<< 2);
15403 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15408 generate_exception (ctx
, EXCP_RI
);
15412 generate_exception_err(ctx
, EXCP_CpU
, 1);
15421 /* COP2: Not implemented. */
15422 generate_exception_err(ctx
, EXCP_CpU
, 2);
15425 check_insn(ctx
, INSN_LOONGSON2F
);
15426 /* Note that these instructions use different fields. */
15427 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15431 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15432 check_cp1_enabled(ctx
);
15433 op1
= MASK_CP3(ctx
->opcode
);
15441 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15444 /* Treat as NOP. */
15459 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15463 generate_exception (ctx
, EXCP_RI
);
15467 generate_exception_err(ctx
, EXCP_CpU
, 1);
15471 #if defined(TARGET_MIPS64)
15472 /* MIPS64 opcodes */
15474 case OPC_LDL
... OPC_LDR
:
15477 check_insn(ctx
, ISA_MIPS3
);
15478 check_mips_64(ctx
);
15479 gen_ld(ctx
, op
, rt
, rs
, imm
);
15481 case OPC_SDL
... OPC_SDR
:
15483 check_insn(ctx
, ISA_MIPS3
);
15484 check_mips_64(ctx
);
15485 gen_st(ctx
, op
, rt
, rs
, imm
);
15488 check_insn(ctx
, ISA_MIPS3
);
15489 check_mips_64(ctx
);
15490 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15494 check_insn(ctx
, ISA_MIPS3
);
15495 check_mips_64(ctx
);
15496 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15500 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15501 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15502 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15505 check_insn(ctx
, ASE_MDMX
);
15506 /* MDMX: Not implemented. */
15507 default: /* Invalid */
15508 MIPS_INVAL("major opcode");
15509 generate_exception(ctx
, EXCP_RI
);
15515 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15518 CPUState
*cs
= CPU(cpu
);
15519 CPUMIPSState
*env
= &cpu
->env
;
15521 target_ulong pc_start
;
15522 uint16_t *gen_opc_end
;
15531 qemu_log("search pc %d\n", search_pc
);
15534 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15537 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15538 ctx
.insn_flags
= env
->insn_flags
;
15540 ctx
.bstate
= BS_NONE
;
15541 /* Restore delay slot state from the tb context. */
15542 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15543 restore_cpu_state(env
, &ctx
);
15544 #ifdef CONFIG_USER_ONLY
15545 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15547 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15550 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15551 if (max_insns
== 0)
15552 max_insns
= CF_COUNT_MASK
;
15553 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15555 while (ctx
.bstate
== BS_NONE
) {
15556 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15557 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15558 if (bp
->pc
== ctx
.pc
) {
15559 save_cpu_state(&ctx
, 1);
15560 ctx
.bstate
= BS_BRANCH
;
15561 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15562 /* Include the breakpoint location or the tb won't
15563 * be flushed when it must be. */
15565 goto done_generating
;
15571 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15575 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15577 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15578 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15579 gen_opc_btarget
[lj
] = ctx
.btarget
;
15580 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15581 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15583 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15586 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15587 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15588 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15590 decode_opc(env
, &ctx
);
15591 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15592 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15593 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15594 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15595 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15596 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15598 generate_exception(&ctx
, EXCP_RI
);
15599 ctx
.bstate
= BS_STOP
;
15603 handle_delay_slot(&ctx
, insn_bytes
);
15605 ctx
.pc
+= insn_bytes
;
15609 /* Execute a branch and its delay slot as a single instruction.
15610 This is what GDB expects and is consistent with what the
15611 hardware does (e.g. if a delay slot instruction faults, the
15612 reported PC is the PC of the branch). */
15613 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15617 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15620 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15624 if (num_insns
>= max_insns
)
15630 if (tb
->cflags
& CF_LAST_IO
) {
15633 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15634 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15635 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15637 switch (ctx
.bstate
) {
15639 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15642 save_cpu_state(&ctx
, 0);
15643 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15646 tcg_gen_exit_tb(0);
15654 gen_tb_end(tb
, num_insns
);
15655 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15657 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15660 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15662 tb
->size
= ctx
.pc
- pc_start
;
15663 tb
->icount
= num_insns
;
15667 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15668 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15669 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15675 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15677 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15680 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15682 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15685 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15689 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15691 #define printfpr(fp) \
15694 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15695 " fd:%13g fs:%13g psu: %13g\n", \
15696 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15697 (double)(fp)->fd, \
15698 (double)(fp)->fs[FP_ENDIAN_IDX], \
15699 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15702 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15703 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15704 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15705 " fd:%13g fs:%13g psu:%13g\n", \
15706 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15708 (double)tmp.fs[FP_ENDIAN_IDX], \
15709 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15714 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15715 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15716 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15717 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15718 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15719 printfpr(&env
->active_fpu
.fpr
[i
]);
15725 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15726 /* Debug help: The architecture requires 32bit code to maintain proper
15727 sign-extended values on 64bit machines. */
15729 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15732 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15733 fprintf_function cpu_fprintf
,
15738 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15739 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15740 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15741 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15742 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15743 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15744 if (!SIGN_EXT_P(env
->btarget
))
15745 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15747 for (i
= 0; i
< 32; i
++) {
15748 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15749 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15752 if (!SIGN_EXT_P(env
->CP0_EPC
))
15753 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15754 if (!SIGN_EXT_P(env
->lladdr
))
15755 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15759 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15762 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15763 CPUMIPSState
*env
= &cpu
->env
;
15766 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15767 " LO=0x" TARGET_FMT_lx
" ds %04x "
15768 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15769 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15770 env
->hflags
, env
->btarget
, env
->bcond
);
15771 for (i
= 0; i
< 32; i
++) {
15773 cpu_fprintf(f
, "GPR%02d:", i
);
15774 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15776 cpu_fprintf(f
, "\n");
15779 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15780 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15781 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15782 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15783 if (env
->hflags
& MIPS_HFLAG_FPU
)
15784 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15785 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15786 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15790 void mips_tcg_init(void)
15795 /* Initialize various static tables. */
15799 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15800 TCGV_UNUSED(cpu_gpr
[0]);
15801 for (i
= 1; i
< 32; i
++)
15802 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15803 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15806 for (i
= 0; i
< 32; i
++) {
15807 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15808 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15811 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15812 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15813 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15814 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15815 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15817 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15818 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15820 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15821 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15824 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15825 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15827 bcond
= tcg_global_mem_new(TCG_AREG0
,
15828 offsetof(CPUMIPSState
, bcond
), "bcond");
15829 btarget
= tcg_global_mem_new(TCG_AREG0
,
15830 offsetof(CPUMIPSState
, btarget
), "btarget");
15831 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15832 offsetof(CPUMIPSState
, hflags
), "hflags");
15834 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15835 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15837 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15838 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15841 /* register helpers */
15842 #define GEN_HELPER 2
15843 #include "helper.h"
15848 #include "translate_init.c"
15850 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15854 const mips_def_t
*def
;
15856 def
= cpu_mips_find_by_name(cpu_model
);
15859 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15861 env
->cpu_model
= def
;
15862 env
->cpu_model_str
= cpu_model
;
15864 #ifndef CONFIG_USER_ONLY
15865 mmu_init(env
, def
);
15867 fpu_init(env
, def
);
15868 mvp_init(env
, def
);
15870 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15875 void cpu_state_reset(CPUMIPSState
*env
)
15877 #ifndef CONFIG_USER_ONLY
15878 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15879 CPUState
*cs
= CPU(cpu
);
15882 /* Reset registers to their default values */
15883 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15884 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15885 #ifdef TARGET_WORDS_BIGENDIAN
15886 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15888 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15889 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15890 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15891 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15892 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15893 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15894 << env
->cpu_model
->CP0_LLAddr_shift
;
15895 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15896 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15897 env
->CCRes
= env
->cpu_model
->CCRes
;
15898 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15899 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15900 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15901 env
->current_tc
= 0;
15902 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15903 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15904 #if defined(TARGET_MIPS64)
15905 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15906 env
->SEGMask
|= 3ULL << 62;
15909 env
->PABITS
= env
->cpu_model
->PABITS
;
15910 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15911 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15912 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15913 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15914 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15915 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15916 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15917 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15918 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15919 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15920 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15921 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15922 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15924 #if defined(CONFIG_USER_ONLY)
15925 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15926 # ifdef TARGET_MIPS64
15927 /* Enable 64-bit register mode. */
15928 env
->CP0_Status
|= (1 << CP0St_PX
);
15930 # ifdef TARGET_ABI_MIPSN64
15931 /* Enable 64-bit address mode. */
15932 env
->CP0_Status
|= (1 << CP0St_UX
);
15934 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15935 hardware registers. */
15936 env
->CP0_HWREna
|= 0x0000000F;
15937 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15938 env
->CP0_Status
|= (1 << CP0St_CU1
);
15940 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
15941 env
->CP0_Status
|= (1 << CP0St_MX
);
15943 /* Enable 64-bit FPU if the target cpu supports it. */
15944 if (env
->active_fpu
.fcr0
& (1 << FCR0_F64
)) {
15945 env
->CP0_Status
|= (1 << CP0St_FR
);
15948 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15949 /* If the exception was raised from a delay slot,
15950 come back to the jump. */
15951 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15953 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
15955 env
->active_tc
.PC
= (int32_t)0xBFC00000;
15956 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
15957 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
15958 env
->CP0_Wired
= 0;
15959 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
15960 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
15961 /* vectored interrupts not implemented, timer on int 7,
15962 no performance counters. */
15963 env
->CP0_IntCtl
= 0xe0000000;
15967 for (i
= 0; i
< 7; i
++) {
15968 env
->CP0_WatchLo
[i
] = 0;
15969 env
->CP0_WatchHi
[i
] = 0x80000000;
15971 env
->CP0_WatchLo
[7] = 0;
15972 env
->CP0_WatchHi
[7] = 0;
15974 /* Count register increments in debug mode, EJTAG version 1 */
15975 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
15977 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
15980 /* Only TC0 on VPE 0 starts as active. */
15981 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
15982 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
15983 env
->tcs
[i
].CP0_TCHalt
= 1;
15985 env
->active_tc
.CP0_TCHalt
= 1;
15988 if (cs
->cpu_index
== 0) {
15989 /* VPE0 starts up enabled. */
15990 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
15991 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
15993 /* TC0 starts up unhalted. */
15995 env
->active_tc
.CP0_TCHalt
= 0;
15996 env
->tcs
[0].CP0_TCHalt
= 0;
15997 /* With thread 0 active. */
15998 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
15999 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16003 compute_hflags(env
);
16004 env
->exception_index
= EXCP_NONE
;
16007 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16009 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16010 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16011 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16012 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16013 case MIPS_HFLAG_BR
:
16015 case MIPS_HFLAG_BC
:
16016 case MIPS_HFLAG_BL
:
16018 env
->btarget
= gen_opc_btarget
[pc_pos
];