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/>.
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 #if defined(TARGET_MIPS64)
322 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
324 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
325 #if defined(TARGET_MIPS64)
326 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
328 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
329 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
330 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
331 #if defined(TARGET_MIPS64)
332 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
334 /* MIPS DSP GPR-Based Shift Sub-class */
335 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
336 #if defined(TARGET_MIPS64)
337 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
339 /* MIPS DSP Multiply Sub-class insns */
340 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
341 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
342 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
343 #if defined(TARGET_MIPS64)
344 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
346 /* DSP Bit/Manipulation Sub-class */
347 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
348 #if defined(TARGET_MIPS64)
349 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
351 /* MIPS DSP Compare-Pick Sub-class */
352 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
353 #if defined(TARGET_MIPS64)
354 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
359 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
362 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
363 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
364 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
368 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
371 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
372 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
375 /* MIPS DSP REGIMM opcodes */
377 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
378 #if defined(TARGET_MIPS64)
379 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
383 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
386 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
387 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
388 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
389 #if defined(TARGET_MIPS64)
390 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
394 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
396 /* MIPS DSP Arithmetic Sub-class */
397 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
398 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
399 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
400 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
401 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
404 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
405 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
406 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
407 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
408 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
409 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
410 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
411 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
412 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
413 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
414 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
415 /* MIPS DSP Multiply Sub-class insns */
416 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
417 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
418 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
419 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
420 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
421 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
424 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
425 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
427 /* MIPS DSP Arithmetic Sub-class */
428 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
429 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
430 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
431 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
432 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
433 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
434 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
435 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
436 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
437 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
438 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
439 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
440 /* MIPS DSP Multiply Sub-class insns */
441 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
442 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
443 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
444 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
447 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
449 /* MIPS DSP Arithmetic Sub-class */
450 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
453 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
454 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
455 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
456 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
457 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
458 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
459 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
460 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
461 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
462 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
463 /* DSP Bit/Manipulation Sub-class */
464 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
465 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
466 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
467 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
468 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
471 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
473 /* MIPS DSP Arithmetic Sub-class */
474 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
481 /* DSP Compare-Pick Sub-class */
482 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
483 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
484 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
485 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
486 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
487 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
488 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
489 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
490 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
491 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
492 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
493 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
494 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
495 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
496 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
499 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501 /* MIPS DSP GPR-Based Shift Sub-class */
502 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
509 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
510 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
511 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
512 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
513 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
514 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
515 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
516 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
517 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
518 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
519 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
520 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
521 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
522 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
523 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
526 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
528 /* MIPS DSP Multiply Sub-class insns */
529 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
536 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
537 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
538 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
539 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
540 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
541 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
542 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
543 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
544 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
545 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
546 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
547 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
548 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
549 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
550 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
553 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555 /* DSP Bit/Manipulation Sub-class */
556 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
559 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
561 /* MIPS DSP Compare-Pick Sub-class */
562 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
563 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
564 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
567 #if defined(TARGET_MIPS64)
568 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
570 /* MIPS DSP Arithmetic Sub-class */
571 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
572 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
573 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
574 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
575 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
576 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
577 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
578 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
588 /* DSP Bit/Manipulation Sub-class */
589 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
594 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
598 #if defined(TARGET_MIPS64)
599 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
601 /* MIPS DSP Multiply Sub-class insns */
602 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
603 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
604 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
605 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
606 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
607 /* MIPS DSP Arithmetic Sub-class */
608 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
609 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
610 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
611 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
612 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
613 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
619 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
620 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
621 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
622 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
623 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
632 #if defined(TARGET_MIPS64)
633 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635 /* DSP Compare-Pick Sub-class */
636 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
637 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
638 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
639 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
655 /* MIPS DSP Arithmetic Sub-class */
656 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
657 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
658 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
667 #if defined(TARGET_MIPS64)
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick 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
,
678 #if defined(TARGET_MIPS64)
679 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
681 /* DSP Bit/Manipulation Sub-class */
682 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
686 #if defined(TARGET_MIPS64)
687 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
689 /* MIPS DSP Multiply Sub-class insns */
690 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
691 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
692 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
693 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
694 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
695 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
696 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
697 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
698 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
699 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
700 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
701 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
702 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
703 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
704 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
705 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
706 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
707 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
708 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
709 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
710 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
711 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
712 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
713 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
719 #if defined(TARGET_MIPS64)
720 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722 /* MIPS DSP GPR-Based Shift Sub-class */
723 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
724 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
725 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
726 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
727 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
728 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
729 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
730 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
731 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
732 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
733 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
734 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
735 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
736 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
737 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
738 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
739 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
740 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
741 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
742 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
743 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
744 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
752 /* Coprocessor 0 (rs field) */
753 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
756 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
757 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
758 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
759 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
760 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
761 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
762 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
763 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
764 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
765 OPC_C0
= (0x10 << 21) | OPC_CP0
,
766 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
767 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
771 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
774 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
775 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
776 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
777 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
778 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
779 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
782 /* Coprocessor 0 (with rs == C0) */
783 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
786 OPC_TLBR
= 0x01 | OPC_C0
,
787 OPC_TLBWI
= 0x02 | OPC_C0
,
788 OPC_TLBWR
= 0x06 | OPC_C0
,
789 OPC_TLBP
= 0x08 | OPC_C0
,
790 OPC_RFE
= 0x10 | OPC_C0
,
791 OPC_ERET
= 0x18 | OPC_C0
,
792 OPC_DERET
= 0x1F | OPC_C0
,
793 OPC_WAIT
= 0x20 | OPC_C0
,
796 /* Coprocessor 1 (rs field) */
797 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
799 /* Values for the fmt field in FP instructions */
801 /* 0 - 15 are reserved */
802 FMT_S
= 16, /* single fp */
803 FMT_D
= 17, /* double fp */
804 FMT_E
= 18, /* extended fp */
805 FMT_Q
= 19, /* quad fp */
806 FMT_W
= 20, /* 32-bit fixed */
807 FMT_L
= 21, /* 64-bit fixed */
808 FMT_PS
= 22, /* paired single fp */
809 /* 23 - 31 are reserved */
813 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
814 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
815 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
816 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
817 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
818 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
819 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
820 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
821 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
822 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
823 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
824 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
825 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
826 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
827 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
828 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
829 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
830 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
833 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
834 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
837 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
838 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
839 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
840 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
844 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
845 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
849 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
850 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
853 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
856 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
857 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
858 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
859 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
860 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
861 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
862 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
863 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
864 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
867 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
870 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
871 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
872 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
873 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
874 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
875 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
876 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
877 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
879 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
880 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
881 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
882 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
883 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
884 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
885 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
886 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
888 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
889 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
890 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
891 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
892 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
893 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
894 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
895 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
897 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
898 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
899 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
900 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
901 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
902 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
903 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
904 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
906 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
907 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
908 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
909 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
910 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
911 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
913 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
914 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
915 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
916 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
917 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
918 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
920 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
921 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
922 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
923 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
924 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
925 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
927 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
928 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
929 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
930 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
931 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
932 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
934 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
935 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
936 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
937 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
938 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
939 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
941 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
942 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
943 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
944 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
945 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
946 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
948 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
949 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
950 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
951 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
952 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
953 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
955 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
956 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
957 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
958 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
959 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
960 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
964 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
967 OPC_LWXC1
= 0x00 | OPC_CP3
,
968 OPC_LDXC1
= 0x01 | OPC_CP3
,
969 OPC_LUXC1
= 0x05 | OPC_CP3
,
970 OPC_SWXC1
= 0x08 | OPC_CP3
,
971 OPC_SDXC1
= 0x09 | OPC_CP3
,
972 OPC_SUXC1
= 0x0D | OPC_CP3
,
973 OPC_PREFX
= 0x0F | OPC_CP3
,
974 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
975 OPC_MADD_S
= 0x20 | OPC_CP3
,
976 OPC_MADD_D
= 0x21 | OPC_CP3
,
977 OPC_MADD_PS
= 0x26 | OPC_CP3
,
978 OPC_MSUB_S
= 0x28 | OPC_CP3
,
979 OPC_MSUB_D
= 0x29 | OPC_CP3
,
980 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
981 OPC_NMADD_S
= 0x30 | OPC_CP3
,
982 OPC_NMADD_D
= 0x31 | OPC_CP3
,
983 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
984 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
985 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
986 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
989 /* global register indices */
990 static TCGv_ptr cpu_env
;
991 static TCGv cpu_gpr
[32], cpu_PC
;
992 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
993 static TCGv cpu_dspctrl
, btarget
, bcond
;
994 static TCGv_i32 hflags
;
995 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
996 static TCGv_i64 fpu_f64
[32];
998 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1000 #include "gen-icount.h"
1002 #define gen_helper_0e0i(name, arg) do { \
1003 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1004 gen_helper_##name(cpu_env, helper_tmp); \
1005 tcg_temp_free_i32(helper_tmp); \
1008 #define gen_helper_0e1i(name, arg1, arg2) do { \
1009 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1010 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1011 tcg_temp_free_i32(helper_tmp); \
1014 #define gen_helper_1e0i(name, ret, arg1) do { \
1015 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1016 gen_helper_##name(ret, cpu_env, helper_tmp); \
1017 tcg_temp_free_i32(helper_tmp); \
1020 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1021 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1022 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1023 tcg_temp_free_i32(helper_tmp); \
1026 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1027 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1028 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1029 tcg_temp_free_i32(helper_tmp); \
1032 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1033 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1034 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1035 tcg_temp_free_i32(helper_tmp); \
1038 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1039 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1040 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1041 tcg_temp_free_i32(helper_tmp); \
1044 typedef struct DisasContext
{
1045 struct TranslationBlock
*tb
;
1046 target_ulong pc
, saved_pc
;
1048 int singlestep_enabled
;
1049 /* Routine used to access memory */
1051 uint32_t hflags
, saved_hflags
;
1053 target_ulong btarget
;
1057 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1058 * exception condition */
1059 BS_STOP
= 1, /* We want to stop translation for any reason */
1060 BS_BRANCH
= 2, /* We reached a branch condition */
1061 BS_EXCP
= 3, /* We reached an exception condition */
1064 static const char * const regnames
[] = {
1065 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1066 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1067 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1068 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1071 static const char * const regnames_HI
[] = {
1072 "HI0", "HI1", "HI2", "HI3",
1075 static const char * const regnames_LO
[] = {
1076 "LO0", "LO1", "LO2", "LO3",
1079 static const char * const regnames_ACX
[] = {
1080 "ACX0", "ACX1", "ACX2", "ACX3",
1083 static const char * const fregnames
[] = {
1084 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1085 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1086 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1087 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1090 #define MIPS_DEBUG(fmt, ...) \
1092 if (MIPS_DEBUG_DISAS) { \
1093 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1094 TARGET_FMT_lx ": %08x " fmt "\n", \
1095 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1099 #define LOG_DISAS(...) \
1101 if (MIPS_DEBUG_DISAS) { \
1102 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1106 #define MIPS_INVAL(op) \
1107 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1108 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1110 /* General purpose registers moves. */
1111 static inline void gen_load_gpr (TCGv t
, int reg
)
1114 tcg_gen_movi_tl(t
, 0);
1116 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1119 static inline void gen_store_gpr (TCGv t
, int reg
)
1122 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1125 /* Moves to/from ACX register. */
1126 static inline void gen_load_ACX (TCGv t
, int reg
)
1128 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1131 static inline void gen_store_ACX (TCGv t
, int reg
)
1133 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1136 /* Moves to/from shadow registers. */
1137 static inline void gen_load_srsgpr (int from
, int to
)
1139 TCGv t0
= tcg_temp_new();
1142 tcg_gen_movi_tl(t0
, 0);
1144 TCGv_i32 t2
= tcg_temp_new_i32();
1145 TCGv_ptr addr
= tcg_temp_new_ptr();
1147 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1148 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1149 tcg_gen_andi_i32(t2
, t2
, 0xf);
1150 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1151 tcg_gen_ext_i32_ptr(addr
, t2
);
1152 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1154 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1155 tcg_temp_free_ptr(addr
);
1156 tcg_temp_free_i32(t2
);
1158 gen_store_gpr(t0
, to
);
1162 static inline void gen_store_srsgpr (int from
, int to
)
1165 TCGv t0
= tcg_temp_new();
1166 TCGv_i32 t2
= tcg_temp_new_i32();
1167 TCGv_ptr addr
= tcg_temp_new_ptr();
1169 gen_load_gpr(t0
, from
);
1170 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1171 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1172 tcg_gen_andi_i32(t2
, t2
, 0xf);
1173 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1174 tcg_gen_ext_i32_ptr(addr
, t2
);
1175 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1177 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1178 tcg_temp_free_ptr(addr
);
1179 tcg_temp_free_i32(t2
);
1184 /* Floating point register moves. */
1185 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1187 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1190 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1192 TCGv_i64 t64
= tcg_temp_new_i64();
1193 tcg_gen_extu_i32_i64(t64
, t
);
1194 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1195 tcg_temp_free_i64(t64
);
1198 static void gen_load_fpr32h(TCGv_i32 t
, int reg
)
1200 TCGv_i64 t64
= tcg_temp_new_i64();
1201 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1202 tcg_gen_trunc_i64_i32(t
, t64
);
1203 tcg_temp_free_i64(t64
);
1206 static void gen_store_fpr32h(TCGv_i32 t
, int reg
)
1208 TCGv_i64 t64
= tcg_temp_new_i64();
1209 tcg_gen_extu_i32_i64(t64
, t
);
1210 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1211 tcg_temp_free_i64(t64
);
1214 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1216 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1217 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1219 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1223 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1225 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1226 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1229 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1230 t0
= tcg_temp_new_i64();
1231 tcg_gen_shri_i64(t0
, t
, 32);
1232 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1233 tcg_temp_free_i64(t0
);
1237 static inline int get_fp_bit (int cc
)
1246 static inline void gen_save_pc(target_ulong pc
)
1248 tcg_gen_movi_tl(cpu_PC
, pc
);
1251 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1253 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1254 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1255 gen_save_pc(ctx
->pc
);
1256 ctx
->saved_pc
= ctx
->pc
;
1258 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1259 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1260 ctx
->saved_hflags
= ctx
->hflags
;
1261 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1267 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1273 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1275 ctx
->saved_hflags
= ctx
->hflags
;
1276 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1282 ctx
->btarget
= env
->btarget
;
1288 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1290 TCGv_i32 texcp
= tcg_const_i32(excp
);
1291 TCGv_i32 terr
= tcg_const_i32(err
);
1292 save_cpu_state(ctx
, 1);
1293 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1294 tcg_temp_free_i32(terr
);
1295 tcg_temp_free_i32(texcp
);
1299 generate_exception (DisasContext
*ctx
, int excp
)
1301 save_cpu_state(ctx
, 1);
1302 gen_helper_0e0i(raise_exception
, excp
);
1305 /* Addresses computation */
1306 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1308 tcg_gen_add_tl(ret
, arg0
, arg1
);
1310 #if defined(TARGET_MIPS64)
1311 /* For compatibility with 32-bit code, data reference in user mode
1312 with Status_UX = 0 should be casted to 32-bit and sign extended.
1313 See the MIPS64 PRA manual, section 4.10. */
1314 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1315 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1316 tcg_gen_ext32s_i64(ret
, ret
);
1321 static inline void check_cp0_enabled(DisasContext
*ctx
)
1323 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1324 generate_exception_err(ctx
, EXCP_CpU
, 0);
1327 static inline void check_cp1_enabled(DisasContext
*ctx
)
1329 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1330 generate_exception_err(ctx
, EXCP_CpU
, 1);
1333 /* Verify that the processor is running with COP1X instructions enabled.
1334 This is associated with the nabla symbol in the MIPS32 and MIPS64
1337 static inline void check_cop1x(DisasContext
*ctx
)
1339 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1340 generate_exception(ctx
, EXCP_RI
);
1343 /* Verify that the processor is running with 64-bit floating-point
1344 operations enabled. */
1346 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1348 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1349 generate_exception(ctx
, EXCP_RI
);
1353 * Verify if floating point register is valid; an operation is not defined
1354 * if bit 0 of any register specification is set and the FR bit in the
1355 * Status register equals zero, since the register numbers specify an
1356 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1357 * in the Status register equals one, both even and odd register numbers
1358 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1360 * Multiple 64 bit wide registers can be checked by calling
1361 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1363 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1365 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1366 generate_exception(ctx
, EXCP_RI
);
1369 /* Verify that the processor is running with DSP instructions enabled.
1370 This is enabled by CP0 Status register MX(24) bit.
1373 static inline void check_dsp(DisasContext
*ctx
)
1375 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1376 generate_exception(ctx
, EXCP_DSPDIS
);
1380 static inline void check_dspr2(DisasContext
*ctx
)
1382 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1383 generate_exception(ctx
, EXCP_DSPDIS
);
1387 /* This code generates a "reserved instruction" exception if the
1388 CPU does not support the instruction set corresponding to flags. */
1389 static inline void check_insn(CPUMIPSState
*env
, DisasContext
*ctx
, int flags
)
1391 if (unlikely(!(env
->insn_flags
& flags
)))
1392 generate_exception(ctx
, EXCP_RI
);
1395 /* This code generates a "reserved instruction" exception if 64-bit
1396 instructions are not enabled. */
1397 static inline void check_mips_64(DisasContext
*ctx
)
1399 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1400 generate_exception(ctx
, EXCP_RI
);
1403 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1404 calling interface for 32 and 64-bit FPRs. No sense in changing
1405 all callers for gen_load_fpr32 when we need the CTX parameter for
1407 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1408 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1409 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1410 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1411 int ft, int fs, int cc) \
1413 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1414 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1417 check_cp1_64bitmode(ctx); \
1423 check_cp1_registers(ctx, fs | ft); \
1431 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1432 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1434 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1435 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1436 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1437 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1438 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1439 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1440 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1441 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1442 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1443 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1444 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1445 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1446 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1447 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1448 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1449 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1452 tcg_temp_free_i##bits (fp0); \
1453 tcg_temp_free_i##bits (fp1); \
1456 FOP_CONDS(, 0, d
, FMT_D
, 64)
1457 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1458 FOP_CONDS(, 0, s
, FMT_S
, 32)
1459 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1460 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1461 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1463 #undef gen_ldcmp_fpr32
1464 #undef gen_ldcmp_fpr64
1466 /* load/store instructions. */
1467 #define OP_LD(insn,fname) \
1468 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1470 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1477 #if defined(TARGET_MIPS64)
1483 #define OP_ST(insn,fname) \
1484 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1486 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1491 #if defined(TARGET_MIPS64)
1496 #ifdef CONFIG_USER_ONLY
1497 #define OP_LD_ATOMIC(insn,fname) \
1498 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1500 TCGv t0 = tcg_temp_new(); \
1501 tcg_gen_mov_tl(t0, arg1); \
1502 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1503 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1504 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1505 tcg_temp_free(t0); \
1508 #define OP_LD_ATOMIC(insn,fname) \
1509 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1511 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1514 OP_LD_ATOMIC(ll
,ld32s
);
1515 #if defined(TARGET_MIPS64)
1516 OP_LD_ATOMIC(lld
,ld64
);
1520 #ifdef CONFIG_USER_ONLY
1521 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1522 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1524 TCGv t0 = tcg_temp_new(); \
1525 int l1 = gen_new_label(); \
1526 int l2 = gen_new_label(); \
1528 tcg_gen_andi_tl(t0, arg2, almask); \
1529 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1530 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1531 generate_exception(ctx, EXCP_AdES); \
1532 gen_set_label(l1); \
1533 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1534 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1535 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1536 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1537 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1538 gen_helper_0e0i(raise_exception, EXCP_SC); \
1539 gen_set_label(l2); \
1540 tcg_gen_movi_tl(t0, 0); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1546 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1548 TCGv t0 = tcg_temp_new(); \
1549 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1550 gen_store_gpr(t0, rt); \
1551 tcg_temp_free(t0); \
1554 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1555 #if defined(TARGET_MIPS64)
1556 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1560 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1561 int base
, int16_t offset
)
1564 tcg_gen_movi_tl(addr
, offset
);
1565 } else if (offset
== 0) {
1566 gen_load_gpr(addr
, base
);
1568 tcg_gen_movi_tl(addr
, offset
);
1569 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1573 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1575 target_ulong pc
= ctx
->pc
;
1577 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1578 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1583 pc
&= ~(target_ulong
)3;
1588 static void gen_ld (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
1589 int rt
, int base
, int16_t offset
)
1591 const char *opn
= "ld";
1594 if (rt
== 0 && env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1595 /* Loongson CPU uses a load to zero register for prefetch.
1596 We emulate it as a NOP. On other CPU we must perform the
1597 actual memory access. */
1602 t0
= tcg_temp_new();
1603 t1
= tcg_temp_new();
1604 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1607 #if defined(TARGET_MIPS64)
1609 save_cpu_state(ctx
, 0);
1610 op_ld_lwu(t0
, t0
, ctx
);
1611 gen_store_gpr(t0
, rt
);
1615 save_cpu_state(ctx
, 0);
1616 op_ld_ld(t0
, t0
, ctx
);
1617 gen_store_gpr(t0
, rt
);
1621 save_cpu_state(ctx
, 1);
1622 op_ld_lld(t0
, t0
, ctx
);
1623 gen_store_gpr(t0
, rt
);
1627 save_cpu_state(ctx
, 1);
1628 gen_load_gpr(t1
, rt
);
1629 gen_helper_1e2i(ldl
, t1
, t1
, t0
, ctx
->mem_idx
);
1630 gen_store_gpr(t1
, rt
);
1634 save_cpu_state(ctx
, 1);
1635 gen_load_gpr(t1
, rt
);
1636 gen_helper_1e2i(ldr
, t1
, t1
, t0
, ctx
->mem_idx
);
1637 gen_store_gpr(t1
, rt
);
1641 save_cpu_state(ctx
, 0);
1642 tcg_gen_movi_tl(t1
, pc_relative_pc(ctx
));
1643 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1644 op_ld_ld(t0
, t0
, ctx
);
1645 gen_store_gpr(t0
, rt
);
1650 save_cpu_state(ctx
, 0);
1651 tcg_gen_movi_tl(t1
, pc_relative_pc(ctx
));
1652 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1653 op_ld_lw(t0
, t0
, ctx
);
1654 gen_store_gpr(t0
, rt
);
1658 save_cpu_state(ctx
, 0);
1659 op_ld_lw(t0
, t0
, ctx
);
1660 gen_store_gpr(t0
, rt
);
1664 save_cpu_state(ctx
, 0);
1665 op_ld_lh(t0
, t0
, ctx
);
1666 gen_store_gpr(t0
, rt
);
1670 save_cpu_state(ctx
, 0);
1671 op_ld_lhu(t0
, t0
, ctx
);
1672 gen_store_gpr(t0
, rt
);
1676 save_cpu_state(ctx
, 0);
1677 op_ld_lb(t0
, t0
, ctx
);
1678 gen_store_gpr(t0
, rt
);
1682 save_cpu_state(ctx
, 0);
1683 op_ld_lbu(t0
, t0
, ctx
);
1684 gen_store_gpr(t0
, rt
);
1688 save_cpu_state(ctx
, 1);
1689 gen_load_gpr(t1
, rt
);
1690 gen_helper_1e2i(lwl
, t1
, t1
, t0
, ctx
->mem_idx
);
1691 gen_store_gpr(t1
, rt
);
1695 save_cpu_state(ctx
, 1);
1696 gen_load_gpr(t1
, rt
);
1697 gen_helper_1e2i(lwr
, t1
, t1
, t0
, ctx
->mem_idx
);
1698 gen_store_gpr(t1
, rt
);
1702 save_cpu_state(ctx
, 1);
1703 op_ld_ll(t0
, t0
, ctx
);
1704 gen_store_gpr(t0
, rt
);
1708 (void)opn
; /* avoid a compiler warning */
1709 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1715 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1716 int base
, int16_t offset
)
1718 const char *opn
= "st";
1719 TCGv t0
= tcg_temp_new();
1720 TCGv t1
= tcg_temp_new();
1722 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1723 gen_load_gpr(t1
, rt
);
1725 #if defined(TARGET_MIPS64)
1727 save_cpu_state(ctx
, 0);
1728 op_st_sd(t1
, t0
, ctx
);
1732 save_cpu_state(ctx
, 1);
1733 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1737 save_cpu_state(ctx
, 1);
1738 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1743 save_cpu_state(ctx
, 0);
1744 op_st_sw(t1
, t0
, ctx
);
1748 save_cpu_state(ctx
, 0);
1749 op_st_sh(t1
, t0
, ctx
);
1753 save_cpu_state(ctx
, 0);
1754 op_st_sb(t1
, t0
, ctx
);
1758 save_cpu_state(ctx
, 1);
1759 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1763 save_cpu_state(ctx
, 1);
1764 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1768 (void)opn
; /* avoid a compiler warning */
1769 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1775 /* Store conditional */
1776 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1777 int base
, int16_t offset
)
1779 const char *opn
= "st_cond";
1782 t0
= tcg_temp_local_new();
1784 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1785 /* Don't do NOP if destination is zero: we must perform the actual
1788 t1
= tcg_temp_local_new();
1789 gen_load_gpr(t1
, rt
);
1791 #if defined(TARGET_MIPS64)
1793 save_cpu_state(ctx
, 1);
1794 op_st_scd(t1
, t0
, rt
, ctx
);
1799 save_cpu_state(ctx
, 1);
1800 op_st_sc(t1
, t0
, rt
, ctx
);
1804 (void)opn
; /* avoid a compiler warning */
1805 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1810 /* Load and store */
1811 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1812 int base
, int16_t offset
)
1814 const char *opn
= "flt_ldst";
1815 TCGv t0
= tcg_temp_new();
1817 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1818 /* Don't do NOP if destination is zero: we must perform the actual
1823 TCGv_i32 fp0
= tcg_temp_new_i32();
1825 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1826 tcg_gen_trunc_tl_i32(fp0
, t0
);
1827 gen_store_fpr32(fp0
, ft
);
1828 tcg_temp_free_i32(fp0
);
1834 TCGv_i32 fp0
= tcg_temp_new_i32();
1835 TCGv t1
= tcg_temp_new();
1837 gen_load_fpr32(fp0
, ft
);
1838 tcg_gen_extu_i32_tl(t1
, fp0
);
1839 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1841 tcg_temp_free_i32(fp0
);
1847 TCGv_i64 fp0
= tcg_temp_new_i64();
1849 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
1850 gen_store_fpr64(ctx
, fp0
, ft
);
1851 tcg_temp_free_i64(fp0
);
1857 TCGv_i64 fp0
= tcg_temp_new_i64();
1859 gen_load_fpr64(ctx
, fp0
, ft
);
1860 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
1861 tcg_temp_free_i64(fp0
);
1867 generate_exception(ctx
, EXCP_RI
);
1870 (void)opn
; /* avoid a compiler warning */
1871 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1876 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1877 uint32_t op
, int rt
, int rs
, int16_t imm
)
1879 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1880 check_cp1_enabled(ctx
);
1881 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1883 generate_exception_err(ctx
, EXCP_CpU
, 1);
1887 /* Arithmetic with immediate operand */
1888 static void gen_arith_imm (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
1889 int rt
, int rs
, int16_t imm
)
1891 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1892 const char *opn
= "imm arith";
1894 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1895 /* If no destination, treat it as a NOP.
1896 For addi, we must generate the overflow exception when needed. */
1903 TCGv t0
= tcg_temp_local_new();
1904 TCGv t1
= tcg_temp_new();
1905 TCGv t2
= tcg_temp_new();
1906 int l1
= gen_new_label();
1908 gen_load_gpr(t1
, rs
);
1909 tcg_gen_addi_tl(t0
, t1
, uimm
);
1910 tcg_gen_ext32s_tl(t0
, t0
);
1912 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1913 tcg_gen_xori_tl(t2
, t0
, uimm
);
1914 tcg_gen_and_tl(t1
, t1
, t2
);
1916 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1918 /* operands of same sign, result different sign */
1919 generate_exception(ctx
, EXCP_OVERFLOW
);
1921 tcg_gen_ext32s_tl(t0
, t0
);
1922 gen_store_gpr(t0
, rt
);
1929 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1930 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1932 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1936 #if defined(TARGET_MIPS64)
1939 TCGv t0
= tcg_temp_local_new();
1940 TCGv t1
= tcg_temp_new();
1941 TCGv t2
= tcg_temp_new();
1942 int l1
= gen_new_label();
1944 gen_load_gpr(t1
, rs
);
1945 tcg_gen_addi_tl(t0
, t1
, uimm
);
1947 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1948 tcg_gen_xori_tl(t2
, t0
, uimm
);
1949 tcg_gen_and_tl(t1
, t1
, t2
);
1951 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1953 /* operands of same sign, result different sign */
1954 generate_exception(ctx
, EXCP_OVERFLOW
);
1956 gen_store_gpr(t0
, rt
);
1963 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1965 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1971 (void)opn
; /* avoid a compiler warning */
1972 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
1975 /* Logic with immediate operand */
1976 static void gen_logic_imm(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
1977 int rt
, int rs
, int16_t imm
)
1980 const char *opn
= "imm logic";
1983 /* If no destination, treat it as a NOP. */
1987 uimm
= (uint16_t)imm
;
1990 if (likely(rs
!= 0))
1991 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1993 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
1998 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2000 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2004 if (likely(rs
!= 0))
2005 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2007 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2011 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2015 (void)opn
; /* avoid a compiler warning */
2016 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2019 /* Set on less than with immediate operand */
2020 static void gen_slt_imm(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2021 int rt
, int rs
, int16_t imm
)
2023 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2024 const char *opn
= "imm arith";
2028 /* If no destination, treat it as a NOP. */
2032 t0
= tcg_temp_new();
2033 gen_load_gpr(t0
, rs
);
2036 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2040 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2044 (void)opn
; /* avoid a compiler warning */
2045 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2049 /* Shifts with immediate operand */
2050 static void gen_shift_imm(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2051 int rt
, int rs
, int16_t imm
)
2053 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2054 const char *opn
= "imm shift";
2058 /* If no destination, treat it as a NOP. */
2063 t0
= tcg_temp_new();
2064 gen_load_gpr(t0
, rs
);
2067 tcg_gen_shli_tl(t0
, t0
, uimm
);
2068 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2072 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2077 tcg_gen_ext32u_tl(t0
, t0
);
2078 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2080 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2086 TCGv_i32 t1
= tcg_temp_new_i32();
2088 tcg_gen_trunc_tl_i32(t1
, t0
);
2089 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2090 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2091 tcg_temp_free_i32(t1
);
2093 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2097 #if defined(TARGET_MIPS64)
2099 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2103 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2107 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2112 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2114 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2119 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2123 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2127 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2131 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2136 (void)opn
; /* avoid a compiler warning */
2137 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2142 static void gen_arith (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2143 int rd
, int rs
, int rt
)
2145 const char *opn
= "arith";
2147 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2148 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2149 /* If no destination, treat it as a NOP.
2150 For add & sub, we must generate the overflow exception when needed. */
2158 TCGv t0
= tcg_temp_local_new();
2159 TCGv t1
= tcg_temp_new();
2160 TCGv t2
= tcg_temp_new();
2161 int l1
= gen_new_label();
2163 gen_load_gpr(t1
, rs
);
2164 gen_load_gpr(t2
, rt
);
2165 tcg_gen_add_tl(t0
, t1
, t2
);
2166 tcg_gen_ext32s_tl(t0
, t0
);
2167 tcg_gen_xor_tl(t1
, t1
, t2
);
2168 tcg_gen_xor_tl(t2
, t0
, t2
);
2169 tcg_gen_andc_tl(t1
, t2
, t1
);
2171 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2173 /* operands of same sign, result different sign */
2174 generate_exception(ctx
, EXCP_OVERFLOW
);
2176 gen_store_gpr(t0
, rd
);
2182 if (rs
!= 0 && rt
!= 0) {
2183 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2184 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2185 } else if (rs
== 0 && rt
!= 0) {
2186 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2187 } else if (rs
!= 0 && rt
== 0) {
2188 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2190 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2196 TCGv t0
= tcg_temp_local_new();
2197 TCGv t1
= tcg_temp_new();
2198 TCGv t2
= tcg_temp_new();
2199 int l1
= gen_new_label();
2201 gen_load_gpr(t1
, rs
);
2202 gen_load_gpr(t2
, rt
);
2203 tcg_gen_sub_tl(t0
, t1
, t2
);
2204 tcg_gen_ext32s_tl(t0
, t0
);
2205 tcg_gen_xor_tl(t2
, t1
, t2
);
2206 tcg_gen_xor_tl(t1
, t0
, t1
);
2207 tcg_gen_and_tl(t1
, t1
, t2
);
2209 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2211 /* operands of different sign, first operand and result different sign */
2212 generate_exception(ctx
, EXCP_OVERFLOW
);
2214 gen_store_gpr(t0
, rd
);
2220 if (rs
!= 0 && rt
!= 0) {
2221 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2222 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2223 } else if (rs
== 0 && rt
!= 0) {
2224 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2225 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2226 } else if (rs
!= 0 && rt
== 0) {
2227 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2229 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2233 #if defined(TARGET_MIPS64)
2236 TCGv t0
= tcg_temp_local_new();
2237 TCGv t1
= tcg_temp_new();
2238 TCGv t2
= tcg_temp_new();
2239 int l1
= gen_new_label();
2241 gen_load_gpr(t1
, rs
);
2242 gen_load_gpr(t2
, rt
);
2243 tcg_gen_add_tl(t0
, t1
, t2
);
2244 tcg_gen_xor_tl(t1
, t1
, t2
);
2245 tcg_gen_xor_tl(t2
, t0
, t2
);
2246 tcg_gen_andc_tl(t1
, t2
, t1
);
2248 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2250 /* operands of same sign, result different sign */
2251 generate_exception(ctx
, EXCP_OVERFLOW
);
2253 gen_store_gpr(t0
, rd
);
2259 if (rs
!= 0 && rt
!= 0) {
2260 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2261 } else if (rs
== 0 && rt
!= 0) {
2262 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2263 } else if (rs
!= 0 && rt
== 0) {
2264 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2266 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2272 TCGv t0
= tcg_temp_local_new();
2273 TCGv t1
= tcg_temp_new();
2274 TCGv t2
= tcg_temp_new();
2275 int l1
= gen_new_label();
2277 gen_load_gpr(t1
, rs
);
2278 gen_load_gpr(t2
, rt
);
2279 tcg_gen_sub_tl(t0
, t1
, t2
);
2280 tcg_gen_xor_tl(t2
, t1
, t2
);
2281 tcg_gen_xor_tl(t1
, t0
, t1
);
2282 tcg_gen_and_tl(t1
, t1
, t2
);
2284 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2286 /* operands of different sign, first operand and result different sign */
2287 generate_exception(ctx
, EXCP_OVERFLOW
);
2289 gen_store_gpr(t0
, rd
);
2295 if (rs
!= 0 && rt
!= 0) {
2296 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2297 } else if (rs
== 0 && rt
!= 0) {
2298 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2299 } else if (rs
!= 0 && rt
== 0) {
2300 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2302 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2308 if (likely(rs
!= 0 && rt
!= 0)) {
2309 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2310 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2312 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2317 (void)opn
; /* avoid a compiler warning */
2318 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2321 /* Conditional move */
2322 static void gen_cond_move(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2323 int rd
, int rs
, int rt
)
2325 const char *opn
= "cond move";
2329 /* If no destination, treat it as a NOP.
2330 For add & sub, we must generate the overflow exception when needed. */
2335 l1
= gen_new_label();
2338 if (likely(rt
!= 0))
2339 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[rt
], 0, l1
);
2345 if (likely(rt
!= 0))
2346 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[rt
], 0, l1
);
2351 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2353 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2356 (void)opn
; /* avoid a compiler warning */
2357 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2361 static void gen_logic(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2362 int rd
, int rs
, int rt
)
2364 const char *opn
= "logic";
2367 /* If no destination, treat it as a NOP. */
2374 if (likely(rs
!= 0 && rt
!= 0)) {
2375 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2377 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2382 if (rs
!= 0 && rt
!= 0) {
2383 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2384 } else if (rs
== 0 && rt
!= 0) {
2385 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2386 } else if (rs
!= 0 && rt
== 0) {
2387 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2389 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2394 if (likely(rs
!= 0 && rt
!= 0)) {
2395 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2396 } else if (rs
== 0 && rt
!= 0) {
2397 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2398 } else if (rs
!= 0 && rt
== 0) {
2399 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2401 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2406 if (likely(rs
!= 0 && rt
!= 0)) {
2407 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2408 } else if (rs
== 0 && rt
!= 0) {
2409 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2410 } else if (rs
!= 0 && rt
== 0) {
2411 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2413 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2418 (void)opn
; /* avoid a compiler warning */
2419 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2422 /* Set on lower than */
2423 static void gen_slt(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2424 int rd
, int rs
, int rt
)
2426 const char *opn
= "slt";
2430 /* If no destination, treat it as a NOP. */
2435 t0
= tcg_temp_new();
2436 t1
= tcg_temp_new();
2437 gen_load_gpr(t0
, rs
);
2438 gen_load_gpr(t1
, rt
);
2441 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2445 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2449 (void)opn
; /* avoid a compiler warning */
2450 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2456 static void gen_shift (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
2457 int rd
, int rs
, int rt
)
2459 const char *opn
= "shifts";
2463 /* If no destination, treat it as a NOP.
2464 For add & sub, we must generate the overflow exception when needed. */
2469 t0
= tcg_temp_new();
2470 t1
= tcg_temp_new();
2471 gen_load_gpr(t0
, rs
);
2472 gen_load_gpr(t1
, rt
);
2475 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2476 tcg_gen_shl_tl(t0
, t1
, t0
);
2477 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2481 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2482 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2486 tcg_gen_ext32u_tl(t1
, t1
);
2487 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2488 tcg_gen_shr_tl(t0
, t1
, t0
);
2489 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2494 TCGv_i32 t2
= tcg_temp_new_i32();
2495 TCGv_i32 t3
= tcg_temp_new_i32();
2497 tcg_gen_trunc_tl_i32(t2
, t0
);
2498 tcg_gen_trunc_tl_i32(t3
, t1
);
2499 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2500 tcg_gen_rotr_i32(t2
, t3
, t2
);
2501 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2502 tcg_temp_free_i32(t2
);
2503 tcg_temp_free_i32(t3
);
2507 #if defined(TARGET_MIPS64)
2509 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2510 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2514 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2515 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2519 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2520 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2524 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2525 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2530 (void)opn
; /* avoid a compiler warning */
2531 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2536 /* Arithmetic on HI/LO registers */
2537 static void gen_HILO (DisasContext
*ctx
, uint32_t opc
, int reg
)
2539 const char *opn
= "hilo";
2542 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2548 if (opc
== OPC_MFHI
|| opc
== OPC_MFLO
) {
2549 acc
= ((ctx
->opcode
) >> 21) & 0x03;
2551 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2560 #if defined(TARGET_MIPS64)
2562 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2566 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2571 #if defined(TARGET_MIPS64)
2573 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2577 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2583 #if defined(TARGET_MIPS64)
2585 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2589 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2592 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2598 #if defined(TARGET_MIPS64)
2600 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2604 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2607 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2612 (void)opn
; /* avoid a compiler warning */
2613 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2616 static void gen_muldiv (DisasContext
*ctx
, uint32_t opc
,
2619 const char *opn
= "mul/div";
2626 #if defined(TARGET_MIPS64)
2630 t0
= tcg_temp_local_new();
2631 t1
= tcg_temp_local_new();
2634 t0
= tcg_temp_new();
2635 t1
= tcg_temp_new();
2639 gen_load_gpr(t0
, rs
);
2640 gen_load_gpr(t1
, rt
);
2644 int l1
= gen_new_label();
2645 int l2
= gen_new_label();
2647 tcg_gen_ext32s_tl(t0
, t0
);
2648 tcg_gen_ext32s_tl(t1
, t1
);
2649 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
2650 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
2651 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
2653 tcg_gen_mov_tl(cpu_LO
[0], t0
);
2654 tcg_gen_movi_tl(cpu_HI
[0], 0);
2657 tcg_gen_div_tl(cpu_LO
[0], t0
, t1
);
2658 tcg_gen_rem_tl(cpu_HI
[0], t0
, t1
);
2659 tcg_gen_ext32s_tl(cpu_LO
[0], cpu_LO
[0]);
2660 tcg_gen_ext32s_tl(cpu_HI
[0], cpu_HI
[0]);
2667 int l1
= gen_new_label();
2669 tcg_gen_ext32u_tl(t0
, t0
);
2670 tcg_gen_ext32u_tl(t1
, t1
);
2671 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
2672 tcg_gen_divu_tl(cpu_LO
[0], t0
, t1
);
2673 tcg_gen_remu_tl(cpu_HI
[0], t0
, t1
);
2674 tcg_gen_ext32s_tl(cpu_LO
[0], cpu_LO
[0]);
2675 tcg_gen_ext32s_tl(cpu_HI
[0], cpu_HI
[0]);
2682 TCGv_i64 t2
= tcg_temp_new_i64();
2683 TCGv_i64 t3
= tcg_temp_new_i64();
2684 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2689 tcg_gen_ext_tl_i64(t2
, t0
);
2690 tcg_gen_ext_tl_i64(t3
, t1
);
2691 tcg_gen_mul_i64(t2
, t2
, t3
);
2692 tcg_temp_free_i64(t3
);
2693 tcg_gen_trunc_i64_tl(t0
, t2
);
2694 tcg_gen_shri_i64(t2
, t2
, 32);
2695 tcg_gen_trunc_i64_tl(t1
, t2
);
2696 tcg_temp_free_i64(t2
);
2697 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2698 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2704 TCGv_i64 t2
= tcg_temp_new_i64();
2705 TCGv_i64 t3
= tcg_temp_new_i64();
2706 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2711 tcg_gen_ext32u_tl(t0
, t0
);
2712 tcg_gen_ext32u_tl(t1
, t1
);
2713 tcg_gen_extu_tl_i64(t2
, t0
);
2714 tcg_gen_extu_tl_i64(t3
, t1
);
2715 tcg_gen_mul_i64(t2
, t2
, t3
);
2716 tcg_temp_free_i64(t3
);
2717 tcg_gen_trunc_i64_tl(t0
, t2
);
2718 tcg_gen_shri_i64(t2
, t2
, 32);
2719 tcg_gen_trunc_i64_tl(t1
, t2
);
2720 tcg_temp_free_i64(t2
);
2721 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2722 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2726 #if defined(TARGET_MIPS64)
2729 int l1
= gen_new_label();
2730 int l2
= gen_new_label();
2732 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
2733 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
2734 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
2735 tcg_gen_mov_tl(cpu_LO
[0], t0
);
2736 tcg_gen_movi_tl(cpu_HI
[0], 0);
2739 tcg_gen_div_i64(cpu_LO
[0], t0
, t1
);
2740 tcg_gen_rem_i64(cpu_HI
[0], t0
, t1
);
2747 int l1
= gen_new_label();
2749 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
2750 tcg_gen_divu_i64(cpu_LO
[0], t0
, t1
);
2751 tcg_gen_remu_i64(cpu_HI
[0], t0
, t1
);
2757 gen_helper_dmult(cpu_env
, t0
, t1
);
2761 gen_helper_dmultu(cpu_env
, t0
, t1
);
2767 TCGv_i64 t2
= tcg_temp_new_i64();
2768 TCGv_i64 t3
= tcg_temp_new_i64();
2769 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2774 tcg_gen_ext_tl_i64(t2
, t0
);
2775 tcg_gen_ext_tl_i64(t3
, t1
);
2776 tcg_gen_mul_i64(t2
, t2
, t3
);
2777 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2778 tcg_gen_add_i64(t2
, t2
, t3
);
2779 tcg_temp_free_i64(t3
);
2780 tcg_gen_trunc_i64_tl(t0
, t2
);
2781 tcg_gen_shri_i64(t2
, t2
, 32);
2782 tcg_gen_trunc_i64_tl(t1
, t2
);
2783 tcg_temp_free_i64(t2
);
2784 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2785 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2791 TCGv_i64 t2
= tcg_temp_new_i64();
2792 TCGv_i64 t3
= tcg_temp_new_i64();
2793 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2798 tcg_gen_ext32u_tl(t0
, t0
);
2799 tcg_gen_ext32u_tl(t1
, t1
);
2800 tcg_gen_extu_tl_i64(t2
, t0
);
2801 tcg_gen_extu_tl_i64(t3
, t1
);
2802 tcg_gen_mul_i64(t2
, t2
, t3
);
2803 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2804 tcg_gen_add_i64(t2
, t2
, t3
);
2805 tcg_temp_free_i64(t3
);
2806 tcg_gen_trunc_i64_tl(t0
, t2
);
2807 tcg_gen_shri_i64(t2
, t2
, 32);
2808 tcg_gen_trunc_i64_tl(t1
, t2
);
2809 tcg_temp_free_i64(t2
);
2810 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2811 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2817 TCGv_i64 t2
= tcg_temp_new_i64();
2818 TCGv_i64 t3
= tcg_temp_new_i64();
2819 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2824 tcg_gen_ext_tl_i64(t2
, t0
);
2825 tcg_gen_ext_tl_i64(t3
, t1
);
2826 tcg_gen_mul_i64(t2
, t2
, t3
);
2827 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2828 tcg_gen_sub_i64(t2
, t3
, t2
);
2829 tcg_temp_free_i64(t3
);
2830 tcg_gen_trunc_i64_tl(t0
, t2
);
2831 tcg_gen_shri_i64(t2
, t2
, 32);
2832 tcg_gen_trunc_i64_tl(t1
, t2
);
2833 tcg_temp_free_i64(t2
);
2834 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2835 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2841 TCGv_i64 t2
= tcg_temp_new_i64();
2842 TCGv_i64 t3
= tcg_temp_new_i64();
2843 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2848 tcg_gen_ext32u_tl(t0
, t0
);
2849 tcg_gen_ext32u_tl(t1
, t1
);
2850 tcg_gen_extu_tl_i64(t2
, t0
);
2851 tcg_gen_extu_tl_i64(t3
, t1
);
2852 tcg_gen_mul_i64(t2
, t2
, t3
);
2853 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2854 tcg_gen_sub_i64(t2
, t3
, t2
);
2855 tcg_temp_free_i64(t3
);
2856 tcg_gen_trunc_i64_tl(t0
, t2
);
2857 tcg_gen_shri_i64(t2
, t2
, 32);
2858 tcg_gen_trunc_i64_tl(t1
, t2
);
2859 tcg_temp_free_i64(t2
);
2860 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2861 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2867 generate_exception(ctx
, EXCP_RI
);
2870 (void)opn
; /* avoid a compiler warning */
2871 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2877 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2878 int rd
, int rs
, int rt
)
2880 const char *opn
= "mul vr54xx";
2881 TCGv t0
= tcg_temp_new();
2882 TCGv t1
= tcg_temp_new();
2884 gen_load_gpr(t0
, rs
);
2885 gen_load_gpr(t1
, rt
);
2888 case OPC_VR54XX_MULS
:
2889 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2892 case OPC_VR54XX_MULSU
:
2893 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2896 case OPC_VR54XX_MACC
:
2897 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2900 case OPC_VR54XX_MACCU
:
2901 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2904 case OPC_VR54XX_MSAC
:
2905 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2908 case OPC_VR54XX_MSACU
:
2909 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2912 case OPC_VR54XX_MULHI
:
2913 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2916 case OPC_VR54XX_MULHIU
:
2917 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2920 case OPC_VR54XX_MULSHI
:
2921 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2924 case OPC_VR54XX_MULSHIU
:
2925 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2928 case OPC_VR54XX_MACCHI
:
2929 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2932 case OPC_VR54XX_MACCHIU
:
2933 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2936 case OPC_VR54XX_MSACHI
:
2937 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2940 case OPC_VR54XX_MSACHIU
:
2941 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2945 MIPS_INVAL("mul vr54xx");
2946 generate_exception(ctx
, EXCP_RI
);
2949 gen_store_gpr(t0
, rd
);
2950 (void)opn
; /* avoid a compiler warning */
2951 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2958 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2961 const char *opn
= "CLx";
2969 t0
= tcg_temp_new();
2970 gen_load_gpr(t0
, rs
);
2973 gen_helper_clo(cpu_gpr
[rd
], t0
);
2977 gen_helper_clz(cpu_gpr
[rd
], t0
);
2980 #if defined(TARGET_MIPS64)
2982 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2986 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2991 (void)opn
; /* avoid a compiler warning */
2992 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2996 /* Godson integer instructions */
2997 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2998 int rd
, int rs
, int rt
)
3000 const char *opn
= "loongson";
3012 case OPC_MULTU_G_2E
:
3013 case OPC_MULTU_G_2F
:
3014 #if defined(TARGET_MIPS64)
3015 case OPC_DMULT_G_2E
:
3016 case OPC_DMULT_G_2F
:
3017 case OPC_DMULTU_G_2E
:
3018 case OPC_DMULTU_G_2F
:
3020 t0
= tcg_temp_new();
3021 t1
= tcg_temp_new();
3024 t0
= tcg_temp_local_new();
3025 t1
= tcg_temp_local_new();
3029 gen_load_gpr(t0
, rs
);
3030 gen_load_gpr(t1
, rt
);
3035 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3036 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3039 case OPC_MULTU_G_2E
:
3040 case OPC_MULTU_G_2F
:
3041 tcg_gen_ext32u_tl(t0
, t0
);
3042 tcg_gen_ext32u_tl(t1
, t1
);
3043 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3044 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3050 int l1
= gen_new_label();
3051 int l2
= gen_new_label();
3052 int l3
= gen_new_label();
3053 tcg_gen_ext32s_tl(t0
, t0
);
3054 tcg_gen_ext32s_tl(t1
, t1
);
3055 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3056 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3059 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3060 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3061 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3064 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3065 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3073 int l1
= gen_new_label();
3074 int l2
= gen_new_label();
3075 tcg_gen_ext32u_tl(t0
, t0
);
3076 tcg_gen_ext32u_tl(t1
, t1
);
3077 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3078 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3081 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3082 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3090 int l1
= gen_new_label();
3091 int l2
= gen_new_label();
3092 int l3
= gen_new_label();
3093 tcg_gen_ext32u_tl(t0
, t0
);
3094 tcg_gen_ext32u_tl(t1
, t1
);
3095 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3096 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3097 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3099 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3102 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3103 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3111 int l1
= gen_new_label();
3112 int l2
= gen_new_label();
3113 tcg_gen_ext32u_tl(t0
, t0
);
3114 tcg_gen_ext32u_tl(t1
, t1
);
3115 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3116 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3119 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3120 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3125 #if defined(TARGET_MIPS64)
3126 case OPC_DMULT_G_2E
:
3127 case OPC_DMULT_G_2F
:
3128 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3131 case OPC_DMULTU_G_2E
:
3132 case OPC_DMULTU_G_2F
:
3133 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3139 int l1
= gen_new_label();
3140 int l2
= gen_new_label();
3141 int l3
= gen_new_label();
3142 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3143 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3146 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3147 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3148 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3151 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3156 case OPC_DDIVU_G_2E
:
3157 case OPC_DDIVU_G_2F
:
3159 int l1
= gen_new_label();
3160 int l2
= gen_new_label();
3161 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3162 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3165 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3173 int l1
= gen_new_label();
3174 int l2
= gen_new_label();
3175 int l3
= gen_new_label();
3176 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3177 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3178 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3180 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3183 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3188 case OPC_DMODU_G_2E
:
3189 case OPC_DMODU_G_2F
:
3191 int l1
= gen_new_label();
3192 int l2
= gen_new_label();
3193 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3194 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3197 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3205 (void)opn
; /* avoid a compiler warning */
3206 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3211 /* Loongson multimedia instructions */
3212 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3214 const char *opn
= "loongson_cp2";
3215 uint32_t opc
, shift_max
;
3218 opc
= MASK_LMI(ctx
->opcode
);
3224 t0
= tcg_temp_local_new_i64();
3225 t1
= tcg_temp_local_new_i64();
3228 t0
= tcg_temp_new_i64();
3229 t1
= tcg_temp_new_i64();
3233 gen_load_fpr64(ctx
, t0
, rs
);
3234 gen_load_fpr64(ctx
, t1
, rt
);
3236 #define LMI_HELPER(UP, LO) \
3237 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3238 #define LMI_HELPER_1(UP, LO) \
3239 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3240 #define LMI_DIRECT(UP, LO, OP) \
3241 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3244 LMI_HELPER(PADDSH
, paddsh
);
3245 LMI_HELPER(PADDUSH
, paddush
);
3246 LMI_HELPER(PADDH
, paddh
);
3247 LMI_HELPER(PADDW
, paddw
);
3248 LMI_HELPER(PADDSB
, paddsb
);
3249 LMI_HELPER(PADDUSB
, paddusb
);
3250 LMI_HELPER(PADDB
, paddb
);
3252 LMI_HELPER(PSUBSH
, psubsh
);
3253 LMI_HELPER(PSUBUSH
, psubush
);
3254 LMI_HELPER(PSUBH
, psubh
);
3255 LMI_HELPER(PSUBW
, psubw
);
3256 LMI_HELPER(PSUBSB
, psubsb
);
3257 LMI_HELPER(PSUBUSB
, psubusb
);
3258 LMI_HELPER(PSUBB
, psubb
);
3260 LMI_HELPER(PSHUFH
, pshufh
);
3261 LMI_HELPER(PACKSSWH
, packsswh
);
3262 LMI_HELPER(PACKSSHB
, packsshb
);
3263 LMI_HELPER(PACKUSHB
, packushb
);
3265 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3266 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3267 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3268 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3269 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3270 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3272 LMI_HELPER(PAVGH
, pavgh
);
3273 LMI_HELPER(PAVGB
, pavgb
);
3274 LMI_HELPER(PMAXSH
, pmaxsh
);
3275 LMI_HELPER(PMINSH
, pminsh
);
3276 LMI_HELPER(PMAXUB
, pmaxub
);
3277 LMI_HELPER(PMINUB
, pminub
);
3279 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3280 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3281 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3282 LMI_HELPER(PCMPGTH
, pcmpgth
);
3283 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3284 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3286 LMI_HELPER(PSLLW
, psllw
);
3287 LMI_HELPER(PSLLH
, psllh
);
3288 LMI_HELPER(PSRLW
, psrlw
);
3289 LMI_HELPER(PSRLH
, psrlh
);
3290 LMI_HELPER(PSRAW
, psraw
);
3291 LMI_HELPER(PSRAH
, psrah
);
3293 LMI_HELPER(PMULLH
, pmullh
);
3294 LMI_HELPER(PMULHH
, pmulhh
);
3295 LMI_HELPER(PMULHUH
, pmulhuh
);
3296 LMI_HELPER(PMADDHW
, pmaddhw
);
3298 LMI_HELPER(PASUBUB
, pasubub
);
3299 LMI_HELPER_1(BIADD
, biadd
);
3300 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3302 LMI_DIRECT(PADDD
, paddd
, add
);
3303 LMI_DIRECT(PSUBD
, psubd
, sub
);
3304 LMI_DIRECT(XOR_CP2
, xor, xor);
3305 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3306 LMI_DIRECT(AND_CP2
, and, and);
3307 LMI_DIRECT(PANDN
, pandn
, andc
);
3308 LMI_DIRECT(OR
, or, or);
3311 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3315 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3319 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3323 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3328 tcg_gen_andi_i64(t1
, t1
, 3);
3329 tcg_gen_shli_i64(t1
, t1
, 4);
3330 tcg_gen_shr_i64(t0
, t0
, t1
);
3331 tcg_gen_ext16u_i64(t0
, t0
);
3336 tcg_gen_add_i64(t0
, t0
, t1
);
3337 tcg_gen_ext32s_i64(t0
, t0
);
3341 tcg_gen_sub_i64(t0
, t0
, t1
);
3342 tcg_gen_ext32s_i64(t0
, t0
);
3371 /* Make sure shift count isn't TCG undefined behaviour. */
3372 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3377 tcg_gen_shl_i64(t0
, t0
, t1
);
3381 /* Since SRA is UndefinedResult without sign-extended inputs,
3382 we can treat SRA and DSRA the same. */
3383 tcg_gen_sar_i64(t0
, t0
, t1
);
3386 /* We want to shift in zeros for SRL; zero-extend first. */
3387 tcg_gen_ext32u_i64(t0
, t0
);
3390 tcg_gen_shr_i64(t0
, t0
, t1
);
3394 if (shift_max
== 32) {
3395 tcg_gen_ext32s_i64(t0
, t0
);
3398 /* Shifts larger than MAX produce zero. */
3399 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3400 tcg_gen_neg_i64(t1
, t1
);
3401 tcg_gen_and_i64(t0
, t0
, t1
);
3407 TCGv_i64 t2
= tcg_temp_new_i64();
3408 int lab
= gen_new_label();
3410 tcg_gen_mov_i64(t2
, t0
);
3411 tcg_gen_add_i64(t0
, t1
, t2
);
3412 if (opc
== OPC_ADD_CP2
) {
3413 tcg_gen_ext32s_i64(t0
, t0
);
3415 tcg_gen_xor_i64(t1
, t1
, t2
);
3416 tcg_gen_xor_i64(t2
, t2
, t0
);
3417 tcg_gen_andc_i64(t1
, t2
, t1
);
3418 tcg_temp_free_i64(t2
);
3419 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3420 generate_exception(ctx
, EXCP_OVERFLOW
);
3423 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3430 TCGv_i64 t2
= tcg_temp_new_i64();
3431 int lab
= gen_new_label();
3433 tcg_gen_mov_i64(t2
, t0
);
3434 tcg_gen_sub_i64(t0
, t1
, t2
);
3435 if (opc
== OPC_SUB_CP2
) {
3436 tcg_gen_ext32s_i64(t0
, t0
);
3438 tcg_gen_xor_i64(t1
, t1
, t2
);
3439 tcg_gen_xor_i64(t2
, t2
, t0
);
3440 tcg_gen_and_i64(t1
, t1
, t2
);
3441 tcg_temp_free_i64(t2
);
3442 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3443 generate_exception(ctx
, EXCP_OVERFLOW
);
3446 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3451 tcg_gen_ext32u_i64(t0
, t0
);
3452 tcg_gen_ext32u_i64(t1
, t1
);
3453 tcg_gen_mul_i64(t0
, t0
, t1
);
3463 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3464 FD field is the CC field? */
3467 generate_exception(ctx
, EXCP_RI
);
3474 gen_store_fpr64(ctx
, t0
, rd
);
3476 (void)opn
; /* avoid a compiler warning */
3477 MIPS_DEBUG("%s %s, %s, %s", opn
,
3478 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3479 tcg_temp_free_i64(t0
);
3480 tcg_temp_free_i64(t1
);
3484 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3485 int rs
, int rt
, int16_t imm
)
3488 TCGv t0
= tcg_temp_new();
3489 TCGv t1
= tcg_temp_new();
3492 /* Load needed operands */
3500 /* Compare two registers */
3502 gen_load_gpr(t0
, rs
);
3503 gen_load_gpr(t1
, rt
);
3513 /* Compare register to immediate */
3514 if (rs
!= 0 || imm
!= 0) {
3515 gen_load_gpr(t0
, rs
);
3516 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3523 case OPC_TEQ
: /* rs == rs */
3524 case OPC_TEQI
: /* r0 == 0 */
3525 case OPC_TGE
: /* rs >= rs */
3526 case OPC_TGEI
: /* r0 >= 0 */
3527 case OPC_TGEU
: /* rs >= rs unsigned */
3528 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3530 generate_exception(ctx
, EXCP_TRAP
);
3532 case OPC_TLT
: /* rs < rs */
3533 case OPC_TLTI
: /* r0 < 0 */
3534 case OPC_TLTU
: /* rs < rs unsigned */
3535 case OPC_TLTIU
: /* r0 < 0 unsigned */
3536 case OPC_TNE
: /* rs != rs */
3537 case OPC_TNEI
: /* r0 != 0 */
3538 /* Never trap: treat as NOP. */
3542 int l1
= gen_new_label();
3547 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3551 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3555 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3559 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3563 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3567 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3570 generate_exception(ctx
, EXCP_TRAP
);
3577 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3579 TranslationBlock
*tb
;
3581 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3582 likely(!ctx
->singlestep_enabled
)) {
3585 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3588 if (ctx
->singlestep_enabled
) {
3589 save_cpu_state(ctx
, 0);
3590 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3596 /* Branches (before delay slot) */
3597 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3599 int rs
, int rt
, int32_t offset
)
3601 target_ulong btgt
= -1;
3603 int bcond_compute
= 0;
3604 TCGv t0
= tcg_temp_new();
3605 TCGv t1
= tcg_temp_new();
3607 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3608 #ifdef MIPS_DEBUG_DISAS
3609 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3611 generate_exception(ctx
, EXCP_RI
);
3615 /* Load needed operands */
3621 /* Compare two registers */
3623 gen_load_gpr(t0
, rs
);
3624 gen_load_gpr(t1
, rt
);
3627 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3643 /* Compare to zero */
3645 gen_load_gpr(t0
, rs
);
3648 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3651 #if defined(TARGET_MIPS64)
3653 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3655 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3658 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3665 /* Jump to immediate */
3666 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3672 /* Jump to register */
3673 if (offset
!= 0 && offset
!= 16) {
3674 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3675 others are reserved. */
3676 MIPS_INVAL("jump hint");
3677 generate_exception(ctx
, EXCP_RI
);
3680 gen_load_gpr(btarget
, rs
);
3683 MIPS_INVAL("branch/jump");
3684 generate_exception(ctx
, EXCP_RI
);
3687 if (bcond_compute
== 0) {
3688 /* No condition to be computed */
3690 case OPC_BEQ
: /* rx == rx */
3691 case OPC_BEQL
: /* rx == rx likely */
3692 case OPC_BGEZ
: /* 0 >= 0 */
3693 case OPC_BGEZL
: /* 0 >= 0 likely */
3694 case OPC_BLEZ
: /* 0 <= 0 */
3695 case OPC_BLEZL
: /* 0 <= 0 likely */
3697 ctx
->hflags
|= MIPS_HFLAG_B
;
3698 MIPS_DEBUG("balways");
3701 case OPC_BGEZAL
: /* 0 >= 0 */
3702 case OPC_BGEZALL
: /* 0 >= 0 likely */
3703 ctx
->hflags
|= (opc
== OPC_BGEZALS
3705 : MIPS_HFLAG_BDS32
);
3706 /* Always take and link */
3708 ctx
->hflags
|= MIPS_HFLAG_B
;
3709 MIPS_DEBUG("balways and link");
3711 case OPC_BNE
: /* rx != rx */
3712 case OPC_BGTZ
: /* 0 > 0 */
3713 case OPC_BLTZ
: /* 0 < 0 */
3715 MIPS_DEBUG("bnever (NOP)");
3718 case OPC_BLTZAL
: /* 0 < 0 */
3719 ctx
->hflags
|= (opc
== OPC_BLTZALS
3721 : MIPS_HFLAG_BDS32
);
3722 /* Handle as an unconditional branch to get correct delay
3725 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3726 ctx
->hflags
|= MIPS_HFLAG_B
;
3727 MIPS_DEBUG("bnever and link");
3729 case OPC_BLTZALL
: /* 0 < 0 likely */
3730 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3731 /* Skip the instruction in the delay slot */
3732 MIPS_DEBUG("bnever, link and skip");
3735 case OPC_BNEL
: /* rx != rx likely */
3736 case OPC_BGTZL
: /* 0 > 0 likely */
3737 case OPC_BLTZL
: /* 0 < 0 likely */
3738 /* Skip the instruction in the delay slot */
3739 MIPS_DEBUG("bnever and skip");
3743 ctx
->hflags
|= MIPS_HFLAG_B
;
3744 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3748 ctx
->hflags
|= MIPS_HFLAG_BX
;
3753 ctx
->hflags
|= MIPS_HFLAG_B
;
3754 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3756 : MIPS_HFLAG_BDS32
);
3757 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3760 ctx
->hflags
|= MIPS_HFLAG_BR
;
3761 if (insn_bytes
== 4)
3762 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3763 MIPS_DEBUG("jr %s", regnames
[rs
]);
3769 ctx
->hflags
|= MIPS_HFLAG_BR
;
3770 ctx
->hflags
|= (opc
== OPC_JALRS
3772 : MIPS_HFLAG_BDS32
);
3773 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3776 MIPS_INVAL("branch/jump");
3777 generate_exception(ctx
, EXCP_RI
);
3783 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3784 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3785 regnames
[rs
], regnames
[rt
], btgt
);
3788 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3789 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3790 regnames
[rs
], regnames
[rt
], btgt
);
3793 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3794 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3795 regnames
[rs
], regnames
[rt
], btgt
);
3798 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3799 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3800 regnames
[rs
], regnames
[rt
], btgt
);
3803 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3804 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3807 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3808 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3812 ctx
->hflags
|= (opc
== OPC_BGEZALS
3814 : MIPS_HFLAG_BDS32
);
3815 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3816 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3820 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3822 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3825 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3826 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3829 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3830 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3833 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3834 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3837 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3838 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3841 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3842 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3845 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3846 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3849 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3850 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3852 #if defined(TARGET_MIPS64)
3854 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3855 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3860 ctx
->hflags
|= (opc
== OPC_BLTZALS
3862 : MIPS_HFLAG_BDS32
);
3863 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3865 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3867 ctx
->hflags
|= MIPS_HFLAG_BC
;
3870 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3872 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3874 ctx
->hflags
|= MIPS_HFLAG_BL
;
3877 MIPS_INVAL("conditional branch/jump");
3878 generate_exception(ctx
, EXCP_RI
);
3882 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3883 blink
, ctx
->hflags
, btgt
);
3885 ctx
->btarget
= btgt
;
3887 int post_delay
= insn_bytes
;
3888 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3890 if (opc
!= OPC_JALRC
)
3891 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3893 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3897 if (insn_bytes
== 2)
3898 ctx
->hflags
|= MIPS_HFLAG_B16
;
3903 /* special3 bitfield operations */
3904 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3905 int rs
, int lsb
, int msb
)
3907 TCGv t0
= tcg_temp_new();
3908 TCGv t1
= tcg_temp_new();
3911 gen_load_gpr(t1
, rs
);
3916 tcg_gen_shri_tl(t0
, t1
, lsb
);
3918 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3920 tcg_gen_ext32s_tl(t0
, t0
);
3923 #if defined(TARGET_MIPS64)
3925 tcg_gen_shri_tl(t0
, t1
, lsb
);
3927 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3931 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3932 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3935 tcg_gen_shri_tl(t0
, t1
, lsb
);
3936 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3942 mask
= ((msb
- lsb
+ 1 < 32) ? ((1 << (msb
- lsb
+ 1)) - 1) : ~0) << lsb
;
3943 gen_load_gpr(t0
, rt
);
3944 tcg_gen_andi_tl(t0
, t0
, ~mask
);
3945 tcg_gen_shli_tl(t1
, t1
, lsb
);
3946 tcg_gen_andi_tl(t1
, t1
, mask
);
3947 tcg_gen_or_tl(t0
, t0
, t1
);
3948 tcg_gen_ext32s_tl(t0
, t0
);
3950 #if defined(TARGET_MIPS64)
3954 mask
= ((msb
- lsb
+ 1 + 32 < 64) ? ((1ULL << (msb
- lsb
+ 1 + 32)) - 1) : ~0ULL) << lsb
;
3955 gen_load_gpr(t0
, rt
);
3956 tcg_gen_andi_tl(t0
, t0
, ~mask
);
3957 tcg_gen_shli_tl(t1
, t1
, lsb
);
3958 tcg_gen_andi_tl(t1
, t1
, mask
);
3959 tcg_gen_or_tl(t0
, t0
, t1
);
3964 mask
= ((1ULL << (msb
- lsb
+ 1)) - 1) << (lsb
+ 32);
3965 gen_load_gpr(t0
, rt
);
3966 tcg_gen_andi_tl(t0
, t0
, ~mask
);
3967 tcg_gen_shli_tl(t1
, t1
, lsb
+ 32);
3968 tcg_gen_andi_tl(t1
, t1
, mask
);
3969 tcg_gen_or_tl(t0
, t0
, t1
);
3974 gen_load_gpr(t0
, rt
);
3975 mask
= ((1ULL << (msb
- lsb
+ 1)) - 1) << lsb
;
3976 gen_load_gpr(t0
, rt
);
3977 tcg_gen_andi_tl(t0
, t0
, ~mask
);
3978 tcg_gen_shli_tl(t1
, t1
, lsb
);
3979 tcg_gen_andi_tl(t1
, t1
, mask
);
3980 tcg_gen_or_tl(t0
, t0
, t1
);
3985 MIPS_INVAL("bitops");
3986 generate_exception(ctx
, EXCP_RI
);
3991 gen_store_gpr(t0
, rt
);
3996 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4001 /* If no destination, treat it as a NOP. */
4006 t0
= tcg_temp_new();
4007 gen_load_gpr(t0
, rt
);
4011 TCGv t1
= tcg_temp_new();
4013 tcg_gen_shri_tl(t1
, t0
, 8);
4014 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4015 tcg_gen_shli_tl(t0
, t0
, 8);
4016 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4017 tcg_gen_or_tl(t0
, t0
, t1
);
4019 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4023 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4026 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4028 #if defined(TARGET_MIPS64)
4031 TCGv t1
= tcg_temp_new();
4033 tcg_gen_shri_tl(t1
, t0
, 8);
4034 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4035 tcg_gen_shli_tl(t0
, t0
, 8);
4036 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4037 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4043 TCGv t1
= tcg_temp_new();
4045 tcg_gen_shri_tl(t1
, t0
, 16);
4046 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4047 tcg_gen_shli_tl(t0
, t0
, 16);
4048 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4049 tcg_gen_or_tl(t0
, t0
, t1
);
4050 tcg_gen_shri_tl(t1
, t0
, 32);
4051 tcg_gen_shli_tl(t0
, t0
, 32);
4052 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4058 MIPS_INVAL("bsfhl");
4059 generate_exception(ctx
, EXCP_RI
);
4066 #ifndef CONFIG_USER_ONLY
4067 /* CP0 (MMU and control) */
4068 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4070 TCGv_i32 t0
= tcg_temp_new_i32();
4072 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4073 tcg_gen_ext_i32_tl(arg
, t0
);
4074 tcg_temp_free_i32(t0
);
4077 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4079 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4080 tcg_gen_ext32s_tl(arg
, arg
);
4083 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4085 TCGv_i32 t0
= tcg_temp_new_i32();
4087 tcg_gen_trunc_tl_i32(t0
, arg
);
4088 tcg_gen_st_i32(t0
, cpu_env
, off
);
4089 tcg_temp_free_i32(t0
);
4092 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4094 tcg_gen_ext32s_tl(arg
, arg
);
4095 tcg_gen_st_tl(arg
, cpu_env
, off
);
4098 static void gen_mfc0 (CPUMIPSState
*env
, DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4100 const char *rn
= "invalid";
4103 check_insn(env
, ctx
, ISA_MIPS32
);
4109 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4113 check_insn(env
, ctx
, ASE_MT
);
4114 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4118 check_insn(env
, ctx
, ASE_MT
);
4119 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4123 check_insn(env
, ctx
, ASE_MT
);
4124 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4134 gen_helper_mfc0_random(arg
, cpu_env
);
4138 check_insn(env
, ctx
, ASE_MT
);
4139 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4143 check_insn(env
, ctx
, ASE_MT
);
4144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4148 check_insn(env
, ctx
, ASE_MT
);
4149 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4153 check_insn(env
, ctx
, ASE_MT
);
4154 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4158 check_insn(env
, ctx
, ASE_MT
);
4159 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4163 check_insn(env
, ctx
, ASE_MT
);
4164 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4165 rn
= "VPEScheFBack";
4168 check_insn(env
, ctx
, ASE_MT
);
4169 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4179 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4180 tcg_gen_ext32s_tl(arg
, arg
);
4184 check_insn(env
, ctx
, ASE_MT
);
4185 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4189 check_insn(env
, ctx
, ASE_MT
);
4190 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4194 check_insn(env
, ctx
, ASE_MT
);
4195 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4199 check_insn(env
, ctx
, ASE_MT
);
4200 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4204 check_insn(env
, ctx
, ASE_MT
);
4205 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4209 check_insn(env
, ctx
, ASE_MT
);
4210 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4214 check_insn(env
, ctx
, ASE_MT
);
4215 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4225 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4226 tcg_gen_ext32s_tl(arg
, arg
);
4236 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4237 tcg_gen_ext32s_tl(arg
, arg
);
4241 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4242 rn
= "ContextConfig";
4251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4255 check_insn(env
, ctx
, ISA_MIPS32R2
);
4256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4266 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4270 check_insn(env
, ctx
, ISA_MIPS32R2
);
4271 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4275 check_insn(env
, ctx
, ISA_MIPS32R2
);
4276 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4280 check_insn(env
, ctx
, ISA_MIPS32R2
);
4281 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4285 check_insn(env
, ctx
, ISA_MIPS32R2
);
4286 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4290 check_insn(env
, ctx
, ISA_MIPS32R2
);
4291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4301 check_insn(env
, ctx
, ISA_MIPS32R2
);
4302 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4312 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4313 tcg_gen_ext32s_tl(arg
, arg
);
4323 /* Mark as an IO operation because we read the time. */
4326 gen_helper_mfc0_count(arg
, cpu_env
);
4330 /* Break the TB to be able to take timer interrupts immediately
4331 after reading count. */
4332 ctx
->bstate
= BS_STOP
;
4335 /* 6,7 are implementation dependent */
4343 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4344 tcg_gen_ext32s_tl(arg
, arg
);
4354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4357 /* 6,7 are implementation dependent */
4365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4369 check_insn(env
, ctx
, ISA_MIPS32R2
);
4370 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4374 check_insn(env
, ctx
, ISA_MIPS32R2
);
4375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4379 check_insn(env
, ctx
, ISA_MIPS32R2
);
4380 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4390 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4400 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4401 tcg_gen_ext32s_tl(arg
, arg
);
4411 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4415 check_insn(env
, ctx
, ISA_MIPS32R2
);
4416 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4426 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4434 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4438 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4441 /* 4,5 are reserved */
4442 /* 6,7 are implementation dependent */
4444 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4448 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4458 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4468 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4478 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4488 #if defined(TARGET_MIPS64)
4489 check_insn(env
, ctx
, ISA_MIPS3
);
4490 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4491 tcg_gen_ext32s_tl(arg
, arg
);
4500 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4503 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4511 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4512 rn
= "'Diagnostic"; /* implementation dependent */
4517 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4521 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4522 rn
= "TraceControl";
4525 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4526 rn
= "TraceControl2";
4529 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4530 rn
= "UserTraceData";
4533 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4544 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4545 tcg_gen_ext32s_tl(arg
, arg
);
4555 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4556 rn
= "Performance0";
4559 // gen_helper_mfc0_performance1(arg);
4560 rn
= "Performance1";
4563 // gen_helper_mfc0_performance2(arg);
4564 rn
= "Performance2";
4567 // gen_helper_mfc0_performance3(arg);
4568 rn
= "Performance3";
4571 // gen_helper_mfc0_performance4(arg);
4572 rn
= "Performance4";
4575 // gen_helper_mfc0_performance5(arg);
4576 rn
= "Performance5";
4579 // gen_helper_mfc0_performance6(arg);
4580 rn
= "Performance6";
4583 // gen_helper_mfc0_performance7(arg);
4584 rn
= "Performance7";
4591 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4597 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4610 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4617 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4630 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4637 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4647 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4648 tcg_gen_ext32s_tl(arg
, arg
);
4659 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4669 (void)rn
; /* avoid a compiler warning */
4670 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4674 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4675 generate_exception(ctx
, EXCP_RI
);
4678 static void gen_mtc0 (CPUMIPSState
*env
, DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4680 const char *rn
= "invalid";
4683 check_insn(env
, ctx
, ISA_MIPS32
);
4692 gen_helper_mtc0_index(cpu_env
, arg
);
4696 check_insn(env
, ctx
, ASE_MT
);
4697 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4701 check_insn(env
, ctx
, ASE_MT
);
4706 check_insn(env
, ctx
, ASE_MT
);
4721 check_insn(env
, ctx
, ASE_MT
);
4722 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4726 check_insn(env
, ctx
, ASE_MT
);
4727 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4731 check_insn(env
, ctx
, ASE_MT
);
4732 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4736 check_insn(env
, ctx
, ASE_MT
);
4737 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4741 check_insn(env
, ctx
, ASE_MT
);
4742 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4746 check_insn(env
, ctx
, ASE_MT
);
4747 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4748 rn
= "VPEScheFBack";
4751 check_insn(env
, ctx
, ASE_MT
);
4752 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4762 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4766 check_insn(env
, ctx
, ASE_MT
);
4767 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4771 check_insn(env
, ctx
, ASE_MT
);
4772 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4776 check_insn(env
, ctx
, ASE_MT
);
4777 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4781 check_insn(env
, ctx
, ASE_MT
);
4782 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4786 check_insn(env
, ctx
, ASE_MT
);
4787 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4791 check_insn(env
, ctx
, ASE_MT
);
4792 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4796 check_insn(env
, ctx
, ASE_MT
);
4797 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4807 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4817 gen_helper_mtc0_context(cpu_env
, arg
);
4821 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4822 rn
= "ContextConfig";
4831 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4835 check_insn(env
, ctx
, ISA_MIPS32R2
);
4836 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4846 gen_helper_mtc0_wired(cpu_env
, arg
);
4850 check_insn(env
, ctx
, ISA_MIPS32R2
);
4851 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4855 check_insn(env
, ctx
, ISA_MIPS32R2
);
4856 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4860 check_insn(env
, ctx
, ISA_MIPS32R2
);
4861 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4865 check_insn(env
, ctx
, ISA_MIPS32R2
);
4866 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4870 check_insn(env
, ctx
, ISA_MIPS32R2
);
4871 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4881 check_insn(env
, ctx
, ISA_MIPS32R2
);
4882 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4896 gen_helper_mtc0_count(cpu_env
, arg
);
4899 /* 6,7 are implementation dependent */
4907 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4917 gen_helper_mtc0_compare(cpu_env
, arg
);
4920 /* 6,7 are implementation dependent */
4928 save_cpu_state(ctx
, 1);
4929 gen_helper_mtc0_status(cpu_env
, arg
);
4930 /* BS_STOP isn't good enough here, hflags may have changed. */
4931 gen_save_pc(ctx
->pc
+ 4);
4932 ctx
->bstate
= BS_EXCP
;
4936 check_insn(env
, ctx
, ISA_MIPS32R2
);
4937 gen_helper_mtc0_intctl(cpu_env
, arg
);
4938 /* Stop translation as we may have switched the execution mode */
4939 ctx
->bstate
= BS_STOP
;
4943 check_insn(env
, ctx
, ISA_MIPS32R2
);
4944 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4945 /* Stop translation as we may have switched the execution mode */
4946 ctx
->bstate
= BS_STOP
;
4950 check_insn(env
, ctx
, ISA_MIPS32R2
);
4951 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4952 /* Stop translation as we may have switched the execution mode */
4953 ctx
->bstate
= BS_STOP
;
4963 save_cpu_state(ctx
, 1);
4964 gen_helper_mtc0_cause(cpu_env
, arg
);
4974 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4988 check_insn(env
, ctx
, ISA_MIPS32R2
);
4989 gen_helper_mtc0_ebase(cpu_env
, arg
);
4999 gen_helper_mtc0_config0(cpu_env
, arg
);
5001 /* Stop translation as we may have switched the execution mode */
5002 ctx
->bstate
= BS_STOP
;
5005 /* ignored, read only */
5009 gen_helper_mtc0_config2(cpu_env
, arg
);
5011 /* Stop translation as we may have switched the execution mode */
5012 ctx
->bstate
= BS_STOP
;
5015 /* ignored, read only */
5018 /* 4,5 are reserved */
5019 /* 6,7 are implementation dependent */
5029 rn
= "Invalid config selector";
5036 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5046 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5056 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5066 #if defined(TARGET_MIPS64)
5067 check_insn(env
, ctx
, ISA_MIPS3
);
5068 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5077 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5080 gen_helper_mtc0_framemask(cpu_env
, arg
);
5089 rn
= "Diagnostic"; /* implementation dependent */
5094 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5095 /* BS_STOP isn't good enough here, hflags may have changed. */
5096 gen_save_pc(ctx
->pc
+ 4);
5097 ctx
->bstate
= BS_EXCP
;
5101 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5102 rn
= "TraceControl";
5103 /* Stop translation as we may have switched the execution mode */
5104 ctx
->bstate
= BS_STOP
;
5107 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5108 rn
= "TraceControl2";
5109 /* Stop translation as we may have switched the execution mode */
5110 ctx
->bstate
= BS_STOP
;
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx
->bstate
= BS_STOP
;
5115 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5116 rn
= "UserTraceData";
5117 /* Stop translation as we may have switched the execution mode */
5118 ctx
->bstate
= BS_STOP
;
5121 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx
->bstate
= BS_STOP
;
5134 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5144 gen_helper_mtc0_performance0(cpu_env
, arg
);
5145 rn
= "Performance0";
5148 // gen_helper_mtc0_performance1(arg);
5149 rn
= "Performance1";
5152 // gen_helper_mtc0_performance2(arg);
5153 rn
= "Performance2";
5156 // gen_helper_mtc0_performance3(arg);
5157 rn
= "Performance3";
5160 // gen_helper_mtc0_performance4(arg);
5161 rn
= "Performance4";
5164 // gen_helper_mtc0_performance5(arg);
5165 rn
= "Performance5";
5168 // gen_helper_mtc0_performance6(arg);
5169 rn
= "Performance6";
5172 // gen_helper_mtc0_performance7(arg);
5173 rn
= "Performance7";
5199 gen_helper_mtc0_taglo(cpu_env
, arg
);
5206 gen_helper_mtc0_datalo(cpu_env
, arg
);
5219 gen_helper_mtc0_taghi(cpu_env
, arg
);
5226 gen_helper_mtc0_datahi(cpu_env
, arg
);
5237 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5248 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5254 /* Stop translation as we may have switched the execution mode */
5255 ctx
->bstate
= BS_STOP
;
5260 (void)rn
; /* avoid a compiler warning */
5261 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5262 /* For simplicity assume that all writes can cause interrupts. */
5265 ctx
->bstate
= BS_STOP
;
5270 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5271 generate_exception(ctx
, EXCP_RI
);
5274 #if defined(TARGET_MIPS64)
5275 static void gen_dmfc0 (CPUMIPSState
*env
, DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5277 const char *rn
= "invalid";
5280 check_insn(env
, ctx
, ISA_MIPS64
);
5286 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5290 check_insn(env
, ctx
, ASE_MT
);
5291 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5295 check_insn(env
, ctx
, ASE_MT
);
5296 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5300 check_insn(env
, ctx
, ASE_MT
);
5301 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5311 gen_helper_mfc0_random(arg
, cpu_env
);
5315 check_insn(env
, ctx
, ASE_MT
);
5316 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5320 check_insn(env
, ctx
, ASE_MT
);
5321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5325 check_insn(env
, ctx
, ASE_MT
);
5326 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5330 check_insn(env
, ctx
, ASE_MT
);
5331 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5335 check_insn(env
, ctx
, ASE_MT
);
5336 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5340 check_insn(env
, ctx
, ASE_MT
);
5341 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5342 rn
= "VPEScheFBack";
5345 check_insn(env
, ctx
, ASE_MT
);
5346 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5356 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5360 check_insn(env
, ctx
, ASE_MT
);
5361 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5365 check_insn(env
, ctx
, ASE_MT
);
5366 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5370 check_insn(env
, ctx
, ASE_MT
);
5371 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5375 check_insn(env
, ctx
, ASE_MT
);
5376 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5380 check_insn(env
, ctx
, ASE_MT
);
5381 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5385 check_insn(env
, ctx
, ASE_MT
);
5386 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5390 check_insn(env
, ctx
, ASE_MT
);
5391 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5401 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5411 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5415 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5416 rn
= "ContextConfig";
5425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5429 check_insn(env
, ctx
, ISA_MIPS32R2
);
5430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5444 check_insn(env
, ctx
, ISA_MIPS32R2
);
5445 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5449 check_insn(env
, ctx
, ISA_MIPS32R2
);
5450 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5454 check_insn(env
, ctx
, ISA_MIPS32R2
);
5455 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5459 check_insn(env
, ctx
, ISA_MIPS32R2
);
5460 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5464 check_insn(env
, ctx
, ISA_MIPS32R2
);
5465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5475 check_insn(env
, ctx
, ISA_MIPS32R2
);
5476 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5486 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5496 /* Mark as an IO operation because we read the time. */
5499 gen_helper_mfc0_count(arg
, cpu_env
);
5503 /* Break the TB to be able to take timer interrupts immediately
5504 after reading count. */
5505 ctx
->bstate
= BS_STOP
;
5508 /* 6,7 are implementation dependent */
5516 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5526 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5529 /* 6,7 are implementation dependent */
5537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5541 check_insn(env
, ctx
, ISA_MIPS32R2
);
5542 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5546 check_insn(env
, ctx
, ISA_MIPS32R2
);
5547 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5551 check_insn(env
, ctx
, ISA_MIPS32R2
);
5552 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5572 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5582 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5586 check_insn(env
, ctx
, ISA_MIPS32R2
);
5587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5597 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5601 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5609 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5612 /* 6,7 are implementation dependent */
5614 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5618 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5628 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5638 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5648 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5658 check_insn(env
, ctx
, ISA_MIPS3
);
5659 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5667 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5670 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5678 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5679 rn
= "'Diagnostic"; /* implementation dependent */
5684 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5688 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5689 rn
= "TraceControl";
5692 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5693 rn
= "TraceControl2";
5696 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5697 rn
= "UserTraceData";
5700 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5711 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5721 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5722 rn
= "Performance0";
5725 // gen_helper_dmfc0_performance1(arg);
5726 rn
= "Performance1";
5729 // gen_helper_dmfc0_performance2(arg);
5730 rn
= "Performance2";
5733 // gen_helper_dmfc0_performance3(arg);
5734 rn
= "Performance3";
5737 // gen_helper_dmfc0_performance4(arg);
5738 rn
= "Performance4";
5741 // gen_helper_dmfc0_performance5(arg);
5742 rn
= "Performance5";
5745 // gen_helper_dmfc0_performance6(arg);
5746 rn
= "Performance6";
5749 // gen_helper_dmfc0_performance7(arg);
5750 rn
= "Performance7";
5757 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5764 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5777 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5797 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5804 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5814 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5825 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5835 (void)rn
; /* avoid a compiler warning */
5836 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5840 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5841 generate_exception(ctx
, EXCP_RI
);
5844 static void gen_dmtc0 (CPUMIPSState
*env
, DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5846 const char *rn
= "invalid";
5849 check_insn(env
, ctx
, ISA_MIPS64
);
5858 gen_helper_mtc0_index(cpu_env
, arg
);
5862 check_insn(env
, ctx
, ASE_MT
);
5863 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5867 check_insn(env
, ctx
, ASE_MT
);
5872 check_insn(env
, ctx
, ASE_MT
);
5887 check_insn(env
, ctx
, ASE_MT
);
5888 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5892 check_insn(env
, ctx
, ASE_MT
);
5893 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5897 check_insn(env
, ctx
, ASE_MT
);
5898 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5902 check_insn(env
, ctx
, ASE_MT
);
5903 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5907 check_insn(env
, ctx
, ASE_MT
);
5908 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5912 check_insn(env
, ctx
, ASE_MT
);
5913 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5914 rn
= "VPEScheFBack";
5917 check_insn(env
, ctx
, ASE_MT
);
5918 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5928 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5932 check_insn(env
, ctx
, ASE_MT
);
5933 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5937 check_insn(env
, ctx
, ASE_MT
);
5938 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5942 check_insn(env
, ctx
, ASE_MT
);
5943 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5947 check_insn(env
, ctx
, ASE_MT
);
5948 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5952 check_insn(env
, ctx
, ASE_MT
);
5953 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5957 check_insn(env
, ctx
, ASE_MT
);
5958 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5962 check_insn(env
, ctx
, ASE_MT
);
5963 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5973 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5983 gen_helper_mtc0_context(cpu_env
, arg
);
5987 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5988 rn
= "ContextConfig";
5997 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6001 check_insn(env
, ctx
, ISA_MIPS32R2
);
6002 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6012 gen_helper_mtc0_wired(cpu_env
, arg
);
6016 check_insn(env
, ctx
, ISA_MIPS32R2
);
6017 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6021 check_insn(env
, ctx
, ISA_MIPS32R2
);
6022 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6026 check_insn(env
, ctx
, ISA_MIPS32R2
);
6027 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6031 check_insn(env
, ctx
, ISA_MIPS32R2
);
6032 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6036 check_insn(env
, ctx
, ISA_MIPS32R2
);
6037 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6047 check_insn(env
, ctx
, ISA_MIPS32R2
);
6048 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6062 gen_helper_mtc0_count(cpu_env
, arg
);
6065 /* 6,7 are implementation dependent */
6069 /* Stop translation as we may have switched the execution mode */
6070 ctx
->bstate
= BS_STOP
;
6075 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6085 gen_helper_mtc0_compare(cpu_env
, arg
);
6088 /* 6,7 are implementation dependent */
6092 /* Stop translation as we may have switched the execution mode */
6093 ctx
->bstate
= BS_STOP
;
6098 save_cpu_state(ctx
, 1);
6099 gen_helper_mtc0_status(cpu_env
, arg
);
6100 /* BS_STOP isn't good enough here, hflags may have changed. */
6101 gen_save_pc(ctx
->pc
+ 4);
6102 ctx
->bstate
= BS_EXCP
;
6106 check_insn(env
, ctx
, ISA_MIPS32R2
);
6107 gen_helper_mtc0_intctl(cpu_env
, arg
);
6108 /* Stop translation as we may have switched the execution mode */
6109 ctx
->bstate
= BS_STOP
;
6113 check_insn(env
, ctx
, ISA_MIPS32R2
);
6114 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6115 /* Stop translation as we may have switched the execution mode */
6116 ctx
->bstate
= BS_STOP
;
6120 check_insn(env
, ctx
, ISA_MIPS32R2
);
6121 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6122 /* Stop translation as we may have switched the execution mode */
6123 ctx
->bstate
= BS_STOP
;
6133 save_cpu_state(ctx
, 1);
6134 /* Mark as an IO operation because we may trigger a software
6139 gen_helper_mtc0_cause(cpu_env
, arg
);
6143 /* Stop translation as we may have triggered an intetrupt */
6144 ctx
->bstate
= BS_STOP
;
6154 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6168 check_insn(env
, ctx
, ISA_MIPS32R2
);
6169 gen_helper_mtc0_ebase(cpu_env
, arg
);
6179 gen_helper_mtc0_config0(cpu_env
, arg
);
6181 /* Stop translation as we may have switched the execution mode */
6182 ctx
->bstate
= BS_STOP
;
6185 /* ignored, read only */
6189 gen_helper_mtc0_config2(cpu_env
, arg
);
6191 /* Stop translation as we may have switched the execution mode */
6192 ctx
->bstate
= BS_STOP
;
6198 /* 6,7 are implementation dependent */
6200 rn
= "Invalid config selector";
6207 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6217 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6227 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6237 check_insn(env
, ctx
, ISA_MIPS3
);
6238 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6246 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6249 gen_helper_mtc0_framemask(cpu_env
, arg
);
6258 rn
= "Diagnostic"; /* implementation dependent */
6263 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6264 /* BS_STOP isn't good enough here, hflags may have changed. */
6265 gen_save_pc(ctx
->pc
+ 4);
6266 ctx
->bstate
= BS_EXCP
;
6270 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6271 /* Stop translation as we may have switched the execution mode */
6272 ctx
->bstate
= BS_STOP
;
6273 rn
= "TraceControl";
6276 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6277 /* Stop translation as we may have switched the execution mode */
6278 ctx
->bstate
= BS_STOP
;
6279 rn
= "TraceControl2";
6282 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6283 /* Stop translation as we may have switched the execution mode */
6284 ctx
->bstate
= BS_STOP
;
6285 rn
= "UserTraceData";
6288 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6289 /* Stop translation as we may have switched the execution mode */
6290 ctx
->bstate
= BS_STOP
;
6301 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6311 gen_helper_mtc0_performance0(cpu_env
, arg
);
6312 rn
= "Performance0";
6315 // gen_helper_mtc0_performance1(cpu_env, arg);
6316 rn
= "Performance1";
6319 // gen_helper_mtc0_performance2(cpu_env, arg);
6320 rn
= "Performance2";
6323 // gen_helper_mtc0_performance3(cpu_env, arg);
6324 rn
= "Performance3";
6327 // gen_helper_mtc0_performance4(cpu_env, arg);
6328 rn
= "Performance4";
6331 // gen_helper_mtc0_performance5(cpu_env, arg);
6332 rn
= "Performance5";
6335 // gen_helper_mtc0_performance6(cpu_env, arg);
6336 rn
= "Performance6";
6339 // gen_helper_mtc0_performance7(cpu_env, arg);
6340 rn
= "Performance7";
6366 gen_helper_mtc0_taglo(cpu_env
, arg
);
6373 gen_helper_mtc0_datalo(cpu_env
, arg
);
6386 gen_helper_mtc0_taghi(cpu_env
, arg
);
6393 gen_helper_mtc0_datahi(cpu_env
, arg
);
6404 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6415 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6421 /* Stop translation as we may have switched the execution mode */
6422 ctx
->bstate
= BS_STOP
;
6427 (void)rn
; /* avoid a compiler warning */
6428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6429 /* For simplicity assume that all writes can cause interrupts. */
6432 ctx
->bstate
= BS_STOP
;
6437 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6438 generate_exception(ctx
, EXCP_RI
);
6440 #endif /* TARGET_MIPS64 */
6442 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6443 int u
, int sel
, int h
)
6445 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6446 TCGv t0
= tcg_temp_local_new();
6448 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6449 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6450 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6451 tcg_gen_movi_tl(t0
, -1);
6452 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6453 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6454 tcg_gen_movi_tl(t0
, -1);
6460 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6463 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6473 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6476 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6479 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6482 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6485 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6488 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6491 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6494 gen_mfc0(env
, ctx
, t0
, rt
, sel
);
6501 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6504 gen_mfc0(env
, ctx
, t0
, rt
, sel
);
6510 gen_helper_mftc0_status(t0
, cpu_env
);
6513 gen_mfc0(env
, ctx
, t0
, rt
, sel
);
6519 gen_helper_mftc0_cause(t0
, cpu_env
);
6529 gen_helper_mftc0_epc(t0
, cpu_env
);
6539 gen_helper_mftc0_ebase(t0
, cpu_env
);
6549 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6559 gen_helper_mftc0_debug(t0
, cpu_env
);
6562 gen_mfc0(env
, ctx
, t0
, rt
, sel
);
6567 gen_mfc0(env
, ctx
, t0
, rt
, sel
);
6569 } else switch (sel
) {
6570 /* GPR registers. */
6572 gen_helper_1e0i(mftgpr
, t0
, rt
);
6574 /* Auxiliary CPU registers */
6578 gen_helper_1e0i(mftlo
, t0
, 0);
6581 gen_helper_1e0i(mfthi
, t0
, 0);
6584 gen_helper_1e0i(mftacx
, t0
, 0);
6587 gen_helper_1e0i(mftlo
, t0
, 1);
6590 gen_helper_1e0i(mfthi
, t0
, 1);
6593 gen_helper_1e0i(mftacx
, t0
, 1);
6596 gen_helper_1e0i(mftlo
, t0
, 2);
6599 gen_helper_1e0i(mfthi
, t0
, 2);
6602 gen_helper_1e0i(mftacx
, t0
, 2);
6605 gen_helper_1e0i(mftlo
, t0
, 3);
6608 gen_helper_1e0i(mfthi
, t0
, 3);
6611 gen_helper_1e0i(mftacx
, t0
, 3);
6614 gen_helper_mftdsp(t0
, cpu_env
);
6620 /* Floating point (COP1). */
6622 /* XXX: For now we support only a single FPU context. */
6624 TCGv_i32 fp0
= tcg_temp_new_i32();
6626 gen_load_fpr32(fp0
, rt
);
6627 tcg_gen_ext_i32_tl(t0
, fp0
);
6628 tcg_temp_free_i32(fp0
);
6630 TCGv_i32 fp0
= tcg_temp_new_i32();
6632 gen_load_fpr32h(fp0
, rt
);
6633 tcg_gen_ext_i32_tl(t0
, fp0
);
6634 tcg_temp_free_i32(fp0
);
6638 /* XXX: For now we support only a single FPU context. */
6639 gen_helper_1e0i(cfc1
, t0
, rt
);
6641 /* COP2: Not implemented. */
6648 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6649 gen_store_gpr(t0
, rd
);
6655 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6656 generate_exception(ctx
, EXCP_RI
);
6659 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6660 int u
, int sel
, int h
)
6662 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6663 TCGv t0
= tcg_temp_local_new();
6665 gen_load_gpr(t0
, rt
);
6666 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6667 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6668 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6670 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6671 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6678 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6681 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6691 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6694 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6697 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6700 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6703 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6706 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6709 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6712 gen_mtc0(env
, ctx
, t0
, rd
, sel
);
6719 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6722 gen_mtc0(env
, ctx
, t0
, rd
, sel
);
6728 gen_helper_mttc0_status(cpu_env
, t0
);
6731 gen_mtc0(env
, ctx
, t0
, rd
, sel
);
6737 gen_helper_mttc0_cause(cpu_env
, t0
);
6747 gen_helper_mttc0_ebase(cpu_env
, t0
);
6757 gen_helper_mttc0_debug(cpu_env
, t0
);
6760 gen_mtc0(env
, ctx
, t0
, rd
, sel
);
6765 gen_mtc0(env
, ctx
, t0
, rd
, sel
);
6767 } else switch (sel
) {
6768 /* GPR registers. */
6770 gen_helper_0e1i(mttgpr
, t0
, rd
);
6772 /* Auxiliary CPU registers */
6776 gen_helper_0e1i(mttlo
, t0
, 0);
6779 gen_helper_0e1i(mtthi
, t0
, 0);
6782 gen_helper_0e1i(mttacx
, t0
, 0);
6785 gen_helper_0e1i(mttlo
, t0
, 1);
6788 gen_helper_0e1i(mtthi
, t0
, 1);
6791 gen_helper_0e1i(mttacx
, t0
, 1);
6794 gen_helper_0e1i(mttlo
, t0
, 2);
6797 gen_helper_0e1i(mtthi
, t0
, 2);
6800 gen_helper_0e1i(mttacx
, t0
, 2);
6803 gen_helper_0e1i(mttlo
, t0
, 3);
6806 gen_helper_0e1i(mtthi
, t0
, 3);
6809 gen_helper_0e1i(mttacx
, t0
, 3);
6812 gen_helper_mttdsp(cpu_env
, t0
);
6818 /* Floating point (COP1). */
6820 /* XXX: For now we support only a single FPU context. */
6822 TCGv_i32 fp0
= tcg_temp_new_i32();
6824 tcg_gen_trunc_tl_i32(fp0
, t0
);
6825 gen_store_fpr32(fp0
, rd
);
6826 tcg_temp_free_i32(fp0
);
6828 TCGv_i32 fp0
= tcg_temp_new_i32();
6830 tcg_gen_trunc_tl_i32(fp0
, t0
);
6831 gen_store_fpr32h(fp0
, rd
);
6832 tcg_temp_free_i32(fp0
);
6836 /* XXX: For now we support only a single FPU context. */
6837 gen_helper_0e1i(ctc1
, t0
, rd
);
6839 /* COP2: Not implemented. */
6846 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6852 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6853 generate_exception(ctx
, EXCP_RI
);
6856 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6858 const char *opn
= "ldst";
6860 check_cp0_enabled(ctx
);
6867 gen_mfc0(env
, ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6872 TCGv t0
= tcg_temp_new();
6874 gen_load_gpr(t0
, rt
);
6875 gen_mtc0(env
, ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6880 #if defined(TARGET_MIPS64)
6882 check_insn(env
, ctx
, ISA_MIPS3
);
6887 gen_dmfc0(env
, ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6891 check_insn(env
, ctx
, ISA_MIPS3
);
6893 TCGv t0
= tcg_temp_new();
6895 gen_load_gpr(t0
, rt
);
6896 gen_dmtc0(env
, ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6903 check_insn(env
, ctx
, ASE_MT
);
6908 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6909 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6913 check_insn(env
, ctx
, ASE_MT
);
6914 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6915 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6920 if (!env
->tlb
->helper_tlbwi
)
6922 gen_helper_tlbwi(cpu_env
);
6926 if (!env
->tlb
->helper_tlbwr
)
6928 gen_helper_tlbwr(cpu_env
);
6932 if (!env
->tlb
->helper_tlbp
)
6934 gen_helper_tlbp(cpu_env
);
6938 if (!env
->tlb
->helper_tlbr
)
6940 gen_helper_tlbr(cpu_env
);
6944 check_insn(env
, ctx
, ISA_MIPS2
);
6945 gen_helper_eret(cpu_env
);
6946 ctx
->bstate
= BS_EXCP
;
6950 check_insn(env
, ctx
, ISA_MIPS32
);
6951 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6953 generate_exception(ctx
, EXCP_RI
);
6955 gen_helper_deret(cpu_env
);
6956 ctx
->bstate
= BS_EXCP
;
6961 check_insn(env
, ctx
, ISA_MIPS3
| ISA_MIPS32
);
6962 /* If we get an exception, we want to restart at next instruction */
6964 save_cpu_state(ctx
, 1);
6966 gen_helper_wait(cpu_env
);
6967 ctx
->bstate
= BS_EXCP
;
6972 generate_exception(ctx
, EXCP_RI
);
6975 (void)opn
; /* avoid a compiler warning */
6976 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6978 #endif /* !CONFIG_USER_ONLY */
6980 /* CP1 Branches (before delay slot) */
6981 static void gen_compute_branch1 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op
,
6982 int32_t cc
, int32_t offset
)
6984 target_ulong btarget
;
6985 const char *opn
= "cp1 cond branch";
6986 TCGv_i32 t0
= tcg_temp_new_i32();
6989 check_insn(env
, ctx
, ISA_MIPS4
| ISA_MIPS32
);
6991 btarget
= ctx
->pc
+ 4 + offset
;
6995 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6996 tcg_gen_not_i32(t0
, t0
);
6997 tcg_gen_andi_i32(t0
, t0
, 1);
6998 tcg_gen_extu_i32_tl(bcond
, t0
);
7002 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7003 tcg_gen_not_i32(t0
, t0
);
7004 tcg_gen_andi_i32(t0
, t0
, 1);
7005 tcg_gen_extu_i32_tl(bcond
, t0
);
7009 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7010 tcg_gen_andi_i32(t0
, t0
, 1);
7011 tcg_gen_extu_i32_tl(bcond
, t0
);
7015 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7016 tcg_gen_andi_i32(t0
, t0
, 1);
7017 tcg_gen_extu_i32_tl(bcond
, t0
);
7020 ctx
->hflags
|= MIPS_HFLAG_BL
;
7024 TCGv_i32 t1
= tcg_temp_new_i32();
7025 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7026 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7027 tcg_gen_nand_i32(t0
, t0
, t1
);
7028 tcg_temp_free_i32(t1
);
7029 tcg_gen_andi_i32(t0
, t0
, 1);
7030 tcg_gen_extu_i32_tl(bcond
, t0
);
7036 TCGv_i32 t1
= tcg_temp_new_i32();
7037 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7038 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7039 tcg_gen_or_i32(t0
, t0
, t1
);
7040 tcg_temp_free_i32(t1
);
7041 tcg_gen_andi_i32(t0
, t0
, 1);
7042 tcg_gen_extu_i32_tl(bcond
, t0
);
7048 TCGv_i32 t1
= tcg_temp_new_i32();
7049 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7050 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7051 tcg_gen_and_i32(t0
, t0
, t1
);
7052 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7053 tcg_gen_and_i32(t0
, t0
, t1
);
7054 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7055 tcg_gen_nand_i32(t0
, t0
, t1
);
7056 tcg_temp_free_i32(t1
);
7057 tcg_gen_andi_i32(t0
, t0
, 1);
7058 tcg_gen_extu_i32_tl(bcond
, t0
);
7064 TCGv_i32 t1
= tcg_temp_new_i32();
7065 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7066 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7067 tcg_gen_or_i32(t0
, t0
, t1
);
7068 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7069 tcg_gen_or_i32(t0
, t0
, t1
);
7070 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7071 tcg_gen_or_i32(t0
, t0
, t1
);
7072 tcg_temp_free_i32(t1
);
7073 tcg_gen_andi_i32(t0
, t0
, 1);
7074 tcg_gen_extu_i32_tl(bcond
, t0
);
7078 ctx
->hflags
|= MIPS_HFLAG_BC
;
7082 generate_exception (ctx
, EXCP_RI
);
7085 (void)opn
; /* avoid a compiler warning */
7086 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7087 ctx
->hflags
, btarget
);
7088 ctx
->btarget
= btarget
;
7091 tcg_temp_free_i32(t0
);
7094 /* Coprocessor 1 (FPU) */
7096 #define FOP(func, fmt) (((fmt) << 21) | (func))
7099 OPC_ADD_S
= FOP(0, FMT_S
),
7100 OPC_SUB_S
= FOP(1, FMT_S
),
7101 OPC_MUL_S
= FOP(2, FMT_S
),
7102 OPC_DIV_S
= FOP(3, FMT_S
),
7103 OPC_SQRT_S
= FOP(4, FMT_S
),
7104 OPC_ABS_S
= FOP(5, FMT_S
),
7105 OPC_MOV_S
= FOP(6, FMT_S
),
7106 OPC_NEG_S
= FOP(7, FMT_S
),
7107 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7108 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7109 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7110 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7111 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7112 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7113 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7114 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7115 OPC_MOVCF_S
= FOP(17, FMT_S
),
7116 OPC_MOVZ_S
= FOP(18, FMT_S
),
7117 OPC_MOVN_S
= FOP(19, FMT_S
),
7118 OPC_RECIP_S
= FOP(21, FMT_S
),
7119 OPC_RSQRT_S
= FOP(22, FMT_S
),
7120 OPC_RECIP2_S
= FOP(28, FMT_S
),
7121 OPC_RECIP1_S
= FOP(29, FMT_S
),
7122 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7123 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7124 OPC_CVT_D_S
= FOP(33, FMT_S
),
7125 OPC_CVT_W_S
= FOP(36, FMT_S
),
7126 OPC_CVT_L_S
= FOP(37, FMT_S
),
7127 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7128 OPC_CMP_F_S
= FOP (48, FMT_S
),
7129 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7130 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7131 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7132 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7133 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7134 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7135 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7136 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7137 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7138 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7139 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7140 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7141 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7142 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7143 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7145 OPC_ADD_D
= FOP(0, FMT_D
),
7146 OPC_SUB_D
= FOP(1, FMT_D
),
7147 OPC_MUL_D
= FOP(2, FMT_D
),
7148 OPC_DIV_D
= FOP(3, FMT_D
),
7149 OPC_SQRT_D
= FOP(4, FMT_D
),
7150 OPC_ABS_D
= FOP(5, FMT_D
),
7151 OPC_MOV_D
= FOP(6, FMT_D
),
7152 OPC_NEG_D
= FOP(7, FMT_D
),
7153 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7154 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7155 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7156 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7157 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7158 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7159 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7160 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7161 OPC_MOVCF_D
= FOP(17, FMT_D
),
7162 OPC_MOVZ_D
= FOP(18, FMT_D
),
7163 OPC_MOVN_D
= FOP(19, FMT_D
),
7164 OPC_RECIP_D
= FOP(21, FMT_D
),
7165 OPC_RSQRT_D
= FOP(22, FMT_D
),
7166 OPC_RECIP2_D
= FOP(28, FMT_D
),
7167 OPC_RECIP1_D
= FOP(29, FMT_D
),
7168 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7169 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7170 OPC_CVT_S_D
= FOP(32, FMT_D
),
7171 OPC_CVT_W_D
= FOP(36, FMT_D
),
7172 OPC_CVT_L_D
= FOP(37, FMT_D
),
7173 OPC_CMP_F_D
= FOP (48, FMT_D
),
7174 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7175 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7176 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7177 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7178 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7179 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7180 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7181 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7182 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7183 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7184 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7185 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7186 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7187 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7188 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7190 OPC_CVT_S_W
= FOP(32, FMT_W
),
7191 OPC_CVT_D_W
= FOP(33, FMT_W
),
7192 OPC_CVT_S_L
= FOP(32, FMT_L
),
7193 OPC_CVT_D_L
= FOP(33, FMT_L
),
7194 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7196 OPC_ADD_PS
= FOP(0, FMT_PS
),
7197 OPC_SUB_PS
= FOP(1, FMT_PS
),
7198 OPC_MUL_PS
= FOP(2, FMT_PS
),
7199 OPC_DIV_PS
= FOP(3, FMT_PS
),
7200 OPC_ABS_PS
= FOP(5, FMT_PS
),
7201 OPC_MOV_PS
= FOP(6, FMT_PS
),
7202 OPC_NEG_PS
= FOP(7, FMT_PS
),
7203 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7204 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7205 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7206 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7207 OPC_MULR_PS
= FOP(26, FMT_PS
),
7208 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7209 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7210 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7211 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7213 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7214 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7215 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7216 OPC_PLL_PS
= FOP(44, FMT_PS
),
7217 OPC_PLU_PS
= FOP(45, FMT_PS
),
7218 OPC_PUL_PS
= FOP(46, FMT_PS
),
7219 OPC_PUU_PS
= FOP(47, FMT_PS
),
7220 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7221 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7222 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7223 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7224 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7225 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7226 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7227 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7228 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7229 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7230 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7231 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7232 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7233 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7234 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7235 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7238 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7240 const char *opn
= "cp1 move";
7241 TCGv t0
= tcg_temp_new();
7246 TCGv_i32 fp0
= tcg_temp_new_i32();
7248 gen_load_fpr32(fp0
, fs
);
7249 tcg_gen_ext_i32_tl(t0
, fp0
);
7250 tcg_temp_free_i32(fp0
);
7252 gen_store_gpr(t0
, rt
);
7256 gen_load_gpr(t0
, rt
);
7258 TCGv_i32 fp0
= tcg_temp_new_i32();
7260 tcg_gen_trunc_tl_i32(fp0
, t0
);
7261 gen_store_fpr32(fp0
, fs
);
7262 tcg_temp_free_i32(fp0
);
7267 gen_helper_1e0i(cfc1
, t0
, fs
);
7268 gen_store_gpr(t0
, rt
);
7272 gen_load_gpr(t0
, rt
);
7273 gen_helper_0e1i(ctc1
, t0
, fs
);
7276 #if defined(TARGET_MIPS64)
7278 gen_load_fpr64(ctx
, t0
, fs
);
7279 gen_store_gpr(t0
, rt
);
7283 gen_load_gpr(t0
, rt
);
7284 gen_store_fpr64(ctx
, t0
, fs
);
7290 TCGv_i32 fp0
= tcg_temp_new_i32();
7292 gen_load_fpr32h(fp0
, fs
);
7293 tcg_gen_ext_i32_tl(t0
, fp0
);
7294 tcg_temp_free_i32(fp0
);
7296 gen_store_gpr(t0
, rt
);
7300 gen_load_gpr(t0
, rt
);
7302 TCGv_i32 fp0
= tcg_temp_new_i32();
7304 tcg_gen_trunc_tl_i32(fp0
, t0
);
7305 gen_store_fpr32h(fp0
, fs
);
7306 tcg_temp_free_i32(fp0
);
7312 generate_exception (ctx
, EXCP_RI
);
7315 (void)opn
; /* avoid a compiler warning */
7316 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7322 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7338 l1
= gen_new_label();
7339 t0
= tcg_temp_new_i32();
7340 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7341 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7342 tcg_temp_free_i32(t0
);
7344 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7346 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7351 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7354 TCGv_i32 t0
= tcg_temp_new_i32();
7355 int l1
= gen_new_label();
7362 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7363 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7364 gen_load_fpr32(t0
, fs
);
7365 gen_store_fpr32(t0
, fd
);
7367 tcg_temp_free_i32(t0
);
7370 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7373 TCGv_i32 t0
= tcg_temp_new_i32();
7375 int l1
= gen_new_label();
7382 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7383 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7384 tcg_temp_free_i32(t0
);
7385 fp0
= tcg_temp_new_i64();
7386 gen_load_fpr64(ctx
, fp0
, fs
);
7387 gen_store_fpr64(ctx
, fp0
, fd
);
7388 tcg_temp_free_i64(fp0
);
7392 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7395 TCGv_i32 t0
= tcg_temp_new_i32();
7396 int l1
= gen_new_label();
7397 int l2
= gen_new_label();
7404 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7405 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7406 gen_load_fpr32(t0
, fs
);
7407 gen_store_fpr32(t0
, fd
);
7410 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7411 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7412 gen_load_fpr32h(t0
, fs
);
7413 gen_store_fpr32h(t0
, fd
);
7414 tcg_temp_free_i32(t0
);
7419 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7420 int ft
, int fs
, int fd
, int cc
)
7422 const char *opn
= "farith";
7423 const char *condnames
[] = {
7441 const char *condnames_abs
[] = {
7459 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7460 uint32_t func
= ctx
->opcode
& 0x3f;
7465 TCGv_i32 fp0
= tcg_temp_new_i32();
7466 TCGv_i32 fp1
= tcg_temp_new_i32();
7468 gen_load_fpr32(fp0
, fs
);
7469 gen_load_fpr32(fp1
, ft
);
7470 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7471 tcg_temp_free_i32(fp1
);
7472 gen_store_fpr32(fp0
, fd
);
7473 tcg_temp_free_i32(fp0
);
7480 TCGv_i32 fp0
= tcg_temp_new_i32();
7481 TCGv_i32 fp1
= tcg_temp_new_i32();
7483 gen_load_fpr32(fp0
, fs
);
7484 gen_load_fpr32(fp1
, ft
);
7485 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7486 tcg_temp_free_i32(fp1
);
7487 gen_store_fpr32(fp0
, fd
);
7488 tcg_temp_free_i32(fp0
);
7495 TCGv_i32 fp0
= tcg_temp_new_i32();
7496 TCGv_i32 fp1
= tcg_temp_new_i32();
7498 gen_load_fpr32(fp0
, fs
);
7499 gen_load_fpr32(fp1
, ft
);
7500 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7501 tcg_temp_free_i32(fp1
);
7502 gen_store_fpr32(fp0
, fd
);
7503 tcg_temp_free_i32(fp0
);
7510 TCGv_i32 fp0
= tcg_temp_new_i32();
7511 TCGv_i32 fp1
= tcg_temp_new_i32();
7513 gen_load_fpr32(fp0
, fs
);
7514 gen_load_fpr32(fp1
, ft
);
7515 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7516 tcg_temp_free_i32(fp1
);
7517 gen_store_fpr32(fp0
, fd
);
7518 tcg_temp_free_i32(fp0
);
7525 TCGv_i32 fp0
= tcg_temp_new_i32();
7527 gen_load_fpr32(fp0
, fs
);
7528 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7529 gen_store_fpr32(fp0
, fd
);
7530 tcg_temp_free_i32(fp0
);
7536 TCGv_i32 fp0
= tcg_temp_new_i32();
7538 gen_load_fpr32(fp0
, fs
);
7539 gen_helper_float_abs_s(fp0
, fp0
);
7540 gen_store_fpr32(fp0
, fd
);
7541 tcg_temp_free_i32(fp0
);
7547 TCGv_i32 fp0
= tcg_temp_new_i32();
7549 gen_load_fpr32(fp0
, fs
);
7550 gen_store_fpr32(fp0
, fd
);
7551 tcg_temp_free_i32(fp0
);
7557 TCGv_i32 fp0
= tcg_temp_new_i32();
7559 gen_load_fpr32(fp0
, fs
);
7560 gen_helper_float_chs_s(fp0
, fp0
);
7561 gen_store_fpr32(fp0
, fd
);
7562 tcg_temp_free_i32(fp0
);
7567 check_cp1_64bitmode(ctx
);
7569 TCGv_i32 fp32
= tcg_temp_new_i32();
7570 TCGv_i64 fp64
= tcg_temp_new_i64();
7572 gen_load_fpr32(fp32
, fs
);
7573 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7574 tcg_temp_free_i32(fp32
);
7575 gen_store_fpr64(ctx
, fp64
, fd
);
7576 tcg_temp_free_i64(fp64
);
7581 check_cp1_64bitmode(ctx
);
7583 TCGv_i32 fp32
= tcg_temp_new_i32();
7584 TCGv_i64 fp64
= tcg_temp_new_i64();
7586 gen_load_fpr32(fp32
, fs
);
7587 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7588 tcg_temp_free_i32(fp32
);
7589 gen_store_fpr64(ctx
, fp64
, fd
);
7590 tcg_temp_free_i64(fp64
);
7595 check_cp1_64bitmode(ctx
);
7597 TCGv_i32 fp32
= tcg_temp_new_i32();
7598 TCGv_i64 fp64
= tcg_temp_new_i64();
7600 gen_load_fpr32(fp32
, fs
);
7601 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7602 tcg_temp_free_i32(fp32
);
7603 gen_store_fpr64(ctx
, fp64
, fd
);
7604 tcg_temp_free_i64(fp64
);
7609 check_cp1_64bitmode(ctx
);
7611 TCGv_i32 fp32
= tcg_temp_new_i32();
7612 TCGv_i64 fp64
= tcg_temp_new_i64();
7614 gen_load_fpr32(fp32
, fs
);
7615 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7616 tcg_temp_free_i32(fp32
);
7617 gen_store_fpr64(ctx
, fp64
, fd
);
7618 tcg_temp_free_i64(fp64
);
7624 TCGv_i32 fp0
= tcg_temp_new_i32();
7626 gen_load_fpr32(fp0
, fs
);
7627 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7628 gen_store_fpr32(fp0
, fd
);
7629 tcg_temp_free_i32(fp0
);
7635 TCGv_i32 fp0
= tcg_temp_new_i32();
7637 gen_load_fpr32(fp0
, fs
);
7638 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7639 gen_store_fpr32(fp0
, fd
);
7640 tcg_temp_free_i32(fp0
);
7646 TCGv_i32 fp0
= tcg_temp_new_i32();
7648 gen_load_fpr32(fp0
, fs
);
7649 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7650 gen_store_fpr32(fp0
, fd
);
7651 tcg_temp_free_i32(fp0
);
7657 TCGv_i32 fp0
= tcg_temp_new_i32();
7659 gen_load_fpr32(fp0
, fs
);
7660 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7661 gen_store_fpr32(fp0
, fd
);
7662 tcg_temp_free_i32(fp0
);
7667 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7672 int l1
= gen_new_label();
7676 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7678 fp0
= tcg_temp_new_i32();
7679 gen_load_fpr32(fp0
, fs
);
7680 gen_store_fpr32(fp0
, fd
);
7681 tcg_temp_free_i32(fp0
);
7688 int l1
= gen_new_label();
7692 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7693 fp0
= tcg_temp_new_i32();
7694 gen_load_fpr32(fp0
, fs
);
7695 gen_store_fpr32(fp0
, fd
);
7696 tcg_temp_free_i32(fp0
);
7705 TCGv_i32 fp0
= tcg_temp_new_i32();
7707 gen_load_fpr32(fp0
, fs
);
7708 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7709 gen_store_fpr32(fp0
, fd
);
7710 tcg_temp_free_i32(fp0
);
7717 TCGv_i32 fp0
= tcg_temp_new_i32();
7719 gen_load_fpr32(fp0
, fs
);
7720 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7721 gen_store_fpr32(fp0
, fd
);
7722 tcg_temp_free_i32(fp0
);
7727 check_cp1_64bitmode(ctx
);
7729 TCGv_i32 fp0
= tcg_temp_new_i32();
7730 TCGv_i32 fp1
= tcg_temp_new_i32();
7732 gen_load_fpr32(fp0
, fs
);
7733 gen_load_fpr32(fp1
, ft
);
7734 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7735 tcg_temp_free_i32(fp1
);
7736 gen_store_fpr32(fp0
, fd
);
7737 tcg_temp_free_i32(fp0
);
7742 check_cp1_64bitmode(ctx
);
7744 TCGv_i32 fp0
= tcg_temp_new_i32();
7746 gen_load_fpr32(fp0
, fs
);
7747 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7748 gen_store_fpr32(fp0
, fd
);
7749 tcg_temp_free_i32(fp0
);
7754 check_cp1_64bitmode(ctx
);
7756 TCGv_i32 fp0
= tcg_temp_new_i32();
7758 gen_load_fpr32(fp0
, fs
);
7759 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7760 gen_store_fpr32(fp0
, fd
);
7761 tcg_temp_free_i32(fp0
);
7766 check_cp1_64bitmode(ctx
);
7768 TCGv_i32 fp0
= tcg_temp_new_i32();
7769 TCGv_i32 fp1
= tcg_temp_new_i32();
7771 gen_load_fpr32(fp0
, fs
);
7772 gen_load_fpr32(fp1
, ft
);
7773 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7774 tcg_temp_free_i32(fp1
);
7775 gen_store_fpr32(fp0
, fd
);
7776 tcg_temp_free_i32(fp0
);
7781 check_cp1_registers(ctx
, fd
);
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_cvtd_s(fp64
, cpu_env
, fp32
);
7788 tcg_temp_free_i32(fp32
);
7789 gen_store_fpr64(ctx
, fp64
, fd
);
7790 tcg_temp_free_i64(fp64
);
7796 TCGv_i32 fp0
= tcg_temp_new_i32();
7798 gen_load_fpr32(fp0
, fs
);
7799 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7800 gen_store_fpr32(fp0
, fd
);
7801 tcg_temp_free_i32(fp0
);
7806 check_cp1_64bitmode(ctx
);
7808 TCGv_i32 fp32
= tcg_temp_new_i32();
7809 TCGv_i64 fp64
= tcg_temp_new_i64();
7811 gen_load_fpr32(fp32
, fs
);
7812 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7813 tcg_temp_free_i32(fp32
);
7814 gen_store_fpr64(ctx
, fp64
, fd
);
7815 tcg_temp_free_i64(fp64
);
7820 check_cp1_64bitmode(ctx
);
7822 TCGv_i64 fp64
= tcg_temp_new_i64();
7823 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7824 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7826 gen_load_fpr32(fp32_0
, fs
);
7827 gen_load_fpr32(fp32_1
, ft
);
7828 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7829 tcg_temp_free_i32(fp32_1
);
7830 tcg_temp_free_i32(fp32_0
);
7831 gen_store_fpr64(ctx
, fp64
, fd
);
7832 tcg_temp_free_i64(fp64
);
7845 case OPC_CMP_NGLE_S
:
7852 if (ctx
->opcode
& (1 << 6)) {
7853 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7854 opn
= condnames_abs
[func
-48];
7856 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7857 opn
= condnames
[func
-48];
7861 check_cp1_registers(ctx
, fs
| ft
| fd
);
7863 TCGv_i64 fp0
= tcg_temp_new_i64();
7864 TCGv_i64 fp1
= tcg_temp_new_i64();
7866 gen_load_fpr64(ctx
, fp0
, fs
);
7867 gen_load_fpr64(ctx
, fp1
, ft
);
7868 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7869 tcg_temp_free_i64(fp1
);
7870 gen_store_fpr64(ctx
, fp0
, fd
);
7871 tcg_temp_free_i64(fp0
);
7877 check_cp1_registers(ctx
, fs
| ft
| fd
);
7879 TCGv_i64 fp0
= tcg_temp_new_i64();
7880 TCGv_i64 fp1
= tcg_temp_new_i64();
7882 gen_load_fpr64(ctx
, fp0
, fs
);
7883 gen_load_fpr64(ctx
, fp1
, ft
);
7884 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7885 tcg_temp_free_i64(fp1
);
7886 gen_store_fpr64(ctx
, fp0
, fd
);
7887 tcg_temp_free_i64(fp0
);
7893 check_cp1_registers(ctx
, fs
| ft
| fd
);
7895 TCGv_i64 fp0
= tcg_temp_new_i64();
7896 TCGv_i64 fp1
= tcg_temp_new_i64();
7898 gen_load_fpr64(ctx
, fp0
, fs
);
7899 gen_load_fpr64(ctx
, fp1
, ft
);
7900 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7901 tcg_temp_free_i64(fp1
);
7902 gen_store_fpr64(ctx
, fp0
, fd
);
7903 tcg_temp_free_i64(fp0
);
7909 check_cp1_registers(ctx
, fs
| ft
| fd
);
7911 TCGv_i64 fp0
= tcg_temp_new_i64();
7912 TCGv_i64 fp1
= tcg_temp_new_i64();
7914 gen_load_fpr64(ctx
, fp0
, fs
);
7915 gen_load_fpr64(ctx
, fp1
, ft
);
7916 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7917 tcg_temp_free_i64(fp1
);
7918 gen_store_fpr64(ctx
, fp0
, fd
);
7919 tcg_temp_free_i64(fp0
);
7925 check_cp1_registers(ctx
, fs
| fd
);
7927 TCGv_i64 fp0
= tcg_temp_new_i64();
7929 gen_load_fpr64(ctx
, fp0
, fs
);
7930 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7931 gen_store_fpr64(ctx
, fp0
, fd
);
7932 tcg_temp_free_i64(fp0
);
7937 check_cp1_registers(ctx
, fs
| fd
);
7939 TCGv_i64 fp0
= tcg_temp_new_i64();
7941 gen_load_fpr64(ctx
, fp0
, fs
);
7942 gen_helper_float_abs_d(fp0
, fp0
);
7943 gen_store_fpr64(ctx
, fp0
, fd
);
7944 tcg_temp_free_i64(fp0
);
7949 check_cp1_registers(ctx
, fs
| fd
);
7951 TCGv_i64 fp0
= tcg_temp_new_i64();
7953 gen_load_fpr64(ctx
, fp0
, fs
);
7954 gen_store_fpr64(ctx
, fp0
, fd
);
7955 tcg_temp_free_i64(fp0
);
7960 check_cp1_registers(ctx
, fs
| fd
);
7962 TCGv_i64 fp0
= tcg_temp_new_i64();
7964 gen_load_fpr64(ctx
, fp0
, fs
);
7965 gen_helper_float_chs_d(fp0
, fp0
);
7966 gen_store_fpr64(ctx
, fp0
, fd
);
7967 tcg_temp_free_i64(fp0
);
7972 check_cp1_64bitmode(ctx
);
7974 TCGv_i64 fp0
= tcg_temp_new_i64();
7976 gen_load_fpr64(ctx
, fp0
, fs
);
7977 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7978 gen_store_fpr64(ctx
, fp0
, fd
);
7979 tcg_temp_free_i64(fp0
);
7984 check_cp1_64bitmode(ctx
);
7986 TCGv_i64 fp0
= tcg_temp_new_i64();
7988 gen_load_fpr64(ctx
, fp0
, fs
);
7989 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7990 gen_store_fpr64(ctx
, fp0
, fd
);
7991 tcg_temp_free_i64(fp0
);
7996 check_cp1_64bitmode(ctx
);
7998 TCGv_i64 fp0
= tcg_temp_new_i64();
8000 gen_load_fpr64(ctx
, fp0
, fs
);
8001 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8002 gen_store_fpr64(ctx
, fp0
, fd
);
8003 tcg_temp_free_i64(fp0
);
8008 check_cp1_64bitmode(ctx
);
8010 TCGv_i64 fp0
= tcg_temp_new_i64();
8012 gen_load_fpr64(ctx
, fp0
, fs
);
8013 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8014 gen_store_fpr64(ctx
, fp0
, fd
);
8015 tcg_temp_free_i64(fp0
);
8020 check_cp1_registers(ctx
, fs
);
8022 TCGv_i32 fp32
= tcg_temp_new_i32();
8023 TCGv_i64 fp64
= tcg_temp_new_i64();
8025 gen_load_fpr64(ctx
, fp64
, fs
);
8026 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8027 tcg_temp_free_i64(fp64
);
8028 gen_store_fpr32(fp32
, fd
);
8029 tcg_temp_free_i32(fp32
);
8034 check_cp1_registers(ctx
, fs
);
8036 TCGv_i32 fp32
= tcg_temp_new_i32();
8037 TCGv_i64 fp64
= tcg_temp_new_i64();
8039 gen_load_fpr64(ctx
, fp64
, fs
);
8040 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8041 tcg_temp_free_i64(fp64
);
8042 gen_store_fpr32(fp32
, fd
);
8043 tcg_temp_free_i32(fp32
);
8048 check_cp1_registers(ctx
, fs
);
8050 TCGv_i32 fp32
= tcg_temp_new_i32();
8051 TCGv_i64 fp64
= tcg_temp_new_i64();
8053 gen_load_fpr64(ctx
, fp64
, fs
);
8054 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8055 tcg_temp_free_i64(fp64
);
8056 gen_store_fpr32(fp32
, fd
);
8057 tcg_temp_free_i32(fp32
);
8062 check_cp1_registers(ctx
, fs
);
8064 TCGv_i32 fp32
= tcg_temp_new_i32();
8065 TCGv_i64 fp64
= tcg_temp_new_i64();
8067 gen_load_fpr64(ctx
, fp64
, fs
);
8068 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8069 tcg_temp_free_i64(fp64
);
8070 gen_store_fpr32(fp32
, fd
);
8071 tcg_temp_free_i32(fp32
);
8076 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8081 int l1
= gen_new_label();
8085 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8087 fp0
= tcg_temp_new_i64();
8088 gen_load_fpr64(ctx
, fp0
, fs
);
8089 gen_store_fpr64(ctx
, fp0
, fd
);
8090 tcg_temp_free_i64(fp0
);
8097 int l1
= gen_new_label();
8101 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8102 fp0
= tcg_temp_new_i64();
8103 gen_load_fpr64(ctx
, fp0
, fs
);
8104 gen_store_fpr64(ctx
, fp0
, fd
);
8105 tcg_temp_free_i64(fp0
);
8112 check_cp1_64bitmode(ctx
);
8114 TCGv_i64 fp0
= tcg_temp_new_i64();
8116 gen_load_fpr64(ctx
, fp0
, fs
);
8117 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8118 gen_store_fpr64(ctx
, fp0
, fd
);
8119 tcg_temp_free_i64(fp0
);
8124 check_cp1_64bitmode(ctx
);
8126 TCGv_i64 fp0
= tcg_temp_new_i64();
8128 gen_load_fpr64(ctx
, fp0
, fs
);
8129 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8130 gen_store_fpr64(ctx
, fp0
, fd
);
8131 tcg_temp_free_i64(fp0
);
8136 check_cp1_64bitmode(ctx
);
8138 TCGv_i64 fp0
= tcg_temp_new_i64();
8139 TCGv_i64 fp1
= tcg_temp_new_i64();
8141 gen_load_fpr64(ctx
, fp0
, fs
);
8142 gen_load_fpr64(ctx
, fp1
, ft
);
8143 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8144 tcg_temp_free_i64(fp1
);
8145 gen_store_fpr64(ctx
, fp0
, fd
);
8146 tcg_temp_free_i64(fp0
);
8151 check_cp1_64bitmode(ctx
);
8153 TCGv_i64 fp0
= tcg_temp_new_i64();
8155 gen_load_fpr64(ctx
, fp0
, fs
);
8156 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8157 gen_store_fpr64(ctx
, fp0
, fd
);
8158 tcg_temp_free_i64(fp0
);
8163 check_cp1_64bitmode(ctx
);
8165 TCGv_i64 fp0
= tcg_temp_new_i64();
8167 gen_load_fpr64(ctx
, fp0
, fs
);
8168 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8169 gen_store_fpr64(ctx
, fp0
, fd
);
8170 tcg_temp_free_i64(fp0
);
8175 check_cp1_64bitmode(ctx
);
8177 TCGv_i64 fp0
= tcg_temp_new_i64();
8178 TCGv_i64 fp1
= tcg_temp_new_i64();
8180 gen_load_fpr64(ctx
, fp0
, fs
);
8181 gen_load_fpr64(ctx
, fp1
, ft
);
8182 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8183 tcg_temp_free_i64(fp1
);
8184 gen_store_fpr64(ctx
, fp0
, fd
);
8185 tcg_temp_free_i64(fp0
);
8198 case OPC_CMP_NGLE_D
:
8205 if (ctx
->opcode
& (1 << 6)) {
8206 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8207 opn
= condnames_abs
[func
-48];
8209 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8210 opn
= condnames
[func
-48];
8214 check_cp1_registers(ctx
, fs
);
8216 TCGv_i32 fp32
= tcg_temp_new_i32();
8217 TCGv_i64 fp64
= tcg_temp_new_i64();
8219 gen_load_fpr64(ctx
, fp64
, fs
);
8220 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8221 tcg_temp_free_i64(fp64
);
8222 gen_store_fpr32(fp32
, fd
);
8223 tcg_temp_free_i32(fp32
);
8228 check_cp1_registers(ctx
, fs
);
8230 TCGv_i32 fp32
= tcg_temp_new_i32();
8231 TCGv_i64 fp64
= tcg_temp_new_i64();
8233 gen_load_fpr64(ctx
, fp64
, fs
);
8234 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8235 tcg_temp_free_i64(fp64
);
8236 gen_store_fpr32(fp32
, fd
);
8237 tcg_temp_free_i32(fp32
);
8242 check_cp1_64bitmode(ctx
);
8244 TCGv_i64 fp0
= tcg_temp_new_i64();
8246 gen_load_fpr64(ctx
, fp0
, fs
);
8247 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8248 gen_store_fpr64(ctx
, fp0
, fd
);
8249 tcg_temp_free_i64(fp0
);
8255 TCGv_i32 fp0
= tcg_temp_new_i32();
8257 gen_load_fpr32(fp0
, fs
);
8258 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8259 gen_store_fpr32(fp0
, fd
);
8260 tcg_temp_free_i32(fp0
);
8265 check_cp1_registers(ctx
, fd
);
8267 TCGv_i32 fp32
= tcg_temp_new_i32();
8268 TCGv_i64 fp64
= tcg_temp_new_i64();
8270 gen_load_fpr32(fp32
, fs
);
8271 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8272 tcg_temp_free_i32(fp32
);
8273 gen_store_fpr64(ctx
, fp64
, fd
);
8274 tcg_temp_free_i64(fp64
);
8279 check_cp1_64bitmode(ctx
);
8281 TCGv_i32 fp32
= tcg_temp_new_i32();
8282 TCGv_i64 fp64
= tcg_temp_new_i64();
8284 gen_load_fpr64(ctx
, fp64
, fs
);
8285 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8286 tcg_temp_free_i64(fp64
);
8287 gen_store_fpr32(fp32
, fd
);
8288 tcg_temp_free_i32(fp32
);
8293 check_cp1_64bitmode(ctx
);
8295 TCGv_i64 fp0
= tcg_temp_new_i64();
8297 gen_load_fpr64(ctx
, fp0
, fs
);
8298 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8299 gen_store_fpr64(ctx
, fp0
, fd
);
8300 tcg_temp_free_i64(fp0
);
8305 check_cp1_64bitmode(ctx
);
8307 TCGv_i64 fp0
= tcg_temp_new_i64();
8309 gen_load_fpr64(ctx
, fp0
, fs
);
8310 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8311 gen_store_fpr64(ctx
, fp0
, fd
);
8312 tcg_temp_free_i64(fp0
);
8317 check_cp1_64bitmode(ctx
);
8319 TCGv_i64 fp0
= tcg_temp_new_i64();
8320 TCGv_i64 fp1
= tcg_temp_new_i64();
8322 gen_load_fpr64(ctx
, fp0
, fs
);
8323 gen_load_fpr64(ctx
, fp1
, ft
);
8324 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8325 tcg_temp_free_i64(fp1
);
8326 gen_store_fpr64(ctx
, fp0
, fd
);
8327 tcg_temp_free_i64(fp0
);
8332 check_cp1_64bitmode(ctx
);
8334 TCGv_i64 fp0
= tcg_temp_new_i64();
8335 TCGv_i64 fp1
= tcg_temp_new_i64();
8337 gen_load_fpr64(ctx
, fp0
, fs
);
8338 gen_load_fpr64(ctx
, fp1
, ft
);
8339 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8340 tcg_temp_free_i64(fp1
);
8341 gen_store_fpr64(ctx
, fp0
, fd
);
8342 tcg_temp_free_i64(fp0
);
8347 check_cp1_64bitmode(ctx
);
8349 TCGv_i64 fp0
= tcg_temp_new_i64();
8350 TCGv_i64 fp1
= tcg_temp_new_i64();
8352 gen_load_fpr64(ctx
, fp0
, fs
);
8353 gen_load_fpr64(ctx
, fp1
, ft
);
8354 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8355 tcg_temp_free_i64(fp1
);
8356 gen_store_fpr64(ctx
, fp0
, fd
);
8357 tcg_temp_free_i64(fp0
);
8362 check_cp1_64bitmode(ctx
);
8364 TCGv_i64 fp0
= tcg_temp_new_i64();
8366 gen_load_fpr64(ctx
, fp0
, fs
);
8367 gen_helper_float_abs_ps(fp0
, fp0
);
8368 gen_store_fpr64(ctx
, fp0
, fd
);
8369 tcg_temp_free_i64(fp0
);
8374 check_cp1_64bitmode(ctx
);
8376 TCGv_i64 fp0
= tcg_temp_new_i64();
8378 gen_load_fpr64(ctx
, fp0
, fs
);
8379 gen_store_fpr64(ctx
, fp0
, fd
);
8380 tcg_temp_free_i64(fp0
);
8385 check_cp1_64bitmode(ctx
);
8387 TCGv_i64 fp0
= tcg_temp_new_i64();
8389 gen_load_fpr64(ctx
, fp0
, fs
);
8390 gen_helper_float_chs_ps(fp0
, fp0
);
8391 gen_store_fpr64(ctx
, fp0
, fd
);
8392 tcg_temp_free_i64(fp0
);
8397 check_cp1_64bitmode(ctx
);
8398 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8402 check_cp1_64bitmode(ctx
);
8404 int l1
= gen_new_label();
8408 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8409 fp0
= tcg_temp_new_i64();
8410 gen_load_fpr64(ctx
, fp0
, fs
);
8411 gen_store_fpr64(ctx
, fp0
, fd
);
8412 tcg_temp_free_i64(fp0
);
8418 check_cp1_64bitmode(ctx
);
8420 int l1
= gen_new_label();
8424 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8425 fp0
= tcg_temp_new_i64();
8426 gen_load_fpr64(ctx
, fp0
, fs
);
8427 gen_store_fpr64(ctx
, fp0
, fd
);
8428 tcg_temp_free_i64(fp0
);
8435 check_cp1_64bitmode(ctx
);
8437 TCGv_i64 fp0
= tcg_temp_new_i64();
8438 TCGv_i64 fp1
= tcg_temp_new_i64();
8440 gen_load_fpr64(ctx
, fp0
, ft
);
8441 gen_load_fpr64(ctx
, fp1
, fs
);
8442 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8443 tcg_temp_free_i64(fp1
);
8444 gen_store_fpr64(ctx
, fp0
, fd
);
8445 tcg_temp_free_i64(fp0
);
8450 check_cp1_64bitmode(ctx
);
8452 TCGv_i64 fp0
= tcg_temp_new_i64();
8453 TCGv_i64 fp1
= tcg_temp_new_i64();
8455 gen_load_fpr64(ctx
, fp0
, ft
);
8456 gen_load_fpr64(ctx
, fp1
, fs
);
8457 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8458 tcg_temp_free_i64(fp1
);
8459 gen_store_fpr64(ctx
, fp0
, fd
);
8460 tcg_temp_free_i64(fp0
);
8465 check_cp1_64bitmode(ctx
);
8467 TCGv_i64 fp0
= tcg_temp_new_i64();
8468 TCGv_i64 fp1
= tcg_temp_new_i64();
8470 gen_load_fpr64(ctx
, fp0
, fs
);
8471 gen_load_fpr64(ctx
, fp1
, ft
);
8472 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8473 tcg_temp_free_i64(fp1
);
8474 gen_store_fpr64(ctx
, fp0
, fd
);
8475 tcg_temp_free_i64(fp0
);
8480 check_cp1_64bitmode(ctx
);
8482 TCGv_i64 fp0
= tcg_temp_new_i64();
8484 gen_load_fpr64(ctx
, fp0
, fs
);
8485 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8486 gen_store_fpr64(ctx
, fp0
, fd
);
8487 tcg_temp_free_i64(fp0
);
8492 check_cp1_64bitmode(ctx
);
8494 TCGv_i64 fp0
= tcg_temp_new_i64();
8496 gen_load_fpr64(ctx
, fp0
, fs
);
8497 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8498 gen_store_fpr64(ctx
, fp0
, fd
);
8499 tcg_temp_free_i64(fp0
);
8504 check_cp1_64bitmode(ctx
);
8506 TCGv_i64 fp0
= tcg_temp_new_i64();
8507 TCGv_i64 fp1
= tcg_temp_new_i64();
8509 gen_load_fpr64(ctx
, fp0
, fs
);
8510 gen_load_fpr64(ctx
, fp1
, ft
);
8511 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8512 tcg_temp_free_i64(fp1
);
8513 gen_store_fpr64(ctx
, fp0
, fd
);
8514 tcg_temp_free_i64(fp0
);
8519 check_cp1_64bitmode(ctx
);
8521 TCGv_i32 fp0
= tcg_temp_new_i32();
8523 gen_load_fpr32h(fp0
, fs
);
8524 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8525 gen_store_fpr32(fp0
, fd
);
8526 tcg_temp_free_i32(fp0
);
8531 check_cp1_64bitmode(ctx
);
8533 TCGv_i64 fp0
= tcg_temp_new_i64();
8535 gen_load_fpr64(ctx
, fp0
, fs
);
8536 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8537 gen_store_fpr64(ctx
, fp0
, fd
);
8538 tcg_temp_free_i64(fp0
);
8543 check_cp1_64bitmode(ctx
);
8545 TCGv_i32 fp0
= tcg_temp_new_i32();
8547 gen_load_fpr32(fp0
, fs
);
8548 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8549 gen_store_fpr32(fp0
, fd
);
8550 tcg_temp_free_i32(fp0
);
8555 check_cp1_64bitmode(ctx
);
8557 TCGv_i32 fp0
= tcg_temp_new_i32();
8558 TCGv_i32 fp1
= tcg_temp_new_i32();
8560 gen_load_fpr32(fp0
, fs
);
8561 gen_load_fpr32(fp1
, ft
);
8562 gen_store_fpr32h(fp0
, fd
);
8563 gen_store_fpr32(fp1
, fd
);
8564 tcg_temp_free_i32(fp0
);
8565 tcg_temp_free_i32(fp1
);
8570 check_cp1_64bitmode(ctx
);
8572 TCGv_i32 fp0
= tcg_temp_new_i32();
8573 TCGv_i32 fp1
= tcg_temp_new_i32();
8575 gen_load_fpr32(fp0
, fs
);
8576 gen_load_fpr32h(fp1
, ft
);
8577 gen_store_fpr32(fp1
, fd
);
8578 gen_store_fpr32h(fp0
, fd
);
8579 tcg_temp_free_i32(fp0
);
8580 tcg_temp_free_i32(fp1
);
8585 check_cp1_64bitmode(ctx
);
8587 TCGv_i32 fp0
= tcg_temp_new_i32();
8588 TCGv_i32 fp1
= tcg_temp_new_i32();
8590 gen_load_fpr32h(fp0
, fs
);
8591 gen_load_fpr32(fp1
, ft
);
8592 gen_store_fpr32(fp1
, fd
);
8593 gen_store_fpr32h(fp0
, fd
);
8594 tcg_temp_free_i32(fp0
);
8595 tcg_temp_free_i32(fp1
);
8600 check_cp1_64bitmode(ctx
);
8602 TCGv_i32 fp0
= tcg_temp_new_i32();
8603 TCGv_i32 fp1
= tcg_temp_new_i32();
8605 gen_load_fpr32h(fp0
, fs
);
8606 gen_load_fpr32h(fp1
, ft
);
8607 gen_store_fpr32(fp1
, fd
);
8608 gen_store_fpr32h(fp0
, fd
);
8609 tcg_temp_free_i32(fp0
);
8610 tcg_temp_free_i32(fp1
);
8617 case OPC_CMP_UEQ_PS
:
8618 case OPC_CMP_OLT_PS
:
8619 case OPC_CMP_ULT_PS
:
8620 case OPC_CMP_OLE_PS
:
8621 case OPC_CMP_ULE_PS
:
8623 case OPC_CMP_NGLE_PS
:
8624 case OPC_CMP_SEQ_PS
:
8625 case OPC_CMP_NGL_PS
:
8627 case OPC_CMP_NGE_PS
:
8629 case OPC_CMP_NGT_PS
:
8630 if (ctx
->opcode
& (1 << 6)) {
8631 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8632 opn
= condnames_abs
[func
-48];
8634 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8635 opn
= condnames
[func
-48];
8640 generate_exception (ctx
, EXCP_RI
);
8643 (void)opn
; /* avoid a compiler warning */
8646 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8649 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8652 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8657 /* Coprocessor 3 (FPU) */
8658 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8659 int fd
, int fs
, int base
, int index
)
8661 const char *opn
= "extended float load/store";
8663 TCGv t0
= tcg_temp_new();
8666 gen_load_gpr(t0
, index
);
8667 } else if (index
== 0) {
8668 gen_load_gpr(t0
, base
);
8670 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8672 /* Don't do NOP if destination is zero: we must perform the actual
8674 save_cpu_state(ctx
, 0);
8679 TCGv_i32 fp0
= tcg_temp_new_i32();
8681 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
8682 tcg_gen_trunc_tl_i32(fp0
, t0
);
8683 gen_store_fpr32(fp0
, fd
);
8684 tcg_temp_free_i32(fp0
);
8690 check_cp1_registers(ctx
, fd
);
8692 TCGv_i64 fp0
= tcg_temp_new_i64();
8694 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8695 gen_store_fpr64(ctx
, fp0
, fd
);
8696 tcg_temp_free_i64(fp0
);
8701 check_cp1_64bitmode(ctx
);
8702 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8704 TCGv_i64 fp0
= tcg_temp_new_i64();
8706 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8707 gen_store_fpr64(ctx
, fp0
, fd
);
8708 tcg_temp_free_i64(fp0
);
8715 TCGv_i32 fp0
= tcg_temp_new_i32();
8716 TCGv t1
= tcg_temp_new();
8718 gen_load_fpr32(fp0
, fs
);
8719 tcg_gen_extu_i32_tl(t1
, fp0
);
8720 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
8721 tcg_temp_free_i32(fp0
);
8729 check_cp1_registers(ctx
, fs
);
8731 TCGv_i64 fp0
= tcg_temp_new_i64();
8733 gen_load_fpr64(ctx
, fp0
, fs
);
8734 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8735 tcg_temp_free_i64(fp0
);
8741 check_cp1_64bitmode(ctx
);
8742 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8744 TCGv_i64 fp0
= tcg_temp_new_i64();
8746 gen_load_fpr64(ctx
, fp0
, fs
);
8747 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8748 tcg_temp_free_i64(fp0
);
8755 (void)opn
; (void)store
; /* avoid compiler warnings */
8756 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8757 regnames
[index
], regnames
[base
]);
8760 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8761 int fd
, int fr
, int fs
, int ft
)
8763 const char *opn
= "flt3_arith";
8767 check_cp1_64bitmode(ctx
);
8769 TCGv t0
= tcg_temp_local_new();
8770 TCGv_i32 fp
= tcg_temp_new_i32();
8771 TCGv_i32 fph
= tcg_temp_new_i32();
8772 int l1
= gen_new_label();
8773 int l2
= gen_new_label();
8775 gen_load_gpr(t0
, fr
);
8776 tcg_gen_andi_tl(t0
, t0
, 0x7);
8778 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8779 gen_load_fpr32(fp
, fs
);
8780 gen_load_fpr32h(fph
, fs
);
8781 gen_store_fpr32(fp
, fd
);
8782 gen_store_fpr32h(fph
, fd
);
8785 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8787 #ifdef TARGET_WORDS_BIGENDIAN
8788 gen_load_fpr32(fp
, fs
);
8789 gen_load_fpr32h(fph
, ft
);
8790 gen_store_fpr32h(fp
, fd
);
8791 gen_store_fpr32(fph
, fd
);
8793 gen_load_fpr32h(fph
, fs
);
8794 gen_load_fpr32(fp
, ft
);
8795 gen_store_fpr32(fph
, fd
);
8796 gen_store_fpr32h(fp
, fd
);
8799 tcg_temp_free_i32(fp
);
8800 tcg_temp_free_i32(fph
);
8807 TCGv_i32 fp0
= tcg_temp_new_i32();
8808 TCGv_i32 fp1
= tcg_temp_new_i32();
8809 TCGv_i32 fp2
= tcg_temp_new_i32();
8811 gen_load_fpr32(fp0
, fs
);
8812 gen_load_fpr32(fp1
, ft
);
8813 gen_load_fpr32(fp2
, fr
);
8814 gen_helper_float_muladd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8815 tcg_temp_free_i32(fp0
);
8816 tcg_temp_free_i32(fp1
);
8817 gen_store_fpr32(fp2
, fd
);
8818 tcg_temp_free_i32(fp2
);
8824 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8826 TCGv_i64 fp0
= tcg_temp_new_i64();
8827 TCGv_i64 fp1
= tcg_temp_new_i64();
8828 TCGv_i64 fp2
= tcg_temp_new_i64();
8830 gen_load_fpr64(ctx
, fp0
, fs
);
8831 gen_load_fpr64(ctx
, fp1
, ft
);
8832 gen_load_fpr64(ctx
, fp2
, fr
);
8833 gen_helper_float_muladd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8834 tcg_temp_free_i64(fp0
);
8835 tcg_temp_free_i64(fp1
);
8836 gen_store_fpr64(ctx
, fp2
, fd
);
8837 tcg_temp_free_i64(fp2
);
8842 check_cp1_64bitmode(ctx
);
8844 TCGv_i64 fp0
= tcg_temp_new_i64();
8845 TCGv_i64 fp1
= tcg_temp_new_i64();
8846 TCGv_i64 fp2
= tcg_temp_new_i64();
8848 gen_load_fpr64(ctx
, fp0
, fs
);
8849 gen_load_fpr64(ctx
, fp1
, ft
);
8850 gen_load_fpr64(ctx
, fp2
, fr
);
8851 gen_helper_float_muladd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8852 tcg_temp_free_i64(fp0
);
8853 tcg_temp_free_i64(fp1
);
8854 gen_store_fpr64(ctx
, fp2
, fd
);
8855 tcg_temp_free_i64(fp2
);
8862 TCGv_i32 fp0
= tcg_temp_new_i32();
8863 TCGv_i32 fp1
= tcg_temp_new_i32();
8864 TCGv_i32 fp2
= tcg_temp_new_i32();
8866 gen_load_fpr32(fp0
, fs
);
8867 gen_load_fpr32(fp1
, ft
);
8868 gen_load_fpr32(fp2
, fr
);
8869 gen_helper_float_mulsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8870 tcg_temp_free_i32(fp0
);
8871 tcg_temp_free_i32(fp1
);
8872 gen_store_fpr32(fp2
, fd
);
8873 tcg_temp_free_i32(fp2
);
8879 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8881 TCGv_i64 fp0
= tcg_temp_new_i64();
8882 TCGv_i64 fp1
= tcg_temp_new_i64();
8883 TCGv_i64 fp2
= tcg_temp_new_i64();
8885 gen_load_fpr64(ctx
, fp0
, fs
);
8886 gen_load_fpr64(ctx
, fp1
, ft
);
8887 gen_load_fpr64(ctx
, fp2
, fr
);
8888 gen_helper_float_mulsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8889 tcg_temp_free_i64(fp0
);
8890 tcg_temp_free_i64(fp1
);
8891 gen_store_fpr64(ctx
, fp2
, fd
);
8892 tcg_temp_free_i64(fp2
);
8897 check_cp1_64bitmode(ctx
);
8899 TCGv_i64 fp0
= tcg_temp_new_i64();
8900 TCGv_i64 fp1
= tcg_temp_new_i64();
8901 TCGv_i64 fp2
= tcg_temp_new_i64();
8903 gen_load_fpr64(ctx
, fp0
, fs
);
8904 gen_load_fpr64(ctx
, fp1
, ft
);
8905 gen_load_fpr64(ctx
, fp2
, fr
);
8906 gen_helper_float_mulsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8907 tcg_temp_free_i64(fp0
);
8908 tcg_temp_free_i64(fp1
);
8909 gen_store_fpr64(ctx
, fp2
, fd
);
8910 tcg_temp_free_i64(fp2
);
8917 TCGv_i32 fp0
= tcg_temp_new_i32();
8918 TCGv_i32 fp1
= tcg_temp_new_i32();
8919 TCGv_i32 fp2
= tcg_temp_new_i32();
8921 gen_load_fpr32(fp0
, fs
);
8922 gen_load_fpr32(fp1
, ft
);
8923 gen_load_fpr32(fp2
, fr
);
8924 gen_helper_float_nmuladd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8925 tcg_temp_free_i32(fp0
);
8926 tcg_temp_free_i32(fp1
);
8927 gen_store_fpr32(fp2
, fd
);
8928 tcg_temp_free_i32(fp2
);
8934 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8936 TCGv_i64 fp0
= tcg_temp_new_i64();
8937 TCGv_i64 fp1
= tcg_temp_new_i64();
8938 TCGv_i64 fp2
= tcg_temp_new_i64();
8940 gen_load_fpr64(ctx
, fp0
, fs
);
8941 gen_load_fpr64(ctx
, fp1
, ft
);
8942 gen_load_fpr64(ctx
, fp2
, fr
);
8943 gen_helper_float_nmuladd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8944 tcg_temp_free_i64(fp0
);
8945 tcg_temp_free_i64(fp1
);
8946 gen_store_fpr64(ctx
, fp2
, fd
);
8947 tcg_temp_free_i64(fp2
);
8952 check_cp1_64bitmode(ctx
);
8954 TCGv_i64 fp0
= tcg_temp_new_i64();
8955 TCGv_i64 fp1
= tcg_temp_new_i64();
8956 TCGv_i64 fp2
= tcg_temp_new_i64();
8958 gen_load_fpr64(ctx
, fp0
, fs
);
8959 gen_load_fpr64(ctx
, fp1
, ft
);
8960 gen_load_fpr64(ctx
, fp2
, fr
);
8961 gen_helper_float_nmuladd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8962 tcg_temp_free_i64(fp0
);
8963 tcg_temp_free_i64(fp1
);
8964 gen_store_fpr64(ctx
, fp2
, fd
);
8965 tcg_temp_free_i64(fp2
);
8972 TCGv_i32 fp0
= tcg_temp_new_i32();
8973 TCGv_i32 fp1
= tcg_temp_new_i32();
8974 TCGv_i32 fp2
= tcg_temp_new_i32();
8976 gen_load_fpr32(fp0
, fs
);
8977 gen_load_fpr32(fp1
, ft
);
8978 gen_load_fpr32(fp2
, fr
);
8979 gen_helper_float_nmulsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8980 tcg_temp_free_i32(fp0
);
8981 tcg_temp_free_i32(fp1
);
8982 gen_store_fpr32(fp2
, fd
);
8983 tcg_temp_free_i32(fp2
);
8989 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8991 TCGv_i64 fp0
= tcg_temp_new_i64();
8992 TCGv_i64 fp1
= tcg_temp_new_i64();
8993 TCGv_i64 fp2
= tcg_temp_new_i64();
8995 gen_load_fpr64(ctx
, fp0
, fs
);
8996 gen_load_fpr64(ctx
, fp1
, ft
);
8997 gen_load_fpr64(ctx
, fp2
, fr
);
8998 gen_helper_float_nmulsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8999 tcg_temp_free_i64(fp0
);
9000 tcg_temp_free_i64(fp1
);
9001 gen_store_fpr64(ctx
, fp2
, fd
);
9002 tcg_temp_free_i64(fp2
);
9007 check_cp1_64bitmode(ctx
);
9009 TCGv_i64 fp0
= tcg_temp_new_i64();
9010 TCGv_i64 fp1
= tcg_temp_new_i64();
9011 TCGv_i64 fp2
= tcg_temp_new_i64();
9013 gen_load_fpr64(ctx
, fp0
, fs
);
9014 gen_load_fpr64(ctx
, fp1
, ft
);
9015 gen_load_fpr64(ctx
, fp2
, fr
);
9016 gen_helper_float_nmulsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9017 tcg_temp_free_i64(fp0
);
9018 tcg_temp_free_i64(fp1
);
9019 gen_store_fpr64(ctx
, fp2
, fd
);
9020 tcg_temp_free_i64(fp2
);
9026 generate_exception (ctx
, EXCP_RI
);
9029 (void)opn
; /* avoid a compiler warning */
9030 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9031 fregnames
[fs
], fregnames
[ft
]);
9035 gen_rdhwr (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
)
9039 #if !defined(CONFIG_USER_ONLY)
9040 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9041 Therefore only check the ISA in system mode. */
9042 check_insn(env
, ctx
, ISA_MIPS32R2
);
9044 t0
= tcg_temp_new();
9048 save_cpu_state(ctx
, 1);
9049 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9050 gen_store_gpr(t0
, rt
);
9053 save_cpu_state(ctx
, 1);
9054 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9055 gen_store_gpr(t0
, rt
);
9058 save_cpu_state(ctx
, 1);
9059 gen_helper_rdhwr_cc(t0
, cpu_env
);
9060 gen_store_gpr(t0
, rt
);
9063 save_cpu_state(ctx
, 1);
9064 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9065 gen_store_gpr(t0
, rt
);
9068 #if defined(CONFIG_USER_ONLY)
9069 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9070 gen_store_gpr(t0
, rt
);
9073 /* XXX: Some CPUs implement this in hardware.
9074 Not supported yet. */
9076 default: /* Invalid */
9077 MIPS_INVAL("rdhwr");
9078 generate_exception(ctx
, EXCP_RI
);
9084 static void handle_delay_slot (CPUMIPSState
*env
, DisasContext
*ctx
,
9087 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9088 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9089 /* Branches completion */
9090 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9091 ctx
->bstate
= BS_BRANCH
;
9092 save_cpu_state(ctx
, 0);
9093 /* FIXME: Need to clear can_do_io. */
9094 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9096 /* unconditional branch */
9097 MIPS_DEBUG("unconditional branch");
9098 if (proc_hflags
& MIPS_HFLAG_BX
) {
9099 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9101 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9104 /* blikely taken case */
9105 MIPS_DEBUG("blikely branch taken");
9106 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9109 /* Conditional branch */
9110 MIPS_DEBUG("conditional branch");
9112 int l1
= gen_new_label();
9114 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9115 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9117 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9121 /* unconditional branch to register */
9122 MIPS_DEBUG("branch to register");
9123 if (env
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9124 TCGv t0
= tcg_temp_new();
9125 TCGv_i32 t1
= tcg_temp_new_i32();
9127 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9128 tcg_gen_trunc_tl_i32(t1
, t0
);
9130 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9131 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9132 tcg_gen_or_i32(hflags
, hflags
, t1
);
9133 tcg_temp_free_i32(t1
);
9135 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9137 tcg_gen_mov_tl(cpu_PC
, btarget
);
9139 if (ctx
->singlestep_enabled
) {
9140 save_cpu_state(ctx
, 0);
9141 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9146 MIPS_DEBUG("unknown branch");
9152 /* ISA extensions (ASEs) */
9153 /* MIPS16 extension to MIPS32 */
9155 /* MIPS16 major opcodes */
9157 M16_OPC_ADDIUSP
= 0x00,
9158 M16_OPC_ADDIUPC
= 0x01,
9161 M16_OPC_BEQZ
= 0x04,
9162 M16_OPC_BNEQZ
= 0x05,
9163 M16_OPC_SHIFT
= 0x06,
9165 M16_OPC_RRIA
= 0x08,
9166 M16_OPC_ADDIU8
= 0x09,
9167 M16_OPC_SLTI
= 0x0a,
9168 M16_OPC_SLTIU
= 0x0b,
9171 M16_OPC_CMPI
= 0x0e,
9175 M16_OPC_LWSP
= 0x12,
9179 M16_OPC_LWPC
= 0x16,
9183 M16_OPC_SWSP
= 0x1a,
9187 M16_OPC_EXTEND
= 0x1e,
9191 /* I8 funct field */
9210 /* RR funct field */
9244 /* I64 funct field */
9256 /* RR ry field for CNVT */
9258 RR_RY_CNVT_ZEB
= 0x0,
9259 RR_RY_CNVT_ZEH
= 0x1,
9260 RR_RY_CNVT_ZEW
= 0x2,
9261 RR_RY_CNVT_SEB
= 0x4,
9262 RR_RY_CNVT_SEH
= 0x5,
9263 RR_RY_CNVT_SEW
= 0x6,
9266 static int xlat (int r
)
9268 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9273 static void gen_mips16_save (DisasContext
*ctx
,
9274 int xsregs
, int aregs
,
9275 int do_ra
, int do_s0
, int do_s1
,
9278 TCGv t0
= tcg_temp_new();
9279 TCGv t1
= tcg_temp_new();
9309 generate_exception(ctx
, EXCP_RI
);
9315 gen_base_offset_addr(ctx
, t0
, 29, 12);
9316 gen_load_gpr(t1
, 7);
9317 op_st_sw(t1
, t0
, ctx
);
9320 gen_base_offset_addr(ctx
, t0
, 29, 8);
9321 gen_load_gpr(t1
, 6);
9322 op_st_sw(t1
, t0
, ctx
);
9325 gen_base_offset_addr(ctx
, t0
, 29, 4);
9326 gen_load_gpr(t1
, 5);
9327 op_st_sw(t1
, t0
, ctx
);
9330 gen_base_offset_addr(ctx
, t0
, 29, 0);
9331 gen_load_gpr(t1
, 4);
9332 op_st_sw(t1
, t0
, ctx
);
9335 gen_load_gpr(t0
, 29);
9337 #define DECR_AND_STORE(reg) do { \
9338 tcg_gen_subi_tl(t0, t0, 4); \
9339 gen_load_gpr(t1, reg); \
9340 op_st_sw(t1, t0, ctx); \
9404 generate_exception(ctx
, EXCP_RI
);
9420 #undef DECR_AND_STORE
9422 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9427 static void gen_mips16_restore (DisasContext
*ctx
,
9428 int xsregs
, int aregs
,
9429 int do_ra
, int do_s0
, int do_s1
,
9433 TCGv t0
= tcg_temp_new();
9434 TCGv t1
= tcg_temp_new();
9436 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9438 #define DECR_AND_LOAD(reg) do { \
9439 tcg_gen_subi_tl(t0, t0, 4); \
9440 op_ld_lw(t1, t0, ctx); \
9441 gen_store_gpr(t1, reg); \
9505 generate_exception(ctx
, EXCP_RI
);
9521 #undef DECR_AND_LOAD
9523 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9528 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9529 int is_64_bit
, int extended
)
9533 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9534 generate_exception(ctx
, EXCP_RI
);
9538 t0
= tcg_temp_new();
9540 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9541 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9543 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9549 #if defined(TARGET_MIPS64)
9550 static void decode_i64_mips16 (CPUMIPSState
*env
, DisasContext
*ctx
,
9551 int ry
, int funct
, int16_t offset
,
9557 offset
= extended
? offset
: offset
<< 3;
9558 gen_ld(env
, ctx
, OPC_LD
, ry
, 29, offset
);
9562 offset
= extended
? offset
: offset
<< 3;
9563 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9567 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9568 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9572 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9573 gen_arith_imm(env
, ctx
, OPC_DADDIU
, 29, 29, offset
);
9576 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9577 generate_exception(ctx
, EXCP_RI
);
9579 offset
= extended
? offset
: offset
<< 3;
9580 gen_ld(env
, ctx
, OPC_LDPC
, ry
, 0, offset
);
9585 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9586 gen_arith_imm(env
, ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9590 offset
= extended
? offset
: offset
<< 2;
9591 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9595 offset
= extended
? offset
: offset
<< 2;
9596 gen_arith_imm(env
, ctx
, OPC_DADDIU
, ry
, 29, offset
);
9602 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9605 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9606 int op
, rx
, ry
, funct
, sa
;
9607 int16_t imm
, offset
;
9609 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9610 op
= (ctx
->opcode
>> 11) & 0x1f;
9611 sa
= (ctx
->opcode
>> 22) & 0x1f;
9612 funct
= (ctx
->opcode
>> 8) & 0x7;
9613 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9614 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9615 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9616 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9617 | (ctx
->opcode
& 0x1f));
9619 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9622 case M16_OPC_ADDIUSP
:
9623 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rx
, 29, imm
);
9625 case M16_OPC_ADDIUPC
:
9626 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9629 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9630 /* No delay slot, so just process as a normal instruction */
9633 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9634 /* No delay slot, so just process as a normal instruction */
9637 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9638 /* No delay slot, so just process as a normal instruction */
9641 switch (ctx
->opcode
& 0x3) {
9643 gen_shift_imm(env
, ctx
, OPC_SLL
, rx
, ry
, sa
);
9646 #if defined(TARGET_MIPS64)
9648 gen_shift_imm(env
, ctx
, OPC_DSLL
, rx
, ry
, sa
);
9650 generate_exception(ctx
, EXCP_RI
);
9654 gen_shift_imm(env
, ctx
, OPC_SRL
, rx
, ry
, sa
);
9657 gen_shift_imm(env
, ctx
, OPC_SRA
, rx
, ry
, sa
);
9661 #if defined(TARGET_MIPS64)
9664 gen_ld(env
, ctx
, OPC_LD
, ry
, rx
, offset
);
9668 imm
= ctx
->opcode
& 0xf;
9669 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9670 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9671 imm
= (int16_t) (imm
<< 1) >> 1;
9672 if ((ctx
->opcode
>> 4) & 0x1) {
9673 #if defined(TARGET_MIPS64)
9675 gen_arith_imm(env
, ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9677 generate_exception(ctx
, EXCP_RI
);
9680 gen_arith_imm(env
, ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9683 case M16_OPC_ADDIU8
:
9684 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9687 gen_slt_imm(env
, ctx
, OPC_SLTI
, 24, rx
, imm
);
9690 gen_slt_imm(env
, ctx
, OPC_SLTIU
, 24, rx
, imm
);
9695 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9698 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9701 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9704 gen_arith_imm(env
, ctx
, OPC_ADDIU
, 29, 29, imm
);
9708 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9709 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9710 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9711 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9712 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9713 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9714 | (ctx
->opcode
& 0xf)) << 3;
9716 if (ctx
->opcode
& (1 << 7)) {
9717 gen_mips16_save(ctx
, xsregs
, aregs
,
9718 do_ra
, do_s0
, do_s1
,
9721 gen_mips16_restore(ctx
, xsregs
, aregs
,
9722 do_ra
, do_s0
, do_s1
,
9728 generate_exception(ctx
, EXCP_RI
);
9733 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9736 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9738 #if defined(TARGET_MIPS64)
9740 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9744 gen_ld(env
, ctx
, OPC_LB
, ry
, rx
, offset
);
9747 gen_ld(env
, ctx
, OPC_LH
, ry
, rx
, offset
);
9750 gen_ld(env
, ctx
, OPC_LW
, rx
, 29, offset
);
9753 gen_ld(env
, ctx
, OPC_LW
, ry
, rx
, offset
);
9756 gen_ld(env
, ctx
, OPC_LBU
, ry
, rx
, offset
);
9759 gen_ld(env
, ctx
, OPC_LHU
, ry
, rx
, offset
);
9762 gen_ld(env
, ctx
, OPC_LWPC
, rx
, 0, offset
);
9764 #if defined(TARGET_MIPS64)
9766 gen_ld(env
, ctx
, OPC_LWU
, ry
, rx
, offset
);
9770 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9773 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9776 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9779 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9781 #if defined(TARGET_MIPS64)
9783 decode_i64_mips16(env
, ctx
, ry
, funct
, offset
, 1);
9787 generate_exception(ctx
, EXCP_RI
);
9794 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9799 int op
, cnvt_op
, op1
, offset
;
9803 op
= (ctx
->opcode
>> 11) & 0x1f;
9804 sa
= (ctx
->opcode
>> 2) & 0x7;
9805 sa
= sa
== 0 ? 8 : sa
;
9806 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9807 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9808 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9809 op1
= offset
= ctx
->opcode
& 0x1f;
9814 case M16_OPC_ADDIUSP
:
9816 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9818 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rx
, 29, imm
);
9821 case M16_OPC_ADDIUPC
:
9822 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9825 offset
= (ctx
->opcode
& 0x7ff) << 1;
9826 offset
= (int16_t)(offset
<< 4) >> 4;
9827 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9828 /* No delay slot, so just process as a normal instruction */
9831 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9832 offset
= (((ctx
->opcode
& 0x1f) << 21)
9833 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9835 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9836 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9841 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9842 /* No delay slot, so just process as a normal instruction */
9845 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9846 /* No delay slot, so just process as a normal instruction */
9849 switch (ctx
->opcode
& 0x3) {
9851 gen_shift_imm(env
, ctx
, OPC_SLL
, rx
, ry
, sa
);
9854 #if defined(TARGET_MIPS64)
9856 gen_shift_imm(env
, ctx
, OPC_DSLL
, rx
, ry
, sa
);
9858 generate_exception(ctx
, EXCP_RI
);
9862 gen_shift_imm(env
, ctx
, OPC_SRL
, rx
, ry
, sa
);
9865 gen_shift_imm(env
, ctx
, OPC_SRA
, rx
, ry
, sa
);
9869 #if defined(TARGET_MIPS64)
9872 gen_ld(env
, ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9877 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9879 if ((ctx
->opcode
>> 4) & 1) {
9880 #if defined(TARGET_MIPS64)
9882 gen_arith_imm(env
, ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9884 generate_exception(ctx
, EXCP_RI
);
9887 gen_arith_imm(env
, ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9891 case M16_OPC_ADDIU8
:
9893 int16_t imm
= (int8_t) ctx
->opcode
;
9895 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9900 int16_t imm
= (uint8_t) ctx
->opcode
;
9901 gen_slt_imm(env
, ctx
, OPC_SLTI
, 24, rx
, imm
);
9906 int16_t imm
= (uint8_t) ctx
->opcode
;
9907 gen_slt_imm(env
, ctx
, OPC_SLTIU
, 24, rx
, imm
);
9914 funct
= (ctx
->opcode
>> 8) & 0x7;
9917 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9918 ((int8_t)ctx
->opcode
) << 1);
9921 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9922 ((int8_t)ctx
->opcode
) << 1);
9925 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9928 gen_arith_imm(env
, ctx
, OPC_ADDIU
, 29, 29,
9929 ((int8_t)ctx
->opcode
) << 3);
9933 int do_ra
= ctx
->opcode
& (1 << 6);
9934 int do_s0
= ctx
->opcode
& (1 << 5);
9935 int do_s1
= ctx
->opcode
& (1 << 4);
9936 int framesize
= ctx
->opcode
& 0xf;
9938 if (framesize
== 0) {
9941 framesize
= framesize
<< 3;
9944 if (ctx
->opcode
& (1 << 7)) {
9945 gen_mips16_save(ctx
, 0, 0,
9946 do_ra
, do_s0
, do_s1
, framesize
);
9948 gen_mips16_restore(ctx
, 0, 0,
9949 do_ra
, do_s0
, do_s1
, framesize
);
9955 int rz
= xlat(ctx
->opcode
& 0x7);
9957 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9958 ((ctx
->opcode
>> 5) & 0x7);
9959 gen_arith(env
, ctx
, OPC_ADDU
, reg32
, rz
, 0);
9963 reg32
= ctx
->opcode
& 0x1f;
9964 gen_arith(env
, ctx
, OPC_ADDU
, ry
, reg32
, 0);
9967 generate_exception(ctx
, EXCP_RI
);
9974 int16_t imm
= (uint8_t) ctx
->opcode
;
9976 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rx
, 0, imm
);
9981 int16_t imm
= (uint8_t) ctx
->opcode
;
9982 gen_logic_imm(env
, ctx
, OPC_XORI
, 24, rx
, imm
);
9985 #if defined(TARGET_MIPS64)
9988 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9992 gen_ld(env
, ctx
, OPC_LB
, ry
, rx
, offset
);
9995 gen_ld(env
, ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9998 gen_ld(env
, ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10001 gen_ld(env
, ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10004 gen_ld(env
, ctx
, OPC_LBU
, ry
, rx
, offset
);
10007 gen_ld(env
, ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
10010 gen_ld(env
, ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10012 #if defined (TARGET_MIPS64)
10014 check_mips_64(ctx
);
10015 gen_ld(env
, ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10019 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10022 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10025 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10028 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10032 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10035 switch (ctx
->opcode
& 0x3) {
10037 mips32_op
= OPC_ADDU
;
10040 mips32_op
= OPC_SUBU
;
10042 #if defined(TARGET_MIPS64)
10044 mips32_op
= OPC_DADDU
;
10045 check_mips_64(ctx
);
10048 mips32_op
= OPC_DSUBU
;
10049 check_mips_64(ctx
);
10053 generate_exception(ctx
, EXCP_RI
);
10057 gen_arith(env
, ctx
, mips32_op
, rz
, rx
, ry
);
10066 int nd
= (ctx
->opcode
>> 7) & 0x1;
10067 int link
= (ctx
->opcode
>> 6) & 0x1;
10068 int ra
= (ctx
->opcode
>> 5) & 0x1;
10071 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10076 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10083 /* XXX: not clear which exception should be raised
10084 * when in debug mode...
10086 check_insn(env
, ctx
, ISA_MIPS32
);
10087 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10088 generate_exception(ctx
, EXCP_DBp
);
10090 generate_exception(ctx
, EXCP_DBp
);
10094 gen_slt(env
, ctx
, OPC_SLT
, 24, rx
, ry
);
10097 gen_slt(env
, ctx
, OPC_SLTU
, 24, rx
, ry
);
10100 generate_exception(ctx
, EXCP_BREAK
);
10103 gen_shift(env
, ctx
, OPC_SLLV
, ry
, rx
, ry
);
10106 gen_shift(env
, ctx
, OPC_SRLV
, ry
, rx
, ry
);
10109 gen_shift(env
, ctx
, OPC_SRAV
, ry
, rx
, ry
);
10111 #if defined (TARGET_MIPS64)
10113 check_mips_64(ctx
);
10114 gen_shift_imm(env
, ctx
, OPC_DSRL
, ry
, ry
, sa
);
10118 gen_logic(env
, ctx
, OPC_XOR
, 24, rx
, ry
);
10121 gen_arith(env
, ctx
, OPC_SUBU
, rx
, 0, ry
);
10124 gen_logic(env
, ctx
, OPC_AND
, rx
, rx
, ry
);
10127 gen_logic(env
, ctx
, OPC_OR
, rx
, rx
, ry
);
10130 gen_logic(env
, ctx
, OPC_XOR
, rx
, rx
, ry
);
10133 gen_logic(env
, ctx
, OPC_NOR
, rx
, ry
, 0);
10136 gen_HILO(ctx
, OPC_MFHI
, rx
);
10140 case RR_RY_CNVT_ZEB
:
10141 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10143 case RR_RY_CNVT_ZEH
:
10144 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10146 case RR_RY_CNVT_SEB
:
10147 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10149 case RR_RY_CNVT_SEH
:
10150 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10152 #if defined (TARGET_MIPS64)
10153 case RR_RY_CNVT_ZEW
:
10154 check_mips_64(ctx
);
10155 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10157 case RR_RY_CNVT_SEW
:
10158 check_mips_64(ctx
);
10159 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10163 generate_exception(ctx
, EXCP_RI
);
10168 gen_HILO(ctx
, OPC_MFLO
, rx
);
10170 #if defined (TARGET_MIPS64)
10172 check_mips_64(ctx
);
10173 gen_shift_imm(env
, ctx
, OPC_DSRA
, ry
, ry
, sa
);
10176 check_mips_64(ctx
);
10177 gen_shift(env
, ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10180 check_mips_64(ctx
);
10181 gen_shift(env
, ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10184 check_mips_64(ctx
);
10185 gen_shift(env
, ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10189 gen_muldiv(ctx
, OPC_MULT
, rx
, ry
);
10192 gen_muldiv(ctx
, OPC_MULTU
, rx
, ry
);
10195 gen_muldiv(ctx
, OPC_DIV
, rx
, ry
);
10198 gen_muldiv(ctx
, OPC_DIVU
, rx
, ry
);
10200 #if defined (TARGET_MIPS64)
10202 check_mips_64(ctx
);
10203 gen_muldiv(ctx
, OPC_DMULT
, rx
, ry
);
10206 check_mips_64(ctx
);
10207 gen_muldiv(ctx
, OPC_DMULTU
, rx
, ry
);
10210 check_mips_64(ctx
);
10211 gen_muldiv(ctx
, OPC_DDIV
, rx
, ry
);
10214 check_mips_64(ctx
);
10215 gen_muldiv(ctx
, OPC_DDIVU
, rx
, ry
);
10219 generate_exception(ctx
, EXCP_RI
);
10223 case M16_OPC_EXTEND
:
10224 decode_extended_mips16_opc(env
, ctx
, is_branch
);
10227 #if defined(TARGET_MIPS64)
10229 funct
= (ctx
->opcode
>> 8) & 0x7;
10230 decode_i64_mips16(env
, ctx
, ry
, funct
, offset
, 0);
10234 generate_exception(ctx
, EXCP_RI
);
10241 /* microMIPS extension to MIPS32 */
10243 /* microMIPS32 major opcodes */
10282 /* 0x20 is reserved */
10292 /* 0x28 and 0x29 are reserved */
10302 /* 0x30 and 0x31 are reserved */
10312 /* 0x38 and 0x39 are reserved */
10323 /* POOL32A encoding of minor opcode field */
10326 /* These opcodes are distinguished only by bits 9..6; those bits are
10327 * what are recorded below. */
10353 /* The following can be distinguished by their lower 6 bits. */
10359 /* POOL32AXF encoding of minor opcode field extension */
10373 /* bits 13..12 for 0x01 */
10379 /* bits 13..12 for 0x2a */
10385 /* bits 13..12 for 0x32 */
10389 /* bits 15..12 for 0x2c */
10405 /* bits 15..12 for 0x34 */
10413 /* bits 15..12 for 0x3c */
10415 JR
= 0x0, /* alias */
10420 /* bits 15..12 for 0x05 */
10424 /* bits 15..12 for 0x0d */
10434 /* bits 15..12 for 0x15 */
10440 /* bits 15..12 for 0x1d */
10444 /* bits 15..12 for 0x2d */
10449 /* bits 15..12 for 0x35 */
10456 /* POOL32B encoding of minor opcode field (bits 15..12) */
10472 /* POOL32C encoding of minor opcode field (bits 15..12) */
10480 /* 0xa is reserved */
10487 /* 0x6 is reserved */
10493 /* POOL32F encoding of minor opcode field (bits 5..0) */
10496 /* These are the bit 7..6 values */
10507 /* These are the bit 8..6 values */
10551 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10555 /* POOL32Fxf encoding of minor opcode extension field */
10593 /* POOL32I encoding of minor opcode field (bits 25..21) */
10618 /* These overlap and are distinguished by bit16 of the instruction */
10627 /* POOL16A encoding of minor opcode field */
10634 /* POOL16B encoding of minor opcode field */
10641 /* POOL16C encoding of minor opcode field */
10661 /* POOL16D encoding of minor opcode field */
10668 /* POOL16E encoding of minor opcode field */
10675 static int mmreg (int r
)
10677 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10682 /* Used for 16-bit store instructions. */
10683 static int mmreg2 (int r
)
10685 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10690 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10691 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10692 #define uMIPS_RS2(op) uMIPS_RS(op)
10693 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10694 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10695 #define uMIPS_RS5(op) (op & 0x1f)
10697 /* Signed immediate */
10698 #define SIMM(op, start, width) \
10699 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10702 /* Zero-extended immediate */
10703 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10705 static void gen_addiur1sp (CPUMIPSState
*env
, DisasContext
*ctx
)
10707 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10709 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10712 static void gen_addiur2 (CPUMIPSState
*env
, DisasContext
*ctx
)
10714 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10715 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10716 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10718 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10721 static void gen_addiusp (CPUMIPSState
*env
, DisasContext
*ctx
)
10723 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10726 if (encoded
<= 1) {
10727 decoded
= 256 + encoded
;
10728 } else if (encoded
<= 255) {
10730 } else if (encoded
<= 509) {
10731 decoded
= encoded
- 512;
10733 decoded
= encoded
- 768;
10736 gen_arith_imm(env
, ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10739 static void gen_addius5 (CPUMIPSState
*env
, DisasContext
*ctx
)
10741 int imm
= SIMM(ctx
->opcode
, 1, 4);
10742 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10744 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10747 static void gen_andi16 (CPUMIPSState
*env
, DisasContext
*ctx
)
10749 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10750 31, 32, 63, 64, 255, 32768, 65535 };
10751 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10752 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10753 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10755 gen_logic_imm(env
, ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10758 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10759 int base
, int16_t offset
)
10761 const char *opn
= "ldst_multiple";
10765 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10766 generate_exception(ctx
, EXCP_RI
);
10770 t0
= tcg_temp_new();
10772 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10774 t1
= tcg_const_tl(reglist
);
10775 t2
= tcg_const_i32(ctx
->mem_idx
);
10777 save_cpu_state(ctx
, 1);
10780 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10784 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10787 #ifdef TARGET_MIPS64
10789 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10793 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10799 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10802 tcg_temp_free_i32(t2
);
10806 static void gen_pool16c_insn (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
10808 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10809 int rs
= mmreg(ctx
->opcode
& 0x7);
10812 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10817 gen_logic(env
, ctx
, OPC_NOR
, rd
, rs
, 0);
10823 gen_logic(env
, ctx
, OPC_XOR
, rd
, rd
, rs
);
10829 gen_logic(env
, ctx
, OPC_AND
, rd
, rd
, rs
);
10835 gen_logic(env
, ctx
, OPC_OR
, rd
, rd
, rs
);
10842 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10843 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10845 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10854 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10855 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10857 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10864 int reg
= ctx
->opcode
& 0x1f;
10866 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10873 int reg
= ctx
->opcode
& 0x1f;
10875 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10876 /* Let normal delay slot handling in our caller take us
10877 to the branch target. */
10889 int reg
= ctx
->opcode
& 0x1f;
10891 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10897 gen_HILO(ctx
, OPC_MFHI
, uMIPS_RS5(ctx
->opcode
));
10901 gen_HILO(ctx
, OPC_MFLO
, uMIPS_RS5(ctx
->opcode
));
10904 generate_exception(ctx
, EXCP_BREAK
);
10907 /* XXX: not clear which exception should be raised
10908 * when in debug mode...
10910 check_insn(env
, ctx
, ISA_MIPS32
);
10911 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10912 generate_exception(ctx
, EXCP_DBp
);
10914 generate_exception(ctx
, EXCP_DBp
);
10917 case JRADDIUSP
+ 0:
10918 case JRADDIUSP
+ 1:
10920 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10922 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10923 gen_arith_imm(env
, ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10924 /* Let normal delay slot handling in our caller take us
10925 to the branch target. */
10929 generate_exception(ctx
, EXCP_RI
);
10934 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10936 TCGv t0
= tcg_temp_new();
10937 TCGv t1
= tcg_temp_new();
10939 gen_load_gpr(t0
, base
);
10942 gen_load_gpr(t1
, index
);
10943 tcg_gen_shli_tl(t1
, t1
, 2);
10944 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10947 save_cpu_state(ctx
, 0);
10948 op_ld_lw(t1
, t0
, ctx
);
10949 gen_store_gpr(t1
, rd
);
10955 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10956 int base
, int16_t offset
)
10958 const char *opn
= "ldst_pair";
10961 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10962 generate_exception(ctx
, EXCP_RI
);
10966 t0
= tcg_temp_new();
10967 t1
= tcg_temp_new();
10969 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10974 generate_exception(ctx
, EXCP_RI
);
10977 save_cpu_state(ctx
, 0);
10978 op_ld_lw(t1
, t0
, ctx
);
10979 gen_store_gpr(t1
, rd
);
10980 tcg_gen_movi_tl(t1
, 4);
10981 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10982 op_ld_lw(t1
, t0
, ctx
);
10983 gen_store_gpr(t1
, rd
+1);
10987 save_cpu_state(ctx
, 0);
10988 gen_load_gpr(t1
, rd
);
10989 op_st_sw(t1
, t0
, ctx
);
10990 tcg_gen_movi_tl(t1
, 4);
10991 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10992 gen_load_gpr(t1
, rd
+1);
10993 op_st_sw(t1
, t0
, ctx
);
10996 #ifdef TARGET_MIPS64
10999 generate_exception(ctx
, EXCP_RI
);
11002 save_cpu_state(ctx
, 0);
11003 op_ld_ld(t1
, t0
, ctx
);
11004 gen_store_gpr(t1
, rd
);
11005 tcg_gen_movi_tl(t1
, 8);
11006 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11007 op_ld_ld(t1
, t0
, ctx
);
11008 gen_store_gpr(t1
, rd
+1);
11012 save_cpu_state(ctx
, 0);
11013 gen_load_gpr(t1
, rd
);
11014 op_st_sd(t1
, t0
, ctx
);
11015 tcg_gen_movi_tl(t1
, 8);
11016 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11017 gen_load_gpr(t1
, rd
+1);
11018 op_st_sd(t1
, t0
, ctx
);
11023 (void)opn
; /* avoid a compiler warning */
11024 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11029 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
,
11032 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11033 int minor
= (ctx
->opcode
>> 12) & 0xf;
11034 uint32_t mips32_op
;
11036 switch (extension
) {
11038 mips32_op
= OPC_TEQ
;
11041 mips32_op
= OPC_TGE
;
11044 mips32_op
= OPC_TGEU
;
11047 mips32_op
= OPC_TLT
;
11050 mips32_op
= OPC_TLTU
;
11053 mips32_op
= OPC_TNE
;
11055 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11057 #ifndef CONFIG_USER_ONLY
11060 check_cp0_enabled(ctx
);
11062 /* Treat as NOP. */
11065 gen_mfc0(env
, ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11069 check_cp0_enabled(ctx
);
11071 TCGv t0
= tcg_temp_new();
11073 gen_load_gpr(t0
, rt
);
11074 gen_mtc0(env
, ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11082 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11085 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11088 mips32_op
= OPC_CLO
;
11091 mips32_op
= OPC_CLZ
;
11093 check_insn(env
, ctx
, ISA_MIPS32
);
11094 gen_cl(ctx
, mips32_op
, rt
, rs
);
11097 gen_rdhwr(env
, ctx
, rt
, rs
);
11100 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11103 mips32_op
= OPC_MULT
;
11106 mips32_op
= OPC_MULTU
;
11109 mips32_op
= OPC_DIV
;
11112 mips32_op
= OPC_DIVU
;
11115 mips32_op
= OPC_MADD
;
11118 mips32_op
= OPC_MADDU
;
11121 mips32_op
= OPC_MSUB
;
11124 mips32_op
= OPC_MSUBU
;
11126 check_insn(env
, ctx
, ISA_MIPS32
);
11127 gen_muldiv(ctx
, mips32_op
, rs
, rt
);
11130 goto pool32axf_invalid
;
11141 generate_exception_err(ctx
, EXCP_CpU
, 2);
11144 goto pool32axf_invalid
;
11151 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11156 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11160 goto pool32axf_invalid
;
11166 check_cp0_enabled(ctx
);
11167 check_insn(env
, ctx
, ISA_MIPS32R2
);
11168 gen_load_srsgpr(rt
, rs
);
11171 check_cp0_enabled(ctx
);
11172 check_insn(env
, ctx
, ISA_MIPS32R2
);
11173 gen_store_srsgpr(rt
, rs
);
11176 goto pool32axf_invalid
;
11179 #ifndef CONFIG_USER_ONLY
11183 mips32_op
= OPC_TLBP
;
11186 mips32_op
= OPC_TLBR
;
11189 mips32_op
= OPC_TLBWI
;
11192 mips32_op
= OPC_TLBWR
;
11195 mips32_op
= OPC_WAIT
;
11198 mips32_op
= OPC_DERET
;
11201 mips32_op
= OPC_ERET
;
11203 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11206 goto pool32axf_invalid
;
11212 check_cp0_enabled(ctx
);
11214 TCGv t0
= tcg_temp_new();
11216 save_cpu_state(ctx
, 1);
11217 gen_helper_di(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 check_cp0_enabled(ctx
);
11227 TCGv t0
= tcg_temp_new();
11229 save_cpu_state(ctx
, 1);
11230 gen_helper_ei(t0
, cpu_env
);
11231 gen_store_gpr(t0
, rs
);
11232 /* Stop translation as we may have switched the execution mode */
11233 ctx
->bstate
= BS_STOP
;
11238 goto pool32axf_invalid
;
11248 generate_exception(ctx
, EXCP_SYSCALL
);
11249 ctx
->bstate
= BS_STOP
;
11252 check_insn(env
, ctx
, ISA_MIPS32
);
11253 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11254 generate_exception(ctx
, EXCP_DBp
);
11256 generate_exception(ctx
, EXCP_DBp
);
11260 goto pool32axf_invalid
;
11266 gen_HILO(ctx
, OPC_MFHI
, rs
);
11269 gen_HILO(ctx
, OPC_MFLO
, rs
);
11272 gen_HILO(ctx
, OPC_MTHI
, rs
);
11275 gen_HILO(ctx
, OPC_MTLO
, rs
);
11278 goto pool32axf_invalid
;
11283 MIPS_INVAL("pool32axf");
11284 generate_exception(ctx
, EXCP_RI
);
11289 /* Values for microMIPS fmt field. Variable-width, depending on which
11290 formats the instruction supports. */
11309 static void gen_pool32fxf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11311 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11312 uint32_t mips32_op
;
11314 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11315 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11316 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11318 switch (extension
) {
11319 case FLOAT_1BIT_FMT(CFC1
, 0):
11320 mips32_op
= OPC_CFC1
;
11322 case FLOAT_1BIT_FMT(CTC1
, 0):
11323 mips32_op
= OPC_CTC1
;
11325 case FLOAT_1BIT_FMT(MFC1
, 0):
11326 mips32_op
= OPC_MFC1
;
11328 case FLOAT_1BIT_FMT(MTC1
, 0):
11329 mips32_op
= OPC_MTC1
;
11331 case FLOAT_1BIT_FMT(MFHC1
, 0):
11332 mips32_op
= OPC_MFHC1
;
11334 case FLOAT_1BIT_FMT(MTHC1
, 0):
11335 mips32_op
= OPC_MTHC1
;
11337 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11340 /* Reciprocal square root */
11341 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11342 mips32_op
= OPC_RSQRT_S
;
11344 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11345 mips32_op
= OPC_RSQRT_D
;
11349 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11350 mips32_op
= OPC_SQRT_S
;
11352 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11353 mips32_op
= OPC_SQRT_D
;
11357 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11358 mips32_op
= OPC_RECIP_S
;
11360 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11361 mips32_op
= OPC_RECIP_D
;
11365 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11366 mips32_op
= OPC_FLOOR_L_S
;
11368 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11369 mips32_op
= OPC_FLOOR_L_D
;
11371 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11372 mips32_op
= OPC_FLOOR_W_S
;
11374 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11375 mips32_op
= OPC_FLOOR_W_D
;
11379 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11380 mips32_op
= OPC_CEIL_L_S
;
11382 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11383 mips32_op
= OPC_CEIL_L_D
;
11385 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11386 mips32_op
= OPC_CEIL_W_S
;
11388 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11389 mips32_op
= OPC_CEIL_W_D
;
11393 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11394 mips32_op
= OPC_TRUNC_L_S
;
11396 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11397 mips32_op
= OPC_TRUNC_L_D
;
11399 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11400 mips32_op
= OPC_TRUNC_W_S
;
11402 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11403 mips32_op
= OPC_TRUNC_W_D
;
11407 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11408 mips32_op
= OPC_ROUND_L_S
;
11410 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11411 mips32_op
= OPC_ROUND_L_D
;
11413 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11414 mips32_op
= OPC_ROUND_W_S
;
11416 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11417 mips32_op
= OPC_ROUND_W_D
;
11420 /* Integer to floating-point conversion */
11421 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11422 mips32_op
= OPC_CVT_L_S
;
11424 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11425 mips32_op
= OPC_CVT_L_D
;
11427 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11428 mips32_op
= OPC_CVT_W_S
;
11430 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11431 mips32_op
= OPC_CVT_W_D
;
11434 /* Paired-foo conversions */
11435 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11436 mips32_op
= OPC_CVT_S_PL
;
11438 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11439 mips32_op
= OPC_CVT_S_PU
;
11441 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11442 mips32_op
= OPC_CVT_PW_PS
;
11444 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11445 mips32_op
= OPC_CVT_PS_PW
;
11448 /* Floating-point moves */
11449 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11450 mips32_op
= OPC_MOV_S
;
11452 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11453 mips32_op
= OPC_MOV_D
;
11455 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11456 mips32_op
= OPC_MOV_PS
;
11459 /* Absolute value */
11460 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11461 mips32_op
= OPC_ABS_S
;
11463 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11464 mips32_op
= OPC_ABS_D
;
11466 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11467 mips32_op
= OPC_ABS_PS
;
11471 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11472 mips32_op
= OPC_NEG_S
;
11474 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11475 mips32_op
= OPC_NEG_D
;
11477 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11478 mips32_op
= OPC_NEG_PS
;
11481 /* Reciprocal square root step */
11482 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11483 mips32_op
= OPC_RSQRT1_S
;
11485 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11486 mips32_op
= OPC_RSQRT1_D
;
11488 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11489 mips32_op
= OPC_RSQRT1_PS
;
11492 /* Reciprocal step */
11493 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11494 mips32_op
= OPC_RECIP1_S
;
11496 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11497 mips32_op
= OPC_RECIP1_S
;
11499 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11500 mips32_op
= OPC_RECIP1_PS
;
11503 /* Conversions from double */
11504 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11505 mips32_op
= OPC_CVT_D_S
;
11507 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11508 mips32_op
= OPC_CVT_D_W
;
11510 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11511 mips32_op
= OPC_CVT_D_L
;
11514 /* Conversions from single */
11515 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11516 mips32_op
= OPC_CVT_S_D
;
11518 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11519 mips32_op
= OPC_CVT_S_W
;
11521 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11522 mips32_op
= OPC_CVT_S_L
;
11524 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11527 /* Conditional moves on floating-point codes */
11528 case COND_FLOAT_MOV(MOVT
, 0):
11529 case COND_FLOAT_MOV(MOVT
, 1):
11530 case COND_FLOAT_MOV(MOVT
, 2):
11531 case COND_FLOAT_MOV(MOVT
, 3):
11532 case COND_FLOAT_MOV(MOVT
, 4):
11533 case COND_FLOAT_MOV(MOVT
, 5):
11534 case COND_FLOAT_MOV(MOVT
, 6):
11535 case COND_FLOAT_MOV(MOVT
, 7):
11536 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11538 case COND_FLOAT_MOV(MOVF
, 0):
11539 case COND_FLOAT_MOV(MOVF
, 1):
11540 case COND_FLOAT_MOV(MOVF
, 2):
11541 case COND_FLOAT_MOV(MOVF
, 3):
11542 case COND_FLOAT_MOV(MOVF
, 4):
11543 case COND_FLOAT_MOV(MOVF
, 5):
11544 case COND_FLOAT_MOV(MOVF
, 6):
11545 case COND_FLOAT_MOV(MOVF
, 7):
11546 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11549 MIPS_INVAL("pool32fxf");
11550 generate_exception(ctx
, EXCP_RI
);
11555 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11556 uint16_t insn_hw1
, int *is_branch
)
11560 int rt
, rs
, rd
, rr
;
11562 uint32_t op
, minor
, mips32_op
;
11563 uint32_t cond
, fmt
, cc
;
11565 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11566 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11568 rt
= (ctx
->opcode
>> 21) & 0x1f;
11569 rs
= (ctx
->opcode
>> 16) & 0x1f;
11570 rd
= (ctx
->opcode
>> 11) & 0x1f;
11571 rr
= (ctx
->opcode
>> 6) & 0x1f;
11572 imm
= (int16_t) ctx
->opcode
;
11574 op
= (ctx
->opcode
>> 26) & 0x3f;
11577 minor
= ctx
->opcode
& 0x3f;
11580 minor
= (ctx
->opcode
>> 6) & 0xf;
11583 mips32_op
= OPC_SLL
;
11586 mips32_op
= OPC_SRA
;
11589 mips32_op
= OPC_SRL
;
11592 mips32_op
= OPC_ROTR
;
11594 gen_shift_imm(env
, ctx
, mips32_op
, rt
, rs
, rd
);
11597 goto pool32a_invalid
;
11601 minor
= (ctx
->opcode
>> 6) & 0xf;
11605 mips32_op
= OPC_ADD
;
11608 mips32_op
= OPC_ADDU
;
11611 mips32_op
= OPC_SUB
;
11614 mips32_op
= OPC_SUBU
;
11617 mips32_op
= OPC_MUL
;
11619 gen_arith(env
, ctx
, mips32_op
, rd
, rs
, rt
);
11623 mips32_op
= OPC_SLLV
;
11626 mips32_op
= OPC_SRLV
;
11629 mips32_op
= OPC_SRAV
;
11632 mips32_op
= OPC_ROTRV
;
11634 gen_shift(env
, ctx
, mips32_op
, rd
, rs
, rt
);
11636 /* Logical operations */
11638 mips32_op
= OPC_AND
;
11641 mips32_op
= OPC_OR
;
11644 mips32_op
= OPC_NOR
;
11647 mips32_op
= OPC_XOR
;
11649 gen_logic(env
, ctx
, mips32_op
, rd
, rs
, rt
);
11651 /* Set less than */
11653 mips32_op
= OPC_SLT
;
11656 mips32_op
= OPC_SLTU
;
11658 gen_slt(env
, ctx
, mips32_op
, rd
, rs
, rt
);
11661 goto pool32a_invalid
;
11665 minor
= (ctx
->opcode
>> 6) & 0xf;
11667 /* Conditional moves */
11669 mips32_op
= OPC_MOVN
;
11672 mips32_op
= OPC_MOVZ
;
11674 gen_cond_move(env
, ctx
, mips32_op
, rd
, rs
, rt
);
11677 gen_ldxs(ctx
, rs
, rt
, rd
);
11680 goto pool32a_invalid
;
11684 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11687 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11690 gen_pool32axf(env
, ctx
, rt
, rs
, is_branch
);
11693 generate_exception(ctx
, EXCP_BREAK
);
11697 MIPS_INVAL("pool32a");
11698 generate_exception(ctx
, EXCP_RI
);
11703 minor
= (ctx
->opcode
>> 12) & 0xf;
11706 check_cp0_enabled(ctx
);
11707 /* Treat as no-op. */
11711 /* COP2: Not implemented. */
11712 generate_exception_err(ctx
, EXCP_CpU
, 2);
11716 #ifdef TARGET_MIPS64
11720 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11724 #ifdef TARGET_MIPS64
11728 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11731 MIPS_INVAL("pool32b");
11732 generate_exception(ctx
, EXCP_RI
);
11737 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11738 minor
= ctx
->opcode
& 0x3f;
11739 check_cp1_enabled(ctx
);
11742 mips32_op
= OPC_ALNV_PS
;
11745 mips32_op
= OPC_MADD_S
;
11748 mips32_op
= OPC_MADD_D
;
11751 mips32_op
= OPC_MADD_PS
;
11754 mips32_op
= OPC_MSUB_S
;
11757 mips32_op
= OPC_MSUB_D
;
11760 mips32_op
= OPC_MSUB_PS
;
11763 mips32_op
= OPC_NMADD_S
;
11766 mips32_op
= OPC_NMADD_D
;
11769 mips32_op
= OPC_NMADD_PS
;
11772 mips32_op
= OPC_NMSUB_S
;
11775 mips32_op
= OPC_NMSUB_D
;
11778 mips32_op
= OPC_NMSUB_PS
;
11780 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11782 case CABS_COND_FMT
:
11783 cond
= (ctx
->opcode
>> 6) & 0xf;
11784 cc
= (ctx
->opcode
>> 13) & 0x7;
11785 fmt
= (ctx
->opcode
>> 10) & 0x3;
11788 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11791 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11794 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11797 goto pool32f_invalid
;
11801 cond
= (ctx
->opcode
>> 6) & 0xf;
11802 cc
= (ctx
->opcode
>> 13) & 0x7;
11803 fmt
= (ctx
->opcode
>> 10) & 0x3;
11806 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11809 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11812 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11815 goto pool32f_invalid
;
11819 gen_pool32fxf(env
, ctx
, rt
, rs
);
11823 switch ((ctx
->opcode
>> 6) & 0x7) {
11825 mips32_op
= OPC_PLL_PS
;
11828 mips32_op
= OPC_PLU_PS
;
11831 mips32_op
= OPC_PUL_PS
;
11834 mips32_op
= OPC_PUU_PS
;
11837 mips32_op
= OPC_CVT_PS_S
;
11839 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11842 goto pool32f_invalid
;
11847 switch ((ctx
->opcode
>> 6) & 0x7) {
11849 mips32_op
= OPC_LWXC1
;
11852 mips32_op
= OPC_SWXC1
;
11855 mips32_op
= OPC_LDXC1
;
11858 mips32_op
= OPC_SDXC1
;
11861 mips32_op
= OPC_LUXC1
;
11864 mips32_op
= OPC_SUXC1
;
11866 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11869 goto pool32f_invalid
;
11874 fmt
= (ctx
->opcode
>> 9) & 0x3;
11875 switch ((ctx
->opcode
>> 6) & 0x7) {
11879 mips32_op
= OPC_RSQRT2_S
;
11882 mips32_op
= OPC_RSQRT2_D
;
11885 mips32_op
= OPC_RSQRT2_PS
;
11888 goto pool32f_invalid
;
11894 mips32_op
= OPC_RECIP2_S
;
11897 mips32_op
= OPC_RECIP2_D
;
11900 mips32_op
= OPC_RECIP2_PS
;
11903 goto pool32f_invalid
;
11907 mips32_op
= OPC_ADDR_PS
;
11910 mips32_op
= OPC_MULR_PS
;
11912 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11915 goto pool32f_invalid
;
11919 /* MOV[FT].fmt and PREFX */
11920 cc
= (ctx
->opcode
>> 13) & 0x7;
11921 fmt
= (ctx
->opcode
>> 9) & 0x3;
11922 switch ((ctx
->opcode
>> 6) & 0x7) {
11926 gen_movcf_s(rs
, rt
, cc
, 0);
11929 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11932 gen_movcf_ps(rs
, rt
, cc
, 0);
11935 goto pool32f_invalid
;
11941 gen_movcf_s(rs
, rt
, cc
, 1);
11944 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11947 gen_movcf_ps(rs
, rt
, cc
, 1);
11950 goto pool32f_invalid
;
11956 goto pool32f_invalid
;
11959 #define FINSN_3ARG_SDPS(prfx) \
11960 switch ((ctx->opcode >> 8) & 0x3) { \
11962 mips32_op = OPC_##prfx##_S; \
11965 mips32_op = OPC_##prfx##_D; \
11967 case FMT_SDPS_PS: \
11968 mips32_op = OPC_##prfx##_PS; \
11971 goto pool32f_invalid; \
11974 /* regular FP ops */
11975 switch ((ctx
->opcode
>> 6) & 0x3) {
11977 FINSN_3ARG_SDPS(ADD
);
11980 FINSN_3ARG_SDPS(SUB
);
11983 FINSN_3ARG_SDPS(MUL
);
11986 fmt
= (ctx
->opcode
>> 8) & 0x3;
11988 mips32_op
= OPC_DIV_D
;
11989 } else if (fmt
== 0) {
11990 mips32_op
= OPC_DIV_S
;
11992 goto pool32f_invalid
;
11996 goto pool32f_invalid
;
12001 switch ((ctx
->opcode
>> 6) & 0x3) {
12003 FINSN_3ARG_SDPS(MOVN
);
12006 FINSN_3ARG_SDPS(MOVZ
);
12009 goto pool32f_invalid
;
12013 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12017 MIPS_INVAL("pool32f");
12018 generate_exception(ctx
, EXCP_RI
);
12022 generate_exception_err(ctx
, EXCP_CpU
, 1);
12026 minor
= (ctx
->opcode
>> 21) & 0x1f;
12029 mips32_op
= OPC_BLTZ
;
12032 mips32_op
= OPC_BLTZAL
;
12035 mips32_op
= OPC_BLTZALS
;
12038 mips32_op
= OPC_BGEZ
;
12041 mips32_op
= OPC_BGEZAL
;
12044 mips32_op
= OPC_BGEZALS
;
12047 mips32_op
= OPC_BLEZ
;
12050 mips32_op
= OPC_BGTZ
;
12052 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12058 mips32_op
= OPC_TLTI
;
12061 mips32_op
= OPC_TGEI
;
12064 mips32_op
= OPC_TLTIU
;
12067 mips32_op
= OPC_TGEIU
;
12070 mips32_op
= OPC_TNEI
;
12073 mips32_op
= OPC_TEQI
;
12075 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12080 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12081 4, rs
, 0, imm
<< 1);
12082 /* Compact branches don't have a delay slot, so just let
12083 the normal delay slot handling take us to the branch
12087 gen_logic_imm(env
, ctx
, OPC_LUI
, rs
, -1, imm
);
12093 /* COP2: Not implemented. */
12094 generate_exception_err(ctx
, EXCP_CpU
, 2);
12097 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12100 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12103 mips32_op
= OPC_BC1FANY4
;
12106 mips32_op
= OPC_BC1TANY4
;
12109 check_insn(env
, ctx
, ASE_MIPS3D
);
12112 gen_compute_branch1(env
, ctx
, mips32_op
,
12113 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12118 /* MIPS DSP: not implemented */
12121 MIPS_INVAL("pool32i");
12122 generate_exception(ctx
, EXCP_RI
);
12127 minor
= (ctx
->opcode
>> 12) & 0xf;
12130 mips32_op
= OPC_LWL
;
12133 mips32_op
= OPC_SWL
;
12136 mips32_op
= OPC_LWR
;
12139 mips32_op
= OPC_SWR
;
12141 #if defined(TARGET_MIPS64)
12143 mips32_op
= OPC_LDL
;
12146 mips32_op
= OPC_SDL
;
12149 mips32_op
= OPC_LDR
;
12152 mips32_op
= OPC_SDR
;
12155 mips32_op
= OPC_LWU
;
12158 mips32_op
= OPC_LLD
;
12162 mips32_op
= OPC_LL
;
12165 gen_ld(env
, ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12168 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12171 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12173 #if defined(TARGET_MIPS64)
12175 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12179 /* Treat as no-op */
12182 MIPS_INVAL("pool32c");
12183 generate_exception(ctx
, EXCP_RI
);
12188 mips32_op
= OPC_ADDI
;
12191 mips32_op
= OPC_ADDIU
;
12193 gen_arith_imm(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12196 /* Logical operations */
12198 mips32_op
= OPC_ORI
;
12201 mips32_op
= OPC_XORI
;
12204 mips32_op
= OPC_ANDI
;
12206 gen_logic_imm(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12209 /* Set less than immediate */
12211 mips32_op
= OPC_SLTI
;
12214 mips32_op
= OPC_SLTIU
;
12216 gen_slt_imm(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12219 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12220 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12224 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12225 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12229 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12233 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12237 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12238 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12242 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12243 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12246 /* Floating point (COP1) */
12248 mips32_op
= OPC_LWC1
;
12251 mips32_op
= OPC_LDC1
;
12254 mips32_op
= OPC_SWC1
;
12257 mips32_op
= OPC_SDC1
;
12259 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12263 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12264 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12266 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12269 /* Loads and stores */
12271 mips32_op
= OPC_LB
;
12274 mips32_op
= OPC_LBU
;
12277 mips32_op
= OPC_LH
;
12280 mips32_op
= OPC_LHU
;
12283 mips32_op
= OPC_LW
;
12285 #ifdef TARGET_MIPS64
12287 mips32_op
= OPC_LD
;
12290 mips32_op
= OPC_SD
;
12294 mips32_op
= OPC_SB
;
12297 mips32_op
= OPC_SH
;
12300 mips32_op
= OPC_SW
;
12303 gen_ld(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12306 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12309 generate_exception(ctx
, EXCP_RI
);
12314 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
12318 /* make sure instructions are on a halfword boundary */
12319 if (ctx
->pc
& 0x1) {
12320 env
->CP0_BadVAddr
= ctx
->pc
;
12321 generate_exception(ctx
, EXCP_AdEL
);
12322 ctx
->bstate
= BS_STOP
;
12326 op
= (ctx
->opcode
>> 10) & 0x3f;
12327 /* Enforce properly-sized instructions in a delay slot */
12328 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12329 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12363 case POOL48A
: /* ??? */
12368 if (bits
& MIPS_HFLAG_BDS16
) {
12369 generate_exception(ctx
, EXCP_RI
);
12370 /* Just stop translation; the user is confused. */
12371 ctx
->bstate
= BS_STOP
;
12396 if (bits
& MIPS_HFLAG_BDS32
) {
12397 generate_exception(ctx
, EXCP_RI
);
12398 /* Just stop translation; the user is confused. */
12399 ctx
->bstate
= BS_STOP
;
12410 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12411 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12412 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12415 switch (ctx
->opcode
& 0x1) {
12424 gen_arith(env
, ctx
, opc
, rd
, rs1
, rs2
);
12429 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12430 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12431 int amount
= (ctx
->opcode
>> 1) & 0x7;
12433 amount
= amount
== 0 ? 8 : amount
;
12435 switch (ctx
->opcode
& 0x1) {
12444 gen_shift_imm(env
, ctx
, opc
, rd
, rs
, amount
);
12448 gen_pool16c_insn(env
, ctx
, is_branch
);
12452 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12453 int rb
= 28; /* GP */
12454 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12456 gen_ld(env
, ctx
, OPC_LW
, rd
, rb
, offset
);
12460 if (ctx
->opcode
& 1) {
12461 generate_exception(ctx
, EXCP_RI
);
12464 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12465 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12466 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12467 int rd
, rs
, re
, rt
;
12468 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12469 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12470 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12472 rd
= rd_enc
[enc_dest
];
12473 re
= re_enc
[enc_dest
];
12474 rs
= rs_rt_enc
[enc_rs
];
12475 rt
= rs_rt_enc
[enc_rt
];
12477 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rd
, rs
, 0);
12478 gen_arith_imm(env
, ctx
, OPC_ADDIU
, re
, rt
, 0);
12483 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12484 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12485 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12486 offset
= (offset
== 0xf ? -1 : offset
);
12488 gen_ld(env
, ctx
, OPC_LBU
, rd
, rb
, offset
);
12493 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12494 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12495 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12497 gen_ld(env
, ctx
, OPC_LHU
, rd
, rb
, offset
);
12502 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12503 int rb
= 29; /* SP */
12504 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12506 gen_ld(env
, ctx
, OPC_LW
, rd
, rb
, offset
);
12511 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12512 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12513 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12515 gen_ld(env
, ctx
, OPC_LW
, rd
, rb
, offset
);
12520 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12521 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12522 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12524 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12529 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12530 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12531 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12533 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12538 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12539 int rb
= 29; /* SP */
12540 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12542 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12547 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12548 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12549 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12551 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12556 int rd
= uMIPS_RD5(ctx
->opcode
);
12557 int rs
= uMIPS_RS5(ctx
->opcode
);
12559 gen_arith_imm(env
, ctx
, OPC_ADDIU
, rd
, rs
, 0);
12563 gen_andi16(env
, ctx
);
12566 switch (ctx
->opcode
& 0x1) {
12568 gen_addius5(env
, ctx
);
12571 gen_addiusp(env
, ctx
);
12576 switch (ctx
->opcode
& 0x1) {
12578 gen_addiur2(env
, ctx
);
12581 gen_addiur1sp(env
, ctx
);
12586 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12587 SIMM(ctx
->opcode
, 0, 10) << 1);
12592 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12593 mmreg(uMIPS_RD(ctx
->opcode
)),
12594 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12599 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12600 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12602 imm
= (imm
== 0x7f ? -1 : imm
);
12603 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12613 generate_exception(ctx
, EXCP_RI
);
12616 decode_micromips32_opc (env
, ctx
, op
, is_branch
);
12623 /* SmartMIPS extension to MIPS32 */
12625 #if defined(TARGET_MIPS64)
12627 /* MDMX extension to MIPS64 */
12631 /* MIPSDSP functions. */
12632 static void gen_mipsdsp_ld(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
12633 int rd
, int base
, int offset
)
12635 const char *opn
= "ldx";
12644 t0
= tcg_temp_new();
12647 gen_load_gpr(t0
, offset
);
12648 } else if (offset
== 0) {
12649 gen_load_gpr(t0
, base
);
12651 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12654 save_cpu_state(ctx
, 0);
12657 op_ld_lbu(t0
, t0
, ctx
);
12658 gen_store_gpr(t0
, rd
);
12662 op_ld_lh(t0
, t0
, ctx
);
12663 gen_store_gpr(t0
, rd
);
12667 op_ld_lw(t0
, t0
, ctx
);
12668 gen_store_gpr(t0
, rd
);
12671 #if defined(TARGET_MIPS64)
12673 op_ld_ld(t0
, t0
, ctx
);
12674 gen_store_gpr(t0
, rd
);
12679 (void)opn
; /* avoid a compiler warning */
12680 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12681 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12685 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12686 int ret
, int v1
, int v2
)
12688 const char *opn
= "mipsdsp arith";
12693 /* Treat as NOP. */
12698 v1_t
= tcg_temp_new();
12699 v2_t
= tcg_temp_new();
12701 gen_load_gpr(v1_t
, v1
);
12702 gen_load_gpr(v2_t
, v2
);
12705 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12706 case OPC_MULT_G_2E
:
12710 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12712 case OPC_ADDUH_R_QB
:
12713 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12716 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12718 case OPC_ADDQH_R_PH
:
12719 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12722 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12724 case OPC_ADDQH_R_W
:
12725 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12728 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12730 case OPC_SUBUH_R_QB
:
12731 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12734 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12736 case OPC_SUBQH_R_PH
:
12737 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12740 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12742 case OPC_SUBQH_R_W
:
12743 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12747 case OPC_ABSQ_S_PH_DSP
:
12749 case OPC_ABSQ_S_QB
:
12751 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12753 case OPC_ABSQ_S_PH
:
12755 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12759 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12761 case OPC_PRECEQ_W_PHL
:
12763 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12764 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12766 case OPC_PRECEQ_W_PHR
:
12768 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12769 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12770 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12772 case OPC_PRECEQU_PH_QBL
:
12774 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12776 case OPC_PRECEQU_PH_QBR
:
12778 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12780 case OPC_PRECEQU_PH_QBLA
:
12782 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12784 case OPC_PRECEQU_PH_QBRA
:
12786 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12788 case OPC_PRECEU_PH_QBL
:
12790 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12792 case OPC_PRECEU_PH_QBR
:
12794 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12796 case OPC_PRECEU_PH_QBLA
:
12798 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12800 case OPC_PRECEU_PH_QBRA
:
12802 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12806 case OPC_ADDU_QB_DSP
:
12810 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12812 case OPC_ADDQ_S_PH
:
12814 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12818 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12822 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12824 case OPC_ADDU_S_QB
:
12826 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12830 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12832 case OPC_ADDU_S_PH
:
12834 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12838 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12840 case OPC_SUBQ_S_PH
:
12842 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12846 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12850 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12852 case OPC_SUBU_S_QB
:
12854 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12858 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12860 case OPC_SUBU_S_PH
:
12862 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12866 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12870 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12874 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12876 case OPC_RADDU_W_QB
:
12878 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12882 case OPC_CMPU_EQ_QB_DSP
:
12884 case OPC_PRECR_QB_PH
:
12886 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12888 case OPC_PRECRQ_QB_PH
:
12890 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12892 case OPC_PRECR_SRA_PH_W
:
12895 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12896 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12898 tcg_temp_free_i32(sa_t
);
12901 case OPC_PRECR_SRA_R_PH_W
:
12904 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12905 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12907 tcg_temp_free_i32(sa_t
);
12910 case OPC_PRECRQ_PH_W
:
12912 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12914 case OPC_PRECRQ_RS_PH_W
:
12916 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12918 case OPC_PRECRQU_S_QB_PH
:
12920 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12924 #ifdef TARGET_MIPS64
12925 case OPC_ABSQ_S_QH_DSP
:
12927 case OPC_PRECEQ_L_PWL
:
12929 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12931 case OPC_PRECEQ_L_PWR
:
12933 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12935 case OPC_PRECEQ_PW_QHL
:
12937 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12939 case OPC_PRECEQ_PW_QHR
:
12941 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12943 case OPC_PRECEQ_PW_QHLA
:
12945 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12947 case OPC_PRECEQ_PW_QHRA
:
12949 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12951 case OPC_PRECEQU_QH_OBL
:
12953 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12955 case OPC_PRECEQU_QH_OBR
:
12957 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12959 case OPC_PRECEQU_QH_OBLA
:
12961 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12963 case OPC_PRECEQU_QH_OBRA
:
12965 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12967 case OPC_PRECEU_QH_OBL
:
12969 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12971 case OPC_PRECEU_QH_OBR
:
12973 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
12975 case OPC_PRECEU_QH_OBLA
:
12977 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
12979 case OPC_PRECEU_QH_OBRA
:
12981 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
12983 case OPC_ABSQ_S_OB
:
12985 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
12987 case OPC_ABSQ_S_PW
:
12989 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
12991 case OPC_ABSQ_S_QH
:
12993 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
12997 case OPC_ADDU_OB_DSP
:
12999 case OPC_RADDU_L_OB
:
13001 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13005 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13007 case OPC_SUBQ_S_PW
:
13009 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13013 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13015 case OPC_SUBQ_S_QH
:
13017 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13021 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13023 case OPC_SUBU_S_OB
:
13025 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13029 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13031 case OPC_SUBU_S_QH
:
13033 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13037 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13039 case OPC_SUBUH_R_OB
:
13041 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13045 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13047 case OPC_ADDQ_S_PW
:
13049 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13053 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13055 case OPC_ADDQ_S_QH
:
13057 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13061 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13063 case OPC_ADDU_S_OB
:
13065 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13069 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13071 case OPC_ADDU_S_QH
:
13073 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13077 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13079 case OPC_ADDUH_R_OB
:
13081 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13085 case OPC_CMPU_EQ_OB_DSP
:
13087 case OPC_PRECR_OB_QH
:
13089 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13091 case OPC_PRECR_SRA_QH_PW
:
13094 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13095 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13096 tcg_temp_free_i32(ret_t
);
13099 case OPC_PRECR_SRA_R_QH_PW
:
13102 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13103 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13104 tcg_temp_free_i32(sa_v
);
13107 case OPC_PRECRQ_OB_QH
:
13109 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13111 case OPC_PRECRQ_PW_L
:
13113 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13115 case OPC_PRECRQ_QH_PW
:
13117 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13119 case OPC_PRECRQ_RS_QH_PW
:
13121 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13123 case OPC_PRECRQU_S_OB_QH
:
13125 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13132 tcg_temp_free(v1_t
);
13133 tcg_temp_free(v2_t
);
13135 (void)opn
; /* avoid a compiler warning */
13136 MIPS_DEBUG("%s", opn
);
13139 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13140 int ret
, int v1
, int v2
)
13143 const char *opn
= "mipsdsp shift";
13149 /* Treat as NOP. */
13154 t0
= tcg_temp_new();
13155 v1_t
= tcg_temp_new();
13156 v2_t
= tcg_temp_new();
13158 tcg_gen_movi_tl(t0
, v1
);
13159 gen_load_gpr(v1_t
, v1
);
13160 gen_load_gpr(v2_t
, v2
);
13163 case OPC_SHLL_QB_DSP
:
13165 op2
= MASK_SHLL_QB(ctx
->opcode
);
13169 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13173 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13177 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13181 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13183 case OPC_SHLL_S_PH
:
13185 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13187 case OPC_SHLLV_S_PH
:
13189 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13193 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13195 case OPC_SHLLV_S_W
:
13197 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13201 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13205 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13209 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13213 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13217 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13219 case OPC_SHRA_R_QB
:
13221 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13225 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13227 case OPC_SHRAV_R_QB
:
13229 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13233 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13235 case OPC_SHRA_R_PH
:
13237 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13241 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13243 case OPC_SHRAV_R_PH
:
13245 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13249 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13251 case OPC_SHRAV_R_W
:
13253 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13255 default: /* Invalid */
13256 MIPS_INVAL("MASK SHLL.QB");
13257 generate_exception(ctx
, EXCP_RI
);
13262 #ifdef TARGET_MIPS64
13263 case OPC_SHLL_OB_DSP
:
13264 op2
= MASK_SHLL_OB(ctx
->opcode
);
13268 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13272 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13274 case OPC_SHLL_S_PW
:
13276 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13278 case OPC_SHLLV_S_PW
:
13280 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13284 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13288 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13292 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13296 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13298 case OPC_SHLL_S_QH
:
13300 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13302 case OPC_SHLLV_S_QH
:
13304 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13308 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13312 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13314 case OPC_SHRA_R_OB
:
13316 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13318 case OPC_SHRAV_R_OB
:
13320 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13324 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13328 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13330 case OPC_SHRA_R_PW
:
13332 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13334 case OPC_SHRAV_R_PW
:
13336 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13340 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13344 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13346 case OPC_SHRA_R_QH
:
13348 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13350 case OPC_SHRAV_R_QH
:
13352 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13356 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13360 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13364 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13368 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13370 default: /* Invalid */
13371 MIPS_INVAL("MASK SHLL.OB");
13372 generate_exception(ctx
, EXCP_RI
);
13380 tcg_temp_free(v1_t
);
13381 tcg_temp_free(v2_t
);
13382 (void)opn
; /* avoid a compiler warning */
13383 MIPS_DEBUG("%s", opn
);
13386 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13387 int ret
, int v1
, int v2
, int check_ret
)
13389 const char *opn
= "mipsdsp multiply";
13394 if ((ret
== 0) && (check_ret
== 1)) {
13395 /* Treat as NOP. */
13400 t0
= tcg_temp_new_i32();
13401 v1_t
= tcg_temp_new();
13402 v2_t
= tcg_temp_new();
13404 tcg_gen_movi_i32(t0
, ret
);
13405 gen_load_gpr(v1_t
, v1
);
13406 gen_load_gpr(v2_t
, v2
);
13409 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13410 * the same mask and op1. */
13411 case OPC_MULT_G_2E
:
13414 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13417 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13420 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13422 case OPC_MULQ_RS_W
:
13423 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13427 case OPC_DPA_W_PH_DSP
:
13429 case OPC_DPAU_H_QBL
:
13431 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13433 case OPC_DPAU_H_QBR
:
13435 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13437 case OPC_DPSU_H_QBL
:
13439 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13441 case OPC_DPSU_H_QBR
:
13443 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13447 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13449 case OPC_DPAX_W_PH
:
13451 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13453 case OPC_DPAQ_S_W_PH
:
13455 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13457 case OPC_DPAQX_S_W_PH
:
13459 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13461 case OPC_DPAQX_SA_W_PH
:
13463 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13467 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13469 case OPC_DPSX_W_PH
:
13471 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13473 case OPC_DPSQ_S_W_PH
:
13475 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13477 case OPC_DPSQX_S_W_PH
:
13479 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13481 case OPC_DPSQX_SA_W_PH
:
13483 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13485 case OPC_MULSAQ_S_W_PH
:
13487 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13489 case OPC_DPAQ_SA_L_W
:
13491 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13493 case OPC_DPSQ_SA_L_W
:
13495 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13497 case OPC_MAQ_S_W_PHL
:
13499 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13501 case OPC_MAQ_S_W_PHR
:
13503 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13505 case OPC_MAQ_SA_W_PHL
:
13507 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13509 case OPC_MAQ_SA_W_PHR
:
13511 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13513 case OPC_MULSA_W_PH
:
13515 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13519 #ifdef TARGET_MIPS64
13520 case OPC_DPAQ_W_QH_DSP
:
13522 int ac
= ret
& 0x03;
13523 tcg_gen_movi_i32(t0
, ac
);
13528 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13532 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13536 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13540 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13544 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13546 case OPC_DPAQ_S_W_QH
:
13548 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13550 case OPC_DPAQ_SA_L_PW
:
13552 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13554 case OPC_DPAU_H_OBL
:
13556 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13558 case OPC_DPAU_H_OBR
:
13560 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13564 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13566 case OPC_DPSQ_S_W_QH
:
13568 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13570 case OPC_DPSQ_SA_L_PW
:
13572 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13574 case OPC_DPSU_H_OBL
:
13576 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13578 case OPC_DPSU_H_OBR
:
13580 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13582 case OPC_MAQ_S_L_PWL
:
13584 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13586 case OPC_MAQ_S_L_PWR
:
13588 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13590 case OPC_MAQ_S_W_QHLL
:
13592 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13594 case OPC_MAQ_SA_W_QHLL
:
13596 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13598 case OPC_MAQ_S_W_QHLR
:
13600 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13602 case OPC_MAQ_SA_W_QHLR
:
13604 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13606 case OPC_MAQ_S_W_QHRL
:
13608 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13610 case OPC_MAQ_SA_W_QHRL
:
13612 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13614 case OPC_MAQ_S_W_QHRR
:
13616 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13618 case OPC_MAQ_SA_W_QHRR
:
13620 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13622 case OPC_MULSAQ_S_L_PW
:
13624 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13626 case OPC_MULSAQ_S_W_QH
:
13628 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13634 case OPC_ADDU_QB_DSP
:
13636 case OPC_MULEU_S_PH_QBL
:
13638 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13640 case OPC_MULEU_S_PH_QBR
:
13642 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13644 case OPC_MULQ_RS_PH
:
13646 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13648 case OPC_MULEQ_S_W_PHL
:
13650 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13652 case OPC_MULEQ_S_W_PHR
:
13654 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13656 case OPC_MULQ_S_PH
:
13658 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13662 #ifdef TARGET_MIPS64
13663 case OPC_ADDU_OB_DSP
:
13665 case OPC_MULEQ_S_PW_QHL
:
13667 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13669 case OPC_MULEQ_S_PW_QHR
:
13671 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13673 case OPC_MULEU_S_QH_OBL
:
13675 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13677 case OPC_MULEU_S_QH_OBR
:
13679 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13681 case OPC_MULQ_RS_QH
:
13683 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13690 tcg_temp_free_i32(t0
);
13691 tcg_temp_free(v1_t
);
13692 tcg_temp_free(v2_t
);
13694 (void)opn
; /* avoid a compiler warning */
13695 MIPS_DEBUG("%s", opn
);
13699 static void gen_mipsdsp_bitinsn(CPUMIPSState
*env
, DisasContext
*ctx
,
13700 uint32_t op1
, uint32_t op2
,
13703 const char *opn
= "mipsdsp Bit/ Manipulation";
13709 /* Treat as NOP. */
13714 t0
= tcg_temp_new();
13715 val_t
= tcg_temp_new();
13716 gen_load_gpr(val_t
, val
);
13719 case OPC_ABSQ_S_PH_DSP
:
13723 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13728 target_long result
;
13729 imm
= (ctx
->opcode
>> 16) & 0xFF;
13730 result
= (uint32_t)imm
<< 24 |
13731 (uint32_t)imm
<< 16 |
13732 (uint32_t)imm
<< 8 |
13734 result
= (int32_t)result
;
13735 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13740 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13741 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13742 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13743 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13744 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13745 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13750 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13751 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13752 (target_long
)((int32_t)imm
<< 16 | \
13753 (uint32_t)(uint16_t)imm
));
13758 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13759 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13760 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13761 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13765 #ifdef TARGET_MIPS64
13766 case OPC_ABSQ_S_QH_DSP
:
13773 imm
= (ctx
->opcode
>> 16) & 0xFF;
13774 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13775 temp
= (temp
<< 16) | temp
;
13776 temp
= (temp
<< 32) | temp
;
13777 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13785 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13786 imm
= (int16_t)(imm
<< 6) >> 6;
13787 temp
= ((target_long
)imm
<< 32) \
13788 | ((target_long
)imm
& 0xFFFFFFFF);
13789 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13797 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13798 imm
= (int16_t)(imm
<< 6) >> 6;
13800 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13801 ((uint64_t)(uint16_t)imm
<< 32) |
13802 ((uint64_t)(uint16_t)imm
<< 16) |
13803 (uint64_t)(uint16_t)imm
;
13804 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13809 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13810 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13811 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13812 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13813 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13814 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13815 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13819 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13820 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13821 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13825 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13826 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13827 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13828 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13829 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13836 tcg_temp_free(val_t
);
13838 (void)opn
; /* avoid a compiler warning */
13839 MIPS_DEBUG("%s", opn
);
13842 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13843 uint32_t op1
, uint32_t op2
,
13844 int ret
, int v1
, int v2
, int check_ret
)
13846 const char *opn
= "mipsdsp add compare pick";
13852 if ((ret
== 0) && (check_ret
== 1)) {
13853 /* Treat as NOP. */
13858 t0
= tcg_temp_new_i32();
13859 t1
= tcg_temp_new();
13860 v1_t
= tcg_temp_new();
13861 v2_t
= tcg_temp_new();
13863 gen_load_gpr(v1_t
, v1
);
13864 gen_load_gpr(v2_t
, v2
);
13867 case OPC_APPEND_DSP
:
13870 tcg_gen_movi_i32(t0
, v2
);
13871 gen_helper_append(cpu_gpr
[ret
], cpu_gpr
[ret
], v1_t
, t0
);
13874 tcg_gen_movi_i32(t0
, v2
);
13875 gen_helper_prepend(cpu_gpr
[ret
], v1_t
, cpu_gpr
[ret
], t0
);
13878 tcg_gen_movi_i32(t0
, v2
);
13879 gen_helper_balign(cpu_gpr
[ret
], v1_t
, cpu_gpr
[ret
], t0
);
13881 default: /* Invid */
13882 MIPS_INVAL("MASK APPEND");
13883 generate_exception(ctx
, EXCP_RI
);
13887 case OPC_CMPU_EQ_QB_DSP
:
13889 case OPC_CMPU_EQ_QB
:
13891 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13893 case OPC_CMPU_LT_QB
:
13895 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13897 case OPC_CMPU_LE_QB
:
13899 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13901 case OPC_CMPGU_EQ_QB
:
13903 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13905 case OPC_CMPGU_LT_QB
:
13907 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13909 case OPC_CMPGU_LE_QB
:
13911 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13913 case OPC_CMPGDU_EQ_QB
:
13915 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13916 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13917 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13918 tcg_gen_shli_tl(t1
, t1
, 24);
13919 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13921 case OPC_CMPGDU_LT_QB
:
13923 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13924 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13925 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13926 tcg_gen_shli_tl(t1
, t1
, 24);
13927 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13929 case OPC_CMPGDU_LE_QB
:
13931 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13932 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13933 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13934 tcg_gen_shli_tl(t1
, t1
, 24);
13935 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13937 case OPC_CMP_EQ_PH
:
13939 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13941 case OPC_CMP_LT_PH
:
13943 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13945 case OPC_CMP_LE_PH
:
13947 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13951 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13955 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13957 case OPC_PACKRL_PH
:
13959 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13963 #ifdef TARGET_MIPS64
13964 case OPC_CMPU_EQ_OB_DSP
:
13966 case OPC_CMP_EQ_PW
:
13968 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13970 case OPC_CMP_LT_PW
:
13972 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13974 case OPC_CMP_LE_PW
:
13976 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13978 case OPC_CMP_EQ_QH
:
13980 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13982 case OPC_CMP_LT_QH
:
13984 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13986 case OPC_CMP_LE_QH
:
13988 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13990 case OPC_CMPGDU_EQ_OB
:
13992 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13994 case OPC_CMPGDU_LT_OB
:
13996 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13998 case OPC_CMPGDU_LE_OB
:
14000 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14002 case OPC_CMPGU_EQ_OB
:
14004 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14006 case OPC_CMPGU_LT_OB
:
14008 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14010 case OPC_CMPGU_LE_OB
:
14012 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14014 case OPC_CMPU_EQ_OB
:
14016 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14018 case OPC_CMPU_LT_OB
:
14020 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14022 case OPC_CMPU_LE_OB
:
14024 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14026 case OPC_PACKRL_PW
:
14028 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14032 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14036 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14040 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14044 case OPC_DAPPEND_DSP
:
14047 tcg_gen_movi_i32(t0
, v2
);
14048 gen_helper_dappend(cpu_gpr
[ret
], v1_t
, cpu_gpr
[ret
], t0
);
14051 tcg_gen_movi_i32(t0
, v2
);
14052 gen_helper_prependd(cpu_gpr
[ret
], v1_t
, cpu_gpr
[ret
], t0
);
14055 tcg_gen_movi_i32(t0
, v2
);
14056 gen_helper_prependw(cpu_gpr
[ret
], v1_t
, cpu_gpr
[ret
], t0
);
14059 tcg_gen_movi_i32(t0
, v2
);
14060 gen_helper_dbalign(cpu_gpr
[ret
], v1_t
, cpu_gpr
[ret
], t0
);
14062 default: /* Invalid */
14063 MIPS_INVAL("MASK DAPPEND");
14064 generate_exception(ctx
, EXCP_RI
);
14071 tcg_temp_free_i32(t0
);
14073 tcg_temp_free(v1_t
);
14074 tcg_temp_free(v2_t
);
14076 (void)opn
; /* avoid a compiler warning */
14077 MIPS_DEBUG("%s", opn
);
14080 /* End MIPSDSP functions. */
14082 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
14085 int rs
, rt
, rd
, sa
;
14086 uint32_t op
, op1
, op2
;
14089 /* make sure instructions are on a word boundary */
14090 if (ctx
->pc
& 0x3) {
14091 env
->CP0_BadVAddr
= ctx
->pc
;
14092 generate_exception(ctx
, EXCP_AdEL
);
14096 /* Handle blikely not taken case */
14097 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14098 int l1
= gen_new_label();
14100 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14101 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14102 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14103 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14107 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14108 tcg_gen_debug_insn_start(ctx
->pc
);
14111 op
= MASK_OP_MAJOR(ctx
->opcode
);
14112 rs
= (ctx
->opcode
>> 21) & 0x1f;
14113 rt
= (ctx
->opcode
>> 16) & 0x1f;
14114 rd
= (ctx
->opcode
>> 11) & 0x1f;
14115 sa
= (ctx
->opcode
>> 6) & 0x1f;
14116 imm
= (int16_t)ctx
->opcode
;
14119 op1
= MASK_SPECIAL(ctx
->opcode
);
14121 case OPC_SLL
: /* Shift with immediate */
14123 gen_shift_imm(env
, ctx
, op1
, rd
, rt
, sa
);
14126 switch ((ctx
->opcode
>> 21) & 0x1f) {
14128 /* rotr is decoded as srl on non-R2 CPUs */
14129 if (env
->insn_flags
& ISA_MIPS32R2
) {
14134 gen_shift_imm(env
, ctx
, op1
, rd
, rt
, sa
);
14137 generate_exception(ctx
, EXCP_RI
);
14141 case OPC_MOVN
: /* Conditional move */
14143 check_insn(env
, ctx
, ISA_MIPS4
| ISA_MIPS32
|
14144 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14145 gen_cond_move(env
, ctx
, op1
, rd
, rs
, rt
);
14147 case OPC_ADD
... OPC_SUBU
:
14148 gen_arith(env
, ctx
, op1
, rd
, rs
, rt
);
14150 case OPC_SLLV
: /* Shifts */
14152 gen_shift(env
, ctx
, op1
, rd
, rs
, rt
);
14155 switch ((ctx
->opcode
>> 6) & 0x1f) {
14157 /* rotrv is decoded as srlv on non-R2 CPUs */
14158 if (env
->insn_flags
& ISA_MIPS32R2
) {
14163 gen_shift(env
, ctx
, op1
, rd
, rs
, rt
);
14166 generate_exception(ctx
, EXCP_RI
);
14170 case OPC_SLT
: /* Set on less than */
14172 gen_slt(env
, ctx
, op1
, rd
, rs
, rt
);
14174 case OPC_AND
: /* Logic*/
14178 gen_logic(env
, ctx
, op1
, rd
, rs
, rt
);
14180 case OPC_MULT
... OPC_DIVU
:
14182 check_insn(env
, ctx
, INSN_VR54XX
);
14183 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14184 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14186 gen_muldiv(ctx
, op1
, rs
, rt
);
14188 case OPC_JR
... OPC_JALR
:
14189 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14192 case OPC_TGE
... OPC_TEQ
: /* Traps */
14194 gen_trap(ctx
, op1
, rs
, rt
, -1);
14196 case OPC_MFHI
: /* Move from HI/LO */
14198 gen_HILO(ctx
, op1
, rd
);
14201 case OPC_MTLO
: /* Move to HI/LO */
14202 gen_HILO(ctx
, op1
, rs
);
14204 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14205 #ifdef MIPS_STRICT_STANDARD
14206 MIPS_INVAL("PMON / selsl");
14207 generate_exception(ctx
, EXCP_RI
);
14209 gen_helper_0e0i(pmon
, sa
);
14213 generate_exception(ctx
, EXCP_SYSCALL
);
14214 ctx
->bstate
= BS_STOP
;
14217 generate_exception(ctx
, EXCP_BREAK
);
14220 #ifdef MIPS_STRICT_STANDARD
14221 MIPS_INVAL("SPIM");
14222 generate_exception(ctx
, EXCP_RI
);
14224 /* Implemented as RI exception for now. */
14225 MIPS_INVAL("spim (unofficial)");
14226 generate_exception(ctx
, EXCP_RI
);
14230 /* Treat as NOP. */
14234 check_insn(env
, ctx
, ISA_MIPS4
| ISA_MIPS32
);
14235 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14236 check_cp1_enabled(ctx
);
14237 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14238 (ctx
->opcode
>> 16) & 1);
14240 generate_exception_err(ctx
, EXCP_CpU
, 1);
14244 #if defined(TARGET_MIPS64)
14245 /* MIPS64 specific opcodes */
14250 check_insn(env
, ctx
, ISA_MIPS3
);
14251 check_mips_64(ctx
);
14252 gen_shift_imm(env
, ctx
, op1
, rd
, rt
, sa
);
14255 switch ((ctx
->opcode
>> 21) & 0x1f) {
14257 /* drotr is decoded as dsrl on non-R2 CPUs */
14258 if (env
->insn_flags
& ISA_MIPS32R2
) {
14263 check_insn(env
, ctx
, ISA_MIPS3
);
14264 check_mips_64(ctx
);
14265 gen_shift_imm(env
, ctx
, op1
, rd
, rt
, sa
);
14268 generate_exception(ctx
, EXCP_RI
);
14273 switch ((ctx
->opcode
>> 21) & 0x1f) {
14275 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14276 if (env
->insn_flags
& ISA_MIPS32R2
) {
14281 check_insn(env
, ctx
, ISA_MIPS3
);
14282 check_mips_64(ctx
);
14283 gen_shift_imm(env
, ctx
, op1
, rd
, rt
, sa
);
14286 generate_exception(ctx
, EXCP_RI
);
14290 case OPC_DADD
... OPC_DSUBU
:
14291 check_insn(env
, ctx
, ISA_MIPS3
);
14292 check_mips_64(ctx
);
14293 gen_arith(env
, ctx
, op1
, rd
, rs
, rt
);
14297 check_insn(env
, ctx
, ISA_MIPS3
);
14298 check_mips_64(ctx
);
14299 gen_shift(env
, ctx
, op1
, rd
, rs
, rt
);
14302 switch ((ctx
->opcode
>> 6) & 0x1f) {
14304 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14305 if (env
->insn_flags
& ISA_MIPS32R2
) {
14310 check_insn(env
, ctx
, ISA_MIPS3
);
14311 check_mips_64(ctx
);
14312 gen_shift(env
, ctx
, op1
, rd
, rs
, rt
);
14315 generate_exception(ctx
, EXCP_RI
);
14319 case OPC_DMULT
... OPC_DDIVU
:
14320 check_insn(env
, ctx
, ISA_MIPS3
);
14321 check_mips_64(ctx
);
14322 gen_muldiv(ctx
, op1
, rs
, rt
);
14325 default: /* Invalid */
14326 MIPS_INVAL("special");
14327 generate_exception(ctx
, EXCP_RI
);
14332 op1
= MASK_SPECIAL2(ctx
->opcode
);
14334 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14335 case OPC_MSUB
... OPC_MSUBU
:
14336 check_insn(env
, ctx
, ISA_MIPS32
);
14337 gen_muldiv(ctx
, op1
, rs
, rt
);
14340 gen_arith(env
, ctx
, op1
, rd
, rs
, rt
);
14344 check_insn(env
, ctx
, ISA_MIPS32
);
14345 gen_cl(ctx
, op1
, rd
, rs
);
14348 /* XXX: not clear which exception should be raised
14349 * when in debug mode...
14351 check_insn(env
, ctx
, ISA_MIPS32
);
14352 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14353 generate_exception(ctx
, EXCP_DBp
);
14355 generate_exception(ctx
, EXCP_DBp
);
14357 /* Treat as NOP. */
14360 case OPC_DIVU_G_2F
:
14361 case OPC_MULT_G_2F
:
14362 case OPC_MULTU_G_2F
:
14364 case OPC_MODU_G_2F
:
14365 check_insn(env
, ctx
, INSN_LOONGSON2F
);
14366 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14368 #if defined(TARGET_MIPS64)
14371 check_insn(env
, ctx
, ISA_MIPS64
);
14372 check_mips_64(ctx
);
14373 gen_cl(ctx
, op1
, rd
, rs
);
14375 case OPC_DMULT_G_2F
:
14376 case OPC_DMULTU_G_2F
:
14377 case OPC_DDIV_G_2F
:
14378 case OPC_DDIVU_G_2F
:
14379 case OPC_DMOD_G_2F
:
14380 case OPC_DMODU_G_2F
:
14381 check_insn(env
, ctx
, INSN_LOONGSON2F
);
14382 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14385 default: /* Invalid */
14386 MIPS_INVAL("special2");
14387 generate_exception(ctx
, EXCP_RI
);
14392 op1
= MASK_SPECIAL3(ctx
->opcode
);
14396 check_insn(env
, ctx
, ISA_MIPS32R2
);
14397 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14400 check_insn(env
, ctx
, ISA_MIPS32R2
);
14401 op2
= MASK_BSHFL(ctx
->opcode
);
14402 gen_bshfl(ctx
, op2
, rt
, rd
);
14405 gen_rdhwr(env
, ctx
, rt
, rd
);
14408 check_insn(env
, ctx
, ASE_MT
);
14410 TCGv t0
= tcg_temp_new();
14411 TCGv t1
= tcg_temp_new();
14413 gen_load_gpr(t0
, rt
);
14414 gen_load_gpr(t1
, rs
);
14415 gen_helper_fork(t0
, t1
);
14421 check_insn(env
, ctx
, ASE_MT
);
14423 TCGv t0
= tcg_temp_new();
14425 save_cpu_state(ctx
, 1);
14426 gen_load_gpr(t0
, rs
);
14427 gen_helper_yield(t0
, cpu_env
, t0
);
14428 gen_store_gpr(t0
, rd
);
14432 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14433 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14434 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14435 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14436 * the same mask and op1. */
14437 if ((env
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14438 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14441 case OPC_ADDUH_R_QB
:
14443 case OPC_ADDQH_R_PH
:
14445 case OPC_ADDQH_R_W
:
14447 case OPC_SUBUH_R_QB
:
14449 case OPC_SUBQH_R_PH
:
14451 case OPC_SUBQH_R_W
:
14452 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14457 case OPC_MULQ_RS_W
:
14458 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14461 MIPS_INVAL("MASK ADDUH.QB");
14462 generate_exception(ctx
, EXCP_RI
);
14465 } else if (env
->insn_flags
& INSN_LOONGSON2E
) {
14466 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14468 generate_exception(ctx
, EXCP_RI
);
14472 op2
= MASK_LX(ctx
->opcode
);
14474 #if defined(TARGET_MIPS64)
14480 gen_mipsdsp_ld(env
, ctx
, op2
, rd
, rs
, rt
);
14482 default: /* Invalid */
14483 MIPS_INVAL("MASK LX");
14484 generate_exception(ctx
, EXCP_RI
);
14488 case OPC_ABSQ_S_PH_DSP
:
14489 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14491 case OPC_ABSQ_S_QB
:
14492 case OPC_ABSQ_S_PH
:
14494 case OPC_PRECEQ_W_PHL
:
14495 case OPC_PRECEQ_W_PHR
:
14496 case OPC_PRECEQU_PH_QBL
:
14497 case OPC_PRECEQU_PH_QBR
:
14498 case OPC_PRECEQU_PH_QBLA
:
14499 case OPC_PRECEQU_PH_QBRA
:
14500 case OPC_PRECEU_PH_QBL
:
14501 case OPC_PRECEU_PH_QBR
:
14502 case OPC_PRECEU_PH_QBLA
:
14503 case OPC_PRECEU_PH_QBRA
:
14504 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14511 gen_mipsdsp_bitinsn(env
, ctx
, op1
, op2
, rd
, rt
);
14514 MIPS_INVAL("MASK ABSQ_S.PH");
14515 generate_exception(ctx
, EXCP_RI
);
14519 case OPC_ADDU_QB_DSP
:
14520 op2
= MASK_ADDU_QB(ctx
->opcode
);
14523 case OPC_ADDQ_S_PH
:
14526 case OPC_ADDU_S_QB
:
14528 case OPC_ADDU_S_PH
:
14530 case OPC_SUBQ_S_PH
:
14533 case OPC_SUBU_S_QB
:
14535 case OPC_SUBU_S_PH
:
14539 case OPC_RADDU_W_QB
:
14540 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14542 case OPC_MULEU_S_PH_QBL
:
14543 case OPC_MULEU_S_PH_QBR
:
14544 case OPC_MULQ_RS_PH
:
14545 case OPC_MULEQ_S_W_PHL
:
14546 case OPC_MULEQ_S_W_PHR
:
14547 case OPC_MULQ_S_PH
:
14548 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14550 default: /* Invalid */
14551 MIPS_INVAL("MASK ADDU.QB");
14552 generate_exception(ctx
, EXCP_RI
);
14557 case OPC_CMPU_EQ_QB_DSP
:
14558 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14560 case OPC_PRECR_SRA_PH_W
:
14561 case OPC_PRECR_SRA_R_PH_W
:
14562 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14564 case OPC_PRECR_QB_PH
:
14565 case OPC_PRECRQ_QB_PH
:
14566 case OPC_PRECRQ_PH_W
:
14567 case OPC_PRECRQ_RS_PH_W
:
14568 case OPC_PRECRQU_S_QB_PH
:
14569 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14571 case OPC_CMPU_EQ_QB
:
14572 case OPC_CMPU_LT_QB
:
14573 case OPC_CMPU_LE_QB
:
14574 case OPC_CMP_EQ_PH
:
14575 case OPC_CMP_LT_PH
:
14576 case OPC_CMP_LE_PH
:
14577 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14579 case OPC_CMPGU_EQ_QB
:
14580 case OPC_CMPGU_LT_QB
:
14581 case OPC_CMPGU_LE_QB
:
14582 case OPC_CMPGDU_EQ_QB
:
14583 case OPC_CMPGDU_LT_QB
:
14584 case OPC_CMPGDU_LE_QB
:
14587 case OPC_PACKRL_PH
:
14588 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14590 default: /* Invalid */
14591 MIPS_INVAL("MASK CMPU.EQ.QB");
14592 generate_exception(ctx
, EXCP_RI
);
14596 case OPC_SHLL_QB_DSP
:
14597 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14599 case OPC_DPA_W_PH_DSP
:
14600 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14602 case OPC_DPAU_H_QBL
:
14603 case OPC_DPAU_H_QBR
:
14604 case OPC_DPSU_H_QBL
:
14605 case OPC_DPSU_H_QBR
:
14607 case OPC_DPAX_W_PH
:
14608 case OPC_DPAQ_S_W_PH
:
14609 case OPC_DPAQX_S_W_PH
:
14610 case OPC_DPAQX_SA_W_PH
:
14612 case OPC_DPSX_W_PH
:
14613 case OPC_DPSQ_S_W_PH
:
14614 case OPC_DPSQX_S_W_PH
:
14615 case OPC_DPSQX_SA_W_PH
:
14616 case OPC_MULSAQ_S_W_PH
:
14617 case OPC_DPAQ_SA_L_W
:
14618 case OPC_DPSQ_SA_L_W
:
14619 case OPC_MAQ_S_W_PHL
:
14620 case OPC_MAQ_S_W_PHR
:
14621 case OPC_MAQ_SA_W_PHL
:
14622 case OPC_MAQ_SA_W_PHR
:
14623 case OPC_MULSA_W_PH
:
14624 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14626 default: /* Invalid */
14627 MIPS_INVAL("MASK DPAW.PH");
14628 generate_exception(ctx
, EXCP_RI
);
14633 op2
= MASK_INSV(ctx
->opcode
);
14645 t0
= tcg_temp_new();
14646 t1
= tcg_temp_new();
14648 gen_load_gpr(t0
, rt
);
14649 gen_load_gpr(t1
, rs
);
14651 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14657 default: /* Invalid */
14658 MIPS_INVAL("MASK INSV");
14659 generate_exception(ctx
, EXCP_RI
);
14663 case OPC_APPEND_DSP
:
14665 op2
= MASK_APPEND(ctx
->opcode
);
14666 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14668 #if defined(TARGET_MIPS64)
14669 case OPC_DEXTM
... OPC_DEXT
:
14670 case OPC_DINSM
... OPC_DINS
:
14671 check_insn(env
, ctx
, ISA_MIPS64R2
);
14672 check_mips_64(ctx
);
14673 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14676 check_insn(env
, ctx
, ISA_MIPS64R2
);
14677 check_mips_64(ctx
);
14678 op2
= MASK_DBSHFL(ctx
->opcode
);
14679 gen_bshfl(ctx
, op2
, rt
, rd
);
14681 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
14682 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
14683 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
14684 check_insn(env
, ctx
, INSN_LOONGSON2E
);
14685 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14687 case OPC_ABSQ_S_QH_DSP
:
14688 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
14690 case OPC_PRECEQ_L_PWL
:
14691 case OPC_PRECEQ_L_PWR
:
14692 case OPC_PRECEQ_PW_QHL
:
14693 case OPC_PRECEQ_PW_QHR
:
14694 case OPC_PRECEQ_PW_QHLA
:
14695 case OPC_PRECEQ_PW_QHRA
:
14696 case OPC_PRECEQU_QH_OBL
:
14697 case OPC_PRECEQU_QH_OBR
:
14698 case OPC_PRECEQU_QH_OBLA
:
14699 case OPC_PRECEQU_QH_OBRA
:
14700 case OPC_PRECEU_QH_OBL
:
14701 case OPC_PRECEU_QH_OBR
:
14702 case OPC_PRECEU_QH_OBLA
:
14703 case OPC_PRECEU_QH_OBRA
:
14704 case OPC_ABSQ_S_OB
:
14705 case OPC_ABSQ_S_PW
:
14706 case OPC_ABSQ_S_QH
:
14707 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14715 gen_mipsdsp_bitinsn(env
, ctx
, op1
, op2
, rd
, rt
);
14717 default: /* Invalid */
14718 MIPS_INVAL("MASK ABSQ_S.QH");
14719 generate_exception(ctx
, EXCP_RI
);
14723 case OPC_ADDU_OB_DSP
:
14724 op2
= MASK_ADDU_OB(ctx
->opcode
);
14726 case OPC_RADDU_L_OB
:
14728 case OPC_SUBQ_S_PW
:
14730 case OPC_SUBQ_S_QH
:
14732 case OPC_SUBU_S_OB
:
14734 case OPC_SUBU_S_QH
:
14736 case OPC_SUBUH_R_OB
:
14738 case OPC_ADDQ_S_PW
:
14740 case OPC_ADDQ_S_QH
:
14742 case OPC_ADDU_S_OB
:
14744 case OPC_ADDU_S_QH
:
14746 case OPC_ADDUH_R_OB
:
14747 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14749 case OPC_MULEQ_S_PW_QHL
:
14750 case OPC_MULEQ_S_PW_QHR
:
14751 case OPC_MULEU_S_QH_OBL
:
14752 case OPC_MULEU_S_QH_OBR
:
14753 case OPC_MULQ_RS_QH
:
14754 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14756 default: /* Invalid */
14757 MIPS_INVAL("MASK ADDU.OB");
14758 generate_exception(ctx
, EXCP_RI
);
14762 case OPC_CMPU_EQ_OB_DSP
:
14763 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
14765 case OPC_PRECR_SRA_QH_PW
:
14766 case OPC_PRECR_SRA_R_QH_PW
:
14767 /* Return value is rt. */
14768 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14770 case OPC_PRECR_OB_QH
:
14771 case OPC_PRECRQ_OB_QH
:
14772 case OPC_PRECRQ_PW_L
:
14773 case OPC_PRECRQ_QH_PW
:
14774 case OPC_PRECRQ_RS_QH_PW
:
14775 case OPC_PRECRQU_S_OB_QH
:
14776 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14778 case OPC_CMPU_EQ_OB
:
14779 case OPC_CMPU_LT_OB
:
14780 case OPC_CMPU_LE_OB
:
14781 case OPC_CMP_EQ_QH
:
14782 case OPC_CMP_LT_QH
:
14783 case OPC_CMP_LE_QH
:
14784 case OPC_CMP_EQ_PW
:
14785 case OPC_CMP_LT_PW
:
14786 case OPC_CMP_LE_PW
:
14787 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14789 case OPC_CMPGDU_EQ_OB
:
14790 case OPC_CMPGDU_LT_OB
:
14791 case OPC_CMPGDU_LE_OB
:
14792 case OPC_CMPGU_EQ_OB
:
14793 case OPC_CMPGU_LT_OB
:
14794 case OPC_CMPGU_LE_OB
:
14795 case OPC_PACKRL_PW
:
14799 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14801 default: /* Invalid */
14802 MIPS_INVAL("MASK CMPU_EQ.OB");
14803 generate_exception(ctx
, EXCP_RI
);
14807 case OPC_DAPPEND_DSP
:
14809 op2
= MASK_DAPPEND(ctx
->opcode
);
14810 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14812 case OPC_DPAQ_W_QH_DSP
:
14813 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
14815 case OPC_DPAU_H_OBL
:
14816 case OPC_DPAU_H_OBR
:
14817 case OPC_DPSU_H_OBL
:
14818 case OPC_DPSU_H_OBR
:
14820 case OPC_DPAQ_S_W_QH
:
14822 case OPC_DPSQ_S_W_QH
:
14823 case OPC_MULSAQ_S_W_QH
:
14824 case OPC_DPAQ_SA_L_PW
:
14825 case OPC_DPSQ_SA_L_PW
:
14826 case OPC_MULSAQ_S_L_PW
:
14827 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14829 case OPC_MAQ_S_W_QHLL
:
14830 case OPC_MAQ_S_W_QHLR
:
14831 case OPC_MAQ_S_W_QHRL
:
14832 case OPC_MAQ_S_W_QHRR
:
14833 case OPC_MAQ_SA_W_QHLL
:
14834 case OPC_MAQ_SA_W_QHLR
:
14835 case OPC_MAQ_SA_W_QHRL
:
14836 case OPC_MAQ_SA_W_QHRR
:
14837 case OPC_MAQ_S_L_PWL
:
14838 case OPC_MAQ_S_L_PWR
:
14843 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14845 default: /* Invalid */
14846 MIPS_INVAL("MASK DPAQ.W.QH");
14847 generate_exception(ctx
, EXCP_RI
);
14851 case OPC_DINSV_DSP
:
14852 op2
= MASK_INSV(ctx
->opcode
);
14864 t0
= tcg_temp_new();
14865 t1
= tcg_temp_new();
14867 gen_load_gpr(t0
, rt
);
14868 gen_load_gpr(t1
, rs
);
14870 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14873 default: /* Invalid */
14874 MIPS_INVAL("MASK DINSV");
14875 generate_exception(ctx
, EXCP_RI
);
14879 case OPC_SHLL_OB_DSP
:
14880 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14883 default: /* Invalid */
14884 MIPS_INVAL("special3");
14885 generate_exception(ctx
, EXCP_RI
);
14890 op1
= MASK_REGIMM(ctx
->opcode
);
14892 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
14893 case OPC_BLTZAL
... OPC_BGEZALL
:
14894 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
14897 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
14899 gen_trap(ctx
, op1
, rs
, -1, imm
);
14902 check_insn(env
, ctx
, ISA_MIPS32R2
);
14903 /* Treat as NOP. */
14905 case OPC_BPOSGE32
: /* MIPS DSP branch */
14906 #if defined(TARGET_MIPS64)
14910 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
14913 default: /* Invalid */
14914 MIPS_INVAL("regimm");
14915 generate_exception(ctx
, EXCP_RI
);
14920 check_cp0_enabled(ctx
);
14921 op1
= MASK_CP0(ctx
->opcode
);
14927 #if defined(TARGET_MIPS64)
14931 #ifndef CONFIG_USER_ONLY
14932 gen_cp0(env
, ctx
, op1
, rt
, rd
);
14933 #endif /* !CONFIG_USER_ONLY */
14935 case OPC_C0_FIRST
... OPC_C0_LAST
:
14936 #ifndef CONFIG_USER_ONLY
14937 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
14938 #endif /* !CONFIG_USER_ONLY */
14941 #ifndef CONFIG_USER_ONLY
14943 TCGv t0
= tcg_temp_new();
14945 op2
= MASK_MFMC0(ctx
->opcode
);
14948 check_insn(env
, ctx
, ASE_MT
);
14949 gen_helper_dmt(t0
);
14950 gen_store_gpr(t0
, rt
);
14953 check_insn(env
, ctx
, ASE_MT
);
14954 gen_helper_emt(t0
);
14955 gen_store_gpr(t0
, rt
);
14958 check_insn(env
, ctx
, ASE_MT
);
14959 gen_helper_dvpe(t0
, cpu_env
);
14960 gen_store_gpr(t0
, rt
);
14963 check_insn(env
, ctx
, ASE_MT
);
14964 gen_helper_evpe(t0
, cpu_env
);
14965 gen_store_gpr(t0
, rt
);
14968 check_insn(env
, ctx
, ISA_MIPS32R2
);
14969 save_cpu_state(ctx
, 1);
14970 gen_helper_di(t0
, cpu_env
);
14971 gen_store_gpr(t0
, rt
);
14972 /* Stop translation as we may have switched the execution mode */
14973 ctx
->bstate
= BS_STOP
;
14976 check_insn(env
, ctx
, ISA_MIPS32R2
);
14977 save_cpu_state(ctx
, 1);
14978 gen_helper_ei(t0
, cpu_env
);
14979 gen_store_gpr(t0
, rt
);
14980 /* Stop translation as we may have switched the execution mode */
14981 ctx
->bstate
= BS_STOP
;
14983 default: /* Invalid */
14984 MIPS_INVAL("mfmc0");
14985 generate_exception(ctx
, EXCP_RI
);
14990 #endif /* !CONFIG_USER_ONLY */
14993 check_insn(env
, ctx
, ISA_MIPS32R2
);
14994 gen_load_srsgpr(rt
, rd
);
14997 check_insn(env
, ctx
, ISA_MIPS32R2
);
14998 gen_store_srsgpr(rt
, rd
);
15002 generate_exception(ctx
, EXCP_RI
);
15006 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15008 gen_arith_imm(env
, ctx
, op
, rt
, rs
, imm
);
15010 case OPC_SLTI
: /* Set on less than with immediate opcode */
15012 gen_slt_imm(env
, ctx
, op
, rt
, rs
, imm
);
15014 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15018 gen_logic_imm(env
, ctx
, op
, rt
, rs
, imm
);
15020 case OPC_J
... OPC_JAL
: /* Jump */
15021 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15022 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15025 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15026 case OPC_BEQL
... OPC_BGTZL
:
15027 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15030 case OPC_LB
... OPC_LWR
: /* Load and stores */
15032 gen_ld(env
, ctx
, op
, rt
, rs
, imm
);
15034 case OPC_SB
... OPC_SW
:
15036 gen_st(ctx
, op
, rt
, rs
, imm
);
15039 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15042 check_cp0_enabled(ctx
);
15043 check_insn(env
, ctx
, ISA_MIPS3
| ISA_MIPS32
);
15044 /* Treat as NOP. */
15047 check_insn(env
, ctx
, ISA_MIPS4
| ISA_MIPS32
);
15048 /* Treat as NOP. */
15051 /* Floating point (COP1). */
15056 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15060 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15061 check_cp1_enabled(ctx
);
15062 op1
= MASK_CP1(ctx
->opcode
);
15066 check_insn(env
, ctx
, ISA_MIPS32R2
);
15071 gen_cp1(ctx
, op1
, rt
, rd
);
15073 #if defined(TARGET_MIPS64)
15076 check_insn(env
, ctx
, ISA_MIPS3
);
15077 gen_cp1(ctx
, op1
, rt
, rd
);
15083 check_insn(env
, ctx
, ASE_MIPS3D
);
15086 gen_compute_branch1(env
, ctx
, MASK_BC1(ctx
->opcode
),
15087 (rt
>> 2) & 0x7, imm
<< 2);
15095 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15100 generate_exception (ctx
, EXCP_RI
);
15104 generate_exception_err(ctx
, EXCP_CpU
, 1);
15113 /* COP2: Not implemented. */
15114 generate_exception_err(ctx
, EXCP_CpU
, 2);
15117 check_insn(env
, ctx
, INSN_LOONGSON2F
);
15118 /* Note that these instructions use different fields. */
15119 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15123 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15124 check_cp1_enabled(ctx
);
15125 op1
= MASK_CP3(ctx
->opcode
);
15133 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15136 /* Treat as NOP. */
15151 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15155 generate_exception (ctx
, EXCP_RI
);
15159 generate_exception_err(ctx
, EXCP_CpU
, 1);
15163 #if defined(TARGET_MIPS64)
15164 /* MIPS64 opcodes */
15166 case OPC_LDL
... OPC_LDR
:
15169 check_insn(env
, ctx
, ISA_MIPS3
);
15170 check_mips_64(ctx
);
15171 gen_ld(env
, ctx
, op
, rt
, rs
, imm
);
15173 case OPC_SDL
... OPC_SDR
:
15175 check_insn(env
, ctx
, ISA_MIPS3
);
15176 check_mips_64(ctx
);
15177 gen_st(ctx
, op
, rt
, rs
, imm
);
15180 check_insn(env
, ctx
, ISA_MIPS3
);
15181 check_mips_64(ctx
);
15182 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15186 check_insn(env
, ctx
, ISA_MIPS3
);
15187 check_mips_64(ctx
);
15188 gen_arith_imm(env
, ctx
, op
, rt
, rs
, imm
);
15192 check_insn(env
, ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15193 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15194 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15198 check_insn(env
, ctx
, ASE_MDMX
);
15199 /* MDMX: Not implemented. */
15200 default: /* Invalid */
15201 MIPS_INVAL("major opcode");
15202 generate_exception(ctx
, EXCP_RI
);
15208 gen_intermediate_code_internal (CPUMIPSState
*env
, TranslationBlock
*tb
,
15212 target_ulong pc_start
;
15213 uint16_t *gen_opc_end
;
15222 qemu_log("search pc %d\n", search_pc
);
15225 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
15228 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
15230 ctx
.bstate
= BS_NONE
;
15231 /* Restore delay slot state from the tb context. */
15232 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15233 restore_cpu_state(env
, &ctx
);
15234 #ifdef CONFIG_USER_ONLY
15235 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15237 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15240 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15241 if (max_insns
== 0)
15242 max_insns
= CF_COUNT_MASK
;
15243 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15244 gen_icount_start();
15245 while (ctx
.bstate
== BS_NONE
) {
15246 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15247 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15248 if (bp
->pc
== ctx
.pc
) {
15249 save_cpu_state(&ctx
, 1);
15250 ctx
.bstate
= BS_BRANCH
;
15251 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15252 /* Include the breakpoint location or the tb won't
15253 * be flushed when it must be. */
15255 goto done_generating
;
15261 j
= gen_opc_ptr
- gen_opc_buf
;
15265 gen_opc_instr_start
[lj
++] = 0;
15267 gen_opc_pc
[lj
] = ctx
.pc
;
15268 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15269 gen_opc_instr_start
[lj
] = 1;
15270 gen_opc_icount
[lj
] = num_insns
;
15272 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15276 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15277 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15279 decode_opc(env
, &ctx
, &is_branch
);
15280 } else if (env
->insn_flags
& ASE_MICROMIPS
) {
15281 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15282 insn_bytes
= decode_micromips_opc(env
, &ctx
, &is_branch
);
15283 } else if (env
->insn_flags
& ASE_MIPS16
) {
15284 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15285 insn_bytes
= decode_mips16_opc(env
, &ctx
, &is_branch
);
15287 generate_exception(&ctx
, EXCP_RI
);
15288 ctx
.bstate
= BS_STOP
;
15292 handle_delay_slot(env
, &ctx
, insn_bytes
);
15294 ctx
.pc
+= insn_bytes
;
15298 /* Execute a branch and its delay slot as a single instruction.
15299 This is what GDB expects and is consistent with what the
15300 hardware does (e.g. if a delay slot instruction faults, the
15301 reported PC is the PC of the branch). */
15302 if (env
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0)
15305 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15308 if (gen_opc_ptr
>= gen_opc_end
)
15311 if (num_insns
>= max_insns
)
15317 if (tb
->cflags
& CF_LAST_IO
)
15319 if (env
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15320 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15321 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15323 switch (ctx
.bstate
) {
15325 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15328 save_cpu_state(&ctx
, 0);
15329 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15332 tcg_gen_exit_tb(0);
15340 gen_icount_end(tb
, num_insns
);
15341 *gen_opc_ptr
= INDEX_op_end
;
15343 j
= gen_opc_ptr
- gen_opc_buf
;
15346 gen_opc_instr_start
[lj
++] = 0;
15348 tb
->size
= ctx
.pc
- pc_start
;
15349 tb
->icount
= num_insns
;
15353 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15354 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15355 log_target_disas(pc_start
, ctx
.pc
- pc_start
, 0);
15361 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15363 gen_intermediate_code_internal(env
, tb
, 0);
15366 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15368 gen_intermediate_code_internal(env
, tb
, 1);
15371 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15375 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15377 #define printfpr(fp) \
15380 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15381 " fd:%13g fs:%13g psu: %13g\n", \
15382 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15383 (double)(fp)->fd, \
15384 (double)(fp)->fs[FP_ENDIAN_IDX], \
15385 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15388 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15389 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15390 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15391 " fd:%13g fs:%13g psu:%13g\n", \
15392 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15394 (double)tmp.fs[FP_ENDIAN_IDX], \
15395 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15400 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15401 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15402 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15403 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15404 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15405 printfpr(&env
->active_fpu
.fpr
[i
]);
15411 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15412 /* Debug help: The architecture requires 32bit code to maintain proper
15413 sign-extended values on 64bit machines. */
15415 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15418 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15419 fprintf_function cpu_fprintf
,
15424 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15425 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15426 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15427 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15428 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15429 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15430 if (!SIGN_EXT_P(env
->btarget
))
15431 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15433 for (i
= 0; i
< 32; i
++) {
15434 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15435 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15438 if (!SIGN_EXT_P(env
->CP0_EPC
))
15439 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15440 if (!SIGN_EXT_P(env
->lladdr
))
15441 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15445 void cpu_dump_state (CPUMIPSState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
15450 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15451 " LO=0x" TARGET_FMT_lx
" ds %04x "
15452 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15453 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15454 env
->hflags
, env
->btarget
, env
->bcond
);
15455 for (i
= 0; i
< 32; i
++) {
15457 cpu_fprintf(f
, "GPR%02d:", i
);
15458 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15460 cpu_fprintf(f
, "\n");
15463 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15464 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15465 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15466 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15467 if (env
->hflags
& MIPS_HFLAG_FPU
)
15468 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15469 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15470 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15474 static void mips_tcg_init(void)
15479 /* Initialize various static tables. */
15483 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15484 TCGV_UNUSED(cpu_gpr
[0]);
15485 for (i
= 1; i
< 32; i
++)
15486 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15487 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15490 for (i
= 0; i
< 32; i
++) {
15491 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15492 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15495 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15496 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15497 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15498 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15499 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15501 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15502 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15504 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15505 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15508 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15509 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15511 bcond
= tcg_global_mem_new(TCG_AREG0
,
15512 offsetof(CPUMIPSState
, bcond
), "bcond");
15513 btarget
= tcg_global_mem_new(TCG_AREG0
,
15514 offsetof(CPUMIPSState
, btarget
), "btarget");
15515 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15516 offsetof(CPUMIPSState
, hflags
), "hflags");
15518 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15519 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15521 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15522 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15525 /* register helpers */
15526 #define GEN_HELPER 2
15527 #include "helper.h"
15532 #include "translate_init.c"
15534 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15538 const mips_def_t
*def
;
15540 def
= cpu_mips_find_by_name(cpu_model
);
15543 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15545 env
->cpu_model
= def
;
15546 env
->cpu_model_str
= cpu_model
;
15548 #ifndef CONFIG_USER_ONLY
15549 mmu_init(env
, def
);
15551 fpu_init(env
, def
);
15552 mvp_init(env
, def
);
15554 cpu_reset(CPU(cpu
));
15555 qemu_init_vcpu(env
);
15559 void cpu_state_reset(CPUMIPSState
*env
)
15561 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
15562 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
15563 log_cpu_state(env
, 0);
15566 memset(env
, 0, offsetof(CPUMIPSState
, breakpoints
));
15569 /* Reset registers to their default values */
15570 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15571 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15572 #ifdef TARGET_WORDS_BIGENDIAN
15573 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15575 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15576 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15577 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15578 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15579 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15580 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15581 << env
->cpu_model
->CP0_LLAddr_shift
;
15582 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15583 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15584 env
->CCRes
= env
->cpu_model
->CCRes
;
15585 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15586 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15587 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15588 env
->current_tc
= 0;
15589 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15590 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15591 #if defined(TARGET_MIPS64)
15592 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15593 env
->SEGMask
|= 3ULL << 62;
15596 env
->PABITS
= env
->cpu_model
->PABITS
;
15597 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15598 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15599 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15600 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15601 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15602 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15603 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15604 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15605 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15606 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15607 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15608 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15609 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15611 #if defined(CONFIG_USER_ONLY)
15612 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15613 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15614 hardware registers. */
15615 env
->CP0_HWREna
|= 0x0000000F;
15616 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15617 env
->CP0_Status
|= (1 << CP0St_CU1
);
15619 if (env
->cpu_model
->insn_flags
& ASE_DSPR2
) {
15620 env
->hflags
|= MIPS_HFLAG_DSP
| MIPS_HFLAG_DSPR2
;
15621 } else if (env
->cpu_model
->insn_flags
& ASE_DSP
) {
15622 env
->hflags
|= MIPS_HFLAG_DSP
;
15625 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15626 /* If the exception was raised from a delay slot,
15627 come back to the jump. */
15628 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15630 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
15632 env
->active_tc
.PC
= (int32_t)0xBFC00000;
15633 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
15634 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
15635 env
->CP0_Wired
= 0;
15636 env
->CP0_EBase
= 0x80000000 | (env
->cpu_index
& 0x3FF);
15637 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
15638 /* vectored interrupts not implemented, timer on int 7,
15639 no performance counters. */
15640 env
->CP0_IntCtl
= 0xe0000000;
15644 for (i
= 0; i
< 7; i
++) {
15645 env
->CP0_WatchLo
[i
] = 0;
15646 env
->CP0_WatchHi
[i
] = 0x80000000;
15648 env
->CP0_WatchLo
[7] = 0;
15649 env
->CP0_WatchHi
[7] = 0;
15651 /* Count register increments in debug mode, EJTAG version 1 */
15652 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
15654 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
15657 /* Only TC0 on VPE 0 starts as active. */
15658 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
15659 env
->tcs
[i
].CP0_TCBind
= env
->cpu_index
<< CP0TCBd_CurVPE
;
15660 env
->tcs
[i
].CP0_TCHalt
= 1;
15662 env
->active_tc
.CP0_TCHalt
= 1;
15665 if (!env
->cpu_index
) {
15666 /* VPE0 starts up enabled. */
15667 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
15668 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
15670 /* TC0 starts up unhalted. */
15672 env
->active_tc
.CP0_TCHalt
= 0;
15673 env
->tcs
[0].CP0_TCHalt
= 0;
15674 /* With thread 0 active. */
15675 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
15676 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
15680 compute_hflags(env
);
15681 env
->exception_index
= EXCP_NONE
;
15684 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
15686 env
->active_tc
.PC
= gen_opc_pc
[pc_pos
];
15687 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
15688 env
->hflags
|= gen_opc_hflags
[pc_pos
];