2 * MIPS 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)
9 * Copyright (c) 2020 Philippe Mathieu-Daudé
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "qemu/osdep.h"
28 #include "tcg/tcg-op.h"
29 #include "exec/translator.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "semihosting/semihost.h"
35 #include "trace-tcg.h"
36 #include "exec/translator.h"
38 #include "qemu/qemu-print.h"
39 #include "fpu_helper.h"
40 #include "translate.h"
43 * Many sysemu-only helpers are not reachable for user-only.
44 * Define stub generators here, so that we need not either sprinkle
45 * ifdefs through the translator, nor provide the helper function.
47 #define STUB_HELPER(NAME, ...) \
48 static inline void gen_helper_##NAME(__VA_ARGS__) \
49 { g_assert_not_reached(); }
51 #ifdef CONFIG_USER_ONLY
52 STUB_HELPER(cache
, TCGv_env env
, TCGv val
, TCGv_i32 reg
)
56 /* indirect opcode tables */
57 OPC_SPECIAL
= (0x00 << 26),
58 OPC_REGIMM
= (0x01 << 26),
59 OPC_CP0
= (0x10 << 26),
60 OPC_CP2
= (0x12 << 26),
61 OPC_CP3
= (0x13 << 26),
62 OPC_SPECIAL2
= (0x1C << 26),
63 OPC_SPECIAL3
= (0x1F << 26),
64 /* arithmetic with immediate */
65 OPC_ADDI
= (0x08 << 26),
66 OPC_ADDIU
= (0x09 << 26),
67 OPC_SLTI
= (0x0A << 26),
68 OPC_SLTIU
= (0x0B << 26),
69 /* logic with immediate */
70 OPC_ANDI
= (0x0C << 26),
71 OPC_ORI
= (0x0D << 26),
72 OPC_XORI
= (0x0E << 26),
73 OPC_LUI
= (0x0F << 26),
74 /* arithmetic with immediate */
75 OPC_DADDI
= (0x18 << 26),
76 OPC_DADDIU
= (0x19 << 26),
77 /* Jump and branches */
79 OPC_JAL
= (0x03 << 26),
80 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
81 OPC_BEQL
= (0x14 << 26),
82 OPC_BNE
= (0x05 << 26),
83 OPC_BNEL
= (0x15 << 26),
84 OPC_BLEZ
= (0x06 << 26),
85 OPC_BLEZL
= (0x16 << 26),
86 OPC_BGTZ
= (0x07 << 26),
87 OPC_BGTZL
= (0x17 << 26),
88 OPC_JALX
= (0x1D << 26),
89 OPC_DAUI
= (0x1D << 26),
91 OPC_LDL
= (0x1A << 26),
92 OPC_LDR
= (0x1B << 26),
93 OPC_LB
= (0x20 << 26),
94 OPC_LH
= (0x21 << 26),
95 OPC_LWL
= (0x22 << 26),
96 OPC_LW
= (0x23 << 26),
97 OPC_LWPC
= OPC_LW
| 0x5,
98 OPC_LBU
= (0x24 << 26),
99 OPC_LHU
= (0x25 << 26),
100 OPC_LWR
= (0x26 << 26),
101 OPC_LWU
= (0x27 << 26),
102 OPC_SB
= (0x28 << 26),
103 OPC_SH
= (0x29 << 26),
104 OPC_SWL
= (0x2A << 26),
105 OPC_SW
= (0x2B << 26),
106 OPC_SDL
= (0x2C << 26),
107 OPC_SDR
= (0x2D << 26),
108 OPC_SWR
= (0x2E << 26),
109 OPC_LL
= (0x30 << 26),
110 OPC_LLD
= (0x34 << 26),
111 OPC_LD
= (0x37 << 26),
112 OPC_LDPC
= OPC_LD
| 0x5,
113 OPC_SC
= (0x38 << 26),
114 OPC_SCD
= (0x3C << 26),
115 OPC_SD
= (0x3F << 26),
116 /* Floating point load/store */
117 OPC_LWC1
= (0x31 << 26),
118 OPC_LWC2
= (0x32 << 26),
119 OPC_LDC1
= (0x35 << 26),
120 OPC_LDC2
= (0x36 << 26),
121 OPC_SWC1
= (0x39 << 26),
122 OPC_SWC2
= (0x3A << 26),
123 OPC_SDC1
= (0x3D << 26),
124 OPC_SDC2
= (0x3E << 26),
125 /* Compact Branches */
126 OPC_BLEZALC
= (0x06 << 26),
127 OPC_BGEZALC
= (0x06 << 26),
128 OPC_BGEUC
= (0x06 << 26),
129 OPC_BGTZALC
= (0x07 << 26),
130 OPC_BLTZALC
= (0x07 << 26),
131 OPC_BLTUC
= (0x07 << 26),
132 OPC_BOVC
= (0x08 << 26),
133 OPC_BEQZALC
= (0x08 << 26),
134 OPC_BEQC
= (0x08 << 26),
135 OPC_BLEZC
= (0x16 << 26),
136 OPC_BGEZC
= (0x16 << 26),
137 OPC_BGEC
= (0x16 << 26),
138 OPC_BGTZC
= (0x17 << 26),
139 OPC_BLTZC
= (0x17 << 26),
140 OPC_BLTC
= (0x17 << 26),
141 OPC_BNVC
= (0x18 << 26),
142 OPC_BNEZALC
= (0x18 << 26),
143 OPC_BNEC
= (0x18 << 26),
144 OPC_BC
= (0x32 << 26),
145 OPC_BEQZC
= (0x36 << 26),
146 OPC_JIC
= (0x36 << 26),
147 OPC_BALC
= (0x3A << 26),
148 OPC_BNEZC
= (0x3E << 26),
149 OPC_JIALC
= (0x3E << 26),
150 /* MDMX ASE specific */
151 OPC_MDMX
= (0x1E << 26),
152 /* Cache and prefetch */
153 OPC_CACHE
= (0x2F << 26),
154 OPC_PREF
= (0x33 << 26),
155 /* PC-relative address computation / loads */
156 OPC_PCREL
= (0x3B << 26),
159 /* PC-relative address computation / loads */
160 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
161 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
163 /* Instructions determined by bits 19 and 20 */
164 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
165 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
166 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
168 /* Instructions determined by bits 16 ... 20 */
169 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
170 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
173 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
176 /* MIPS special opcodes */
177 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
181 OPC_SLL
= 0x00 | OPC_SPECIAL
,
182 /* NOP is SLL r0, r0, 0 */
183 /* SSNOP is SLL r0, r0, 1 */
184 /* EHB is SLL r0, r0, 3 */
185 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
186 OPC_ROTR
= OPC_SRL
| (1 << 21),
187 OPC_SRA
= 0x03 | OPC_SPECIAL
,
188 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
189 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
190 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
191 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
192 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
193 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
194 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
195 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
196 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
197 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
198 OPC_DROTR
= OPC_DSRL
| (1 << 21),
199 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
200 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
201 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
202 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
203 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
204 /* Multiplication / division */
205 OPC_MULT
= 0x18 | OPC_SPECIAL
,
206 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
207 OPC_DIV
= 0x1A | OPC_SPECIAL
,
208 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
209 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
210 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
211 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
212 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
214 /* 2 registers arithmetic / logic */
215 OPC_ADD
= 0x20 | OPC_SPECIAL
,
216 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
217 OPC_SUB
= 0x22 | OPC_SPECIAL
,
218 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
219 OPC_AND
= 0x24 | OPC_SPECIAL
,
220 OPC_OR
= 0x25 | OPC_SPECIAL
,
221 OPC_XOR
= 0x26 | OPC_SPECIAL
,
222 OPC_NOR
= 0x27 | OPC_SPECIAL
,
223 OPC_SLT
= 0x2A | OPC_SPECIAL
,
224 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
225 OPC_DADD
= 0x2C | OPC_SPECIAL
,
226 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
227 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
228 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
230 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
231 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
233 OPC_TGE
= 0x30 | OPC_SPECIAL
,
234 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
235 OPC_TLT
= 0x32 | OPC_SPECIAL
,
236 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
237 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
238 OPC_TNE
= 0x36 | OPC_SPECIAL
,
239 /* HI / LO registers load & stores */
240 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
241 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
242 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
243 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
244 /* Conditional moves */
245 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
246 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
248 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
249 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
251 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
254 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
255 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
256 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
257 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
258 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
260 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
261 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
262 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
263 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
267 * R6 Multiply and Divide instructions have the same opcode
268 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
270 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
273 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
274 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
275 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
276 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
277 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
278 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
279 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
280 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
282 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
283 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
284 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
285 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
286 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
287 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
288 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
289 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
291 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
292 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
293 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
294 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
295 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
298 /* Multiplication variants of the vr54xx. */
299 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
302 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
303 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
304 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
305 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
306 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
307 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
308 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
309 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
310 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
311 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
312 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
313 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
314 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
315 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
318 /* REGIMM (rt field) opcodes */
319 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
322 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
323 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
324 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
325 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
326 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
327 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
328 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
329 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
330 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
331 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
332 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
333 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
334 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
335 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
336 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
337 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
339 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
340 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
343 /* Special2 opcodes */
344 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
347 /* Multiply & xxx operations */
348 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
349 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
350 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
351 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
352 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
354 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
355 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
356 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
357 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
358 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
359 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
360 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
361 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
362 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
363 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
364 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
365 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
367 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
368 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
369 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
370 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
372 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
375 /* Special3 opcodes */
376 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
379 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
380 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
381 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
382 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
383 OPC_INS
= 0x04 | OPC_SPECIAL3
,
384 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
385 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
386 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
387 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
388 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
389 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
390 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
391 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
392 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
395 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
396 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
397 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
398 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
399 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
400 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
401 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
402 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
403 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
404 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
405 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
406 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
409 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
410 /* MIPS DSP Arithmetic */
411 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
412 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
413 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
414 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
415 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
416 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
417 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
418 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
419 /* MIPS DSP GPR-Based Shift Sub-class */
420 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
421 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
422 /* MIPS DSP Multiply Sub-class insns */
423 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
424 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
425 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
426 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
427 /* DSP Bit/Manipulation Sub-class */
428 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
429 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
430 /* MIPS DSP Append Sub-class */
431 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
432 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
433 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
434 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
435 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
438 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
439 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
440 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
441 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
442 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
443 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
444 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
445 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
446 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
447 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
448 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
449 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
450 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
451 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
452 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
453 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
456 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
457 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
458 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
459 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
460 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
461 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
464 /* Loongson EXT load/store quad word opcodes */
465 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
467 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
468 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
469 OPC_GSSHFL
= OPC_LWC2
,
470 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
471 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
472 OPC_GSSHFS
= OPC_SWC2
,
475 /* Loongson EXT shifted load/store opcodes */
476 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
478 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
479 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
480 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
481 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
482 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
483 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
484 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
485 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
488 /* Loongson EXT LDC2/SDC2 opcodes */
489 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
492 OPC_GSLBX
= 0x0 | OPC_LDC2
,
493 OPC_GSLHX
= 0x1 | OPC_LDC2
,
494 OPC_GSLWX
= 0x2 | OPC_LDC2
,
495 OPC_GSLDX
= 0x3 | OPC_LDC2
,
496 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
497 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
498 OPC_GSSBX
= 0x0 | OPC_SDC2
,
499 OPC_GSSHX
= 0x1 | OPC_SDC2
,
500 OPC_GSSWX
= 0x2 | OPC_SDC2
,
501 OPC_GSSDX
= 0x3 | OPC_SDC2
,
502 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
503 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
507 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
510 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
511 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
512 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
513 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
514 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
515 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
516 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
517 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
521 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
524 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
525 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
526 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
527 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
528 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
529 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
530 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
531 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
532 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
533 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
534 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
537 /* MIPS DSP REGIMM opcodes */
539 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
540 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
543 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
547 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
548 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
549 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
552 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Arithmetic Sub-class */
555 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
556 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
557 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
560 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
561 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
562 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
563 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
564 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
565 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
566 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
567 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
568 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
569 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
570 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
571 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
572 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
573 /* MIPS DSP Multiply Sub-class insns */
574 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
575 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
576 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
577 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
578 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
579 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
582 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
583 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
585 /* MIPS DSP Arithmetic Sub-class */
586 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
590 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
591 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
592 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
593 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
594 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
595 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
596 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
597 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
598 /* MIPS DSP Multiply Sub-class insns */
599 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
600 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
601 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
602 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
605 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
607 /* MIPS DSP Arithmetic Sub-class */
608 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
609 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
613 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
614 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
615 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
616 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
617 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
618 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
619 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
620 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
621 /* DSP Bit/Manipulation Sub-class */
622 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
623 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
624 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
625 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
626 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
629 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
631 /* MIPS DSP Arithmetic Sub-class */
632 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
639 /* DSP Compare-Pick Sub-class */
640 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
642 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
643 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
644 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
645 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
646 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
647 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
648 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
649 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
650 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
651 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
652 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
653 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
654 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
657 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
659 /* MIPS DSP GPR-Based Shift Sub-class */
660 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
669 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
670 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
671 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
672 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
673 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
674 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
675 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
676 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
677 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
678 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
679 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
680 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
681 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
684 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
686 /* MIPS DSP Multiply Sub-class insns */
687 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
696 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
697 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
698 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
699 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
700 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
701 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
702 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
703 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
704 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
705 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
706 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
707 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
708 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
711 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
713 /* DSP Bit/Manipulation Sub-class */
714 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
717 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
719 /* MIPS DSP Append Sub-class */
720 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
721 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
722 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
725 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
727 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
728 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
729 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
730 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
731 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
732 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
733 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
734 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
735 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
736 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
737 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
738 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
739 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
740 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
741 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
742 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
743 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
744 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
747 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
749 /* MIPS DSP Arithmetic Sub-class */
750 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
754 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
755 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
759 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
761 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
762 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
763 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
764 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
765 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
766 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
767 /* DSP Bit/Manipulation Sub-class */
768 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
769 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
770 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
771 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
772 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
773 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
776 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
778 /* MIPS DSP Multiply Sub-class insns */
779 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
780 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
781 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
783 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
784 /* MIPS DSP Arithmetic Sub-class */
785 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
786 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
787 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
788 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
789 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
790 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
791 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
793 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
794 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
795 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
796 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
797 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
798 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
799 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
800 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
801 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
802 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
803 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
804 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
805 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
808 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
810 /* DSP Compare-Pick Sub-class */
811 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
817 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
818 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
822 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
826 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
827 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
828 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
829 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
830 /* MIPS DSP Arithmetic Sub-class */
831 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
832 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
833 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
834 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
835 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
836 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
837 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
838 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
841 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
843 /* DSP Append Sub-class */
844 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
845 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
846 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
847 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
850 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
852 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
853 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
861 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
862 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
863 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
864 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
865 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
866 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
867 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
868 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
869 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
870 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
871 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
872 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
873 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
876 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
878 /* DSP Bit/Manipulation Sub-class */
879 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
882 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
884 /* MIPS DSP Multiply Sub-class insns */
885 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
898 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
899 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
900 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
901 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
902 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
903 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
904 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
905 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
906 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
907 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
908 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
909 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
910 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
913 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
915 /* MIPS DSP GPR-Based Shift Sub-class */
916 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
929 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
930 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
931 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
932 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
933 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
934 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
935 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
936 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
937 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
938 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
939 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
940 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
941 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
944 /* Coprocessor 0 (rs field) */
945 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
948 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
949 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
950 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
951 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
952 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
953 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
954 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
955 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
956 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
957 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
958 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
959 OPC_C0
= (0x10 << 21) | OPC_CP0
,
960 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
961 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
962 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
963 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
964 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
965 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
966 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
967 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
968 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
969 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
970 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
971 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
972 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
973 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
974 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
978 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
981 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
982 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
983 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
984 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
985 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
986 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
987 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
988 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
991 /* Coprocessor 0 (with rs == C0) */
992 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
995 OPC_TLBR
= 0x01 | OPC_C0
,
996 OPC_TLBWI
= 0x02 | OPC_C0
,
997 OPC_TLBINV
= 0x03 | OPC_C0
,
998 OPC_TLBINVF
= 0x04 | OPC_C0
,
999 OPC_TLBWR
= 0x06 | OPC_C0
,
1000 OPC_TLBP
= 0x08 | OPC_C0
,
1001 OPC_RFE
= 0x10 | OPC_C0
,
1002 OPC_ERET
= 0x18 | OPC_C0
,
1003 OPC_DERET
= 0x1F | OPC_C0
,
1004 OPC_WAIT
= 0x20 | OPC_C0
,
1007 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1010 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1011 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1012 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1013 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1014 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1015 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1016 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1017 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1018 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1019 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1020 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1023 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1026 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1027 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1028 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1029 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1030 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1031 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1032 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1033 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1035 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1036 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1037 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1038 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1039 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1040 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1041 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1042 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1044 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1045 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1046 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1047 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1048 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1049 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1050 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1051 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1053 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1054 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1055 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1056 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1057 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1058 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1059 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1060 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1062 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1063 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1064 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1065 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1066 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1067 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1069 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1070 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1071 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1072 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1073 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1074 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1076 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1077 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1078 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1079 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1080 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1081 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1083 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1084 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1085 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1086 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1087 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1088 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1090 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1091 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1092 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1093 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1094 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1095 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1097 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1098 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1099 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1100 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1101 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1102 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1104 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1105 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1106 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1107 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1108 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1109 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1111 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1112 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1113 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1114 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1115 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1116 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1120 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1123 OPC_LWXC1
= 0x00 | OPC_CP3
,
1124 OPC_LDXC1
= 0x01 | OPC_CP3
,
1125 OPC_LUXC1
= 0x05 | OPC_CP3
,
1126 OPC_SWXC1
= 0x08 | OPC_CP3
,
1127 OPC_SDXC1
= 0x09 | OPC_CP3
,
1128 OPC_SUXC1
= 0x0D | OPC_CP3
,
1129 OPC_PREFX
= 0x0F | OPC_CP3
,
1130 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1131 OPC_MADD_S
= 0x20 | OPC_CP3
,
1132 OPC_MADD_D
= 0x21 | OPC_CP3
,
1133 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1134 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1135 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1136 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1137 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1138 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1139 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1140 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1141 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1142 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1146 * MMI (MultiMedia Instruction) encodings
1147 * ======================================
1149 * MMI instructions encoding table keys:
1151 * * This code is reserved for future use. An attempt to execute it
1152 * causes a Reserved Instruction exception.
1153 * % This code indicates an instruction class. The instruction word
1154 * must be further decoded by examining additional tables that show
1155 * the values for other instruction fields.
1156 * # This code is reserved for the unsupported instructions DMULT,
1157 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1158 * to execute it causes a Reserved Instruction exception.
1160 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1163 * +--------+----------------------------------------+
1165 * +--------+----------------------------------------+
1167 * opcode bits 28..26
1168 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1169 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1170 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1171 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1172 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1173 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1174 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1175 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1176 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1177 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1178 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1182 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1183 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1184 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1188 * MMI instructions with opcode field = MMI:
1191 * +--------+-------------------------------+--------+
1192 * | MMI | |function|
1193 * +--------+-------------------------------+--------+
1195 * function bits 2..0
1196 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1197 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1198 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1199 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1200 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1201 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1202 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1203 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1204 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1205 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1206 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1209 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1211 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1212 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1213 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1214 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1215 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1216 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1217 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1218 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1221 /* global register indices */
1222 TCGv cpu_gpr
[32], cpu_PC
;
1224 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1225 * and the upper halves in cpu_gpr_hi[].
1227 TCGv_i64 cpu_gpr_hi
[32];
1228 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1229 static TCGv cpu_dspctrl
, btarget
;
1231 static TCGv cpu_lladdr
, cpu_llval
;
1232 static TCGv_i32 hflags
;
1233 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1234 TCGv_i64 fpu_f64
[32];
1236 #include "exec/gen-icount.h"
1238 #define gen_helper_0e0i(name, arg) do { \
1239 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1240 gen_helper_##name(cpu_env, helper_tmp); \
1241 tcg_temp_free_i32(helper_tmp); \
1244 #define gen_helper_0e1i(name, arg1, arg2) do { \
1245 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1246 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1247 tcg_temp_free_i32(helper_tmp); \
1250 #define gen_helper_1e0i(name, ret, arg1) do { \
1251 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1252 gen_helper_##name(ret, cpu_env, helper_tmp); \
1253 tcg_temp_free_i32(helper_tmp); \
1256 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1257 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1258 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1259 tcg_temp_free_i32(helper_tmp); \
1262 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1263 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1264 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1265 tcg_temp_free_i32(helper_tmp); \
1268 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1269 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1270 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1271 tcg_temp_free_i32(helper_tmp); \
1274 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1275 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1276 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1277 tcg_temp_free_i32(helper_tmp); \
1280 #define DISAS_STOP DISAS_TARGET_0
1281 #define DISAS_EXIT DISAS_TARGET_1
1283 static const char regnames_HI
[][4] = {
1284 "HI0", "HI1", "HI2", "HI3",
1287 static const char regnames_LO
[][4] = {
1288 "LO0", "LO1", "LO2", "LO3",
1291 /* General purpose registers moves. */
1292 void gen_load_gpr(TCGv t
, int reg
)
1295 tcg_gen_movi_tl(t
, 0);
1297 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1301 void gen_store_gpr(TCGv t
, int reg
)
1304 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1308 #if defined(TARGET_MIPS64)
1309 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
1312 tcg_gen_movi_i64(t
, 0);
1314 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
1318 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
1321 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
1324 #endif /* TARGET_MIPS64 */
1326 /* Moves to/from shadow registers. */
1327 static inline void gen_load_srsgpr(int from
, int to
)
1329 TCGv t0
= tcg_temp_new();
1332 tcg_gen_movi_tl(t0
, 0);
1334 TCGv_i32 t2
= tcg_temp_new_i32();
1335 TCGv_ptr addr
= tcg_temp_new_ptr();
1337 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1338 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1339 tcg_gen_andi_i32(t2
, t2
, 0xf);
1340 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1341 tcg_gen_ext_i32_ptr(addr
, t2
);
1342 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1344 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1345 tcg_temp_free_ptr(addr
);
1346 tcg_temp_free_i32(t2
);
1348 gen_store_gpr(t0
, to
);
1352 static inline void gen_store_srsgpr(int from
, int to
)
1355 TCGv t0
= tcg_temp_new();
1356 TCGv_i32 t2
= tcg_temp_new_i32();
1357 TCGv_ptr addr
= tcg_temp_new_ptr();
1359 gen_load_gpr(t0
, from
);
1360 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1361 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1362 tcg_gen_andi_i32(t2
, t2
, 0xf);
1363 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1364 tcg_gen_ext_i32_ptr(addr
, t2
);
1365 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1367 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1368 tcg_temp_free_ptr(addr
);
1369 tcg_temp_free_i32(t2
);
1375 static inline void gen_save_pc(target_ulong pc
)
1377 tcg_gen_movi_tl(cpu_PC
, pc
);
1380 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1382 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1383 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
1384 gen_save_pc(ctx
->base
.pc_next
);
1385 ctx
->saved_pc
= ctx
->base
.pc_next
;
1387 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1388 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1389 ctx
->saved_hflags
= ctx
->hflags
;
1390 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1396 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1402 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1404 ctx
->saved_hflags
= ctx
->hflags
;
1405 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1411 ctx
->btarget
= env
->btarget
;
1416 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1418 TCGv_i32 texcp
= tcg_const_i32(excp
);
1419 TCGv_i32 terr
= tcg_const_i32(err
);
1420 save_cpu_state(ctx
, 1);
1421 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1422 tcg_temp_free_i32(terr
);
1423 tcg_temp_free_i32(texcp
);
1424 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1427 void generate_exception(DisasContext
*ctx
, int excp
)
1429 gen_helper_0e0i(raise_exception
, excp
);
1432 void generate_exception_end(DisasContext
*ctx
, int excp
)
1434 generate_exception_err(ctx
, excp
, 0);
1437 void gen_reserved_instruction(DisasContext
*ctx
)
1439 generate_exception_end(ctx
, EXCP_RI
);
1442 /* Floating point register moves. */
1443 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1445 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1446 generate_exception(ctx
, EXCP_RI
);
1448 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1451 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1454 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1455 generate_exception(ctx
, EXCP_RI
);
1457 t64
= tcg_temp_new_i64();
1458 tcg_gen_extu_i32_i64(t64
, t
);
1459 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1460 tcg_temp_free_i64(t64
);
1463 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1465 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1466 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1468 gen_load_fpr32(ctx
, t
, reg
| 1);
1472 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1474 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1475 TCGv_i64 t64
= tcg_temp_new_i64();
1476 tcg_gen_extu_i32_i64(t64
, t
);
1477 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1478 tcg_temp_free_i64(t64
);
1480 gen_store_fpr32(ctx
, t
, reg
| 1);
1484 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1486 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1487 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1489 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1493 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1495 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1496 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1499 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1500 t0
= tcg_temp_new_i64();
1501 tcg_gen_shri_i64(t0
, t
, 32);
1502 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1503 tcg_temp_free_i64(t0
);
1507 int get_fp_bit(int cc
)
1516 /* Addresses computation */
1517 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1519 tcg_gen_add_tl(ret
, arg0
, arg1
);
1521 #if defined(TARGET_MIPS64)
1522 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1523 tcg_gen_ext32s_i64(ret
, ret
);
1528 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
1531 tcg_gen_addi_tl(ret
, base
, ofs
);
1533 #if defined(TARGET_MIPS64)
1534 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1535 tcg_gen_ext32s_i64(ret
, ret
);
1540 /* Addresses computation (translation time) */
1541 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1544 target_long sum
= base
+ offset
;
1546 #if defined(TARGET_MIPS64)
1547 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1554 /* Sign-extract the low 32-bits to a target_long. */
1555 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1557 #if defined(TARGET_MIPS64)
1558 tcg_gen_ext32s_i64(ret
, arg
);
1560 tcg_gen_extrl_i64_i32(ret
, arg
);
1564 /* Sign-extract the high 32-bits to a target_long. */
1565 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1567 #if defined(TARGET_MIPS64)
1568 tcg_gen_sari_i64(ret
, arg
, 32);
1570 tcg_gen_extrh_i64_i32(ret
, arg
);
1574 bool check_cp0_enabled(DisasContext
*ctx
)
1576 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1577 generate_exception_end(ctx
, EXCP_CpU
);
1583 void check_cp1_enabled(DisasContext
*ctx
)
1585 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
1586 generate_exception_err(ctx
, EXCP_CpU
, 1);
1591 * Verify that the processor is running with COP1X instructions enabled.
1592 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1595 void check_cop1x(DisasContext
*ctx
)
1597 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
1598 gen_reserved_instruction(ctx
);
1603 * Verify that the processor is running with 64-bit floating-point
1604 * operations enabled.
1606 void check_cp1_64bitmode(DisasContext
*ctx
)
1608 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
1609 gen_reserved_instruction(ctx
);
1614 * Verify if floating point register is valid; an operation is not defined
1615 * if bit 0 of any register specification is set and the FR bit in the
1616 * Status register equals zero, since the register numbers specify an
1617 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1618 * in the Status register equals one, both even and odd register numbers
1619 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1621 * Multiple 64 bit wide registers can be checked by calling
1622 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1624 void check_cp1_registers(DisasContext
*ctx
, int regs
)
1626 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
1627 gen_reserved_instruction(ctx
);
1632 * Verify that the processor is running with DSP instructions enabled.
1633 * This is enabled by CP0 Status register MX(24) bit.
1635 static inline void check_dsp(DisasContext
*ctx
)
1637 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1638 if (ctx
->insn_flags
& ASE_DSP
) {
1639 generate_exception_end(ctx
, EXCP_DSPDIS
);
1641 gen_reserved_instruction(ctx
);
1646 static inline void check_dsp_r2(DisasContext
*ctx
)
1648 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
1649 if (ctx
->insn_flags
& ASE_DSP
) {
1650 generate_exception_end(ctx
, EXCP_DSPDIS
);
1652 gen_reserved_instruction(ctx
);
1657 static inline void check_dsp_r3(DisasContext
*ctx
)
1659 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
1660 if (ctx
->insn_flags
& ASE_DSP
) {
1661 generate_exception_end(ctx
, EXCP_DSPDIS
);
1663 gen_reserved_instruction(ctx
);
1669 * This code generates a "reserved instruction" exception if the
1670 * CPU does not support the instruction set corresponding to flags.
1672 void check_insn(DisasContext
*ctx
, uint64_t flags
)
1674 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1675 gen_reserved_instruction(ctx
);
1680 * This code generates a "reserved instruction" exception if the
1681 * CPU has corresponding flag set which indicates that the instruction
1684 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
1686 if (unlikely(ctx
->insn_flags
& flags
)) {
1687 gen_reserved_instruction(ctx
);
1692 * The Linux kernel traps certain reserved instruction exceptions to
1693 * emulate the corresponding instructions. QEMU is the kernel in user
1694 * mode, so those traps are emulated by accepting the instructions.
1696 * A reserved instruction exception is generated for flagged CPUs if
1697 * QEMU runs in system mode.
1699 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
1701 #ifndef CONFIG_USER_ONLY
1702 check_insn_opc_removed(ctx
, flags
);
1707 * This code generates a "reserved instruction" exception if the
1708 * CPU does not support 64-bit paired-single (PS) floating point data type.
1710 static inline void check_ps(DisasContext
*ctx
)
1712 if (unlikely(!ctx
->ps
)) {
1713 generate_exception(ctx
, EXCP_RI
);
1715 check_cp1_64bitmode(ctx
);
1719 * This code generates a "reserved instruction" exception if cpu is not
1720 * 64-bit or 64-bit instructions are not enabled.
1722 void check_mips_64(DisasContext
*ctx
)
1724 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
1725 gen_reserved_instruction(ctx
);
1729 #ifndef CONFIG_USER_ONLY
1730 static inline void check_mvh(DisasContext
*ctx
)
1732 if (unlikely(!ctx
->mvh
)) {
1733 generate_exception(ctx
, EXCP_RI
);
1739 * This code generates a "reserved instruction" exception if the
1740 * Config5 XNP bit is set.
1742 static inline void check_xnp(DisasContext
*ctx
)
1744 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
1745 gen_reserved_instruction(ctx
);
1749 #ifndef CONFIG_USER_ONLY
1751 * This code generates a "reserved instruction" exception if the
1752 * Config3 PW bit is NOT set.
1754 static inline void check_pw(DisasContext
*ctx
)
1756 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
1757 gen_reserved_instruction(ctx
);
1763 * This code generates a "reserved instruction" exception if the
1764 * Config3 MT bit is NOT set.
1766 static inline void check_mt(DisasContext
*ctx
)
1768 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1769 gen_reserved_instruction(ctx
);
1773 #ifndef CONFIG_USER_ONLY
1775 * This code generates a "coprocessor unusable" exception if CP0 is not
1776 * available, and, if that is not the case, generates a "reserved instruction"
1777 * exception if the Config5 MT bit is NOT set. This is needed for availability
1778 * control of some of MT ASE instructions.
1780 static inline void check_cp0_mt(DisasContext
*ctx
)
1782 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1783 generate_exception_end(ctx
, EXCP_CpU
);
1785 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1786 gen_reserved_instruction(ctx
);
1793 * This code generates a "reserved instruction" exception if the
1794 * Config5 NMS bit is set.
1796 static inline void check_nms(DisasContext
*ctx
)
1798 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
1799 gen_reserved_instruction(ctx
);
1804 * This code generates a "reserved instruction" exception if the
1805 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1806 * Config2 TL, and Config5 L2C are unset.
1808 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
1810 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
1811 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
1812 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
1813 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
1814 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
1815 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
1816 gen_reserved_instruction(ctx
);
1821 * This code generates a "reserved instruction" exception if the
1822 * Config5 EVA bit is NOT set.
1824 static inline void check_eva(DisasContext
*ctx
)
1826 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
1827 gen_reserved_instruction(ctx
);
1833 * Define small wrappers for gen_load_fpr* so that we have a uniform
1834 * calling interface for 32 and 64-bit FPRs. No sense in changing
1835 * all callers for gen_load_fpr32 when we need the CTX parameter for
1838 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1839 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1840 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1841 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1842 int ft, int fs, int cc) \
1844 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1845 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1854 check_cp1_registers(ctx, fs | ft); \
1862 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1863 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1866 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1869 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1872 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1875 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1878 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1881 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1884 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1887 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1890 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1893 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1896 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1899 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1902 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1905 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1908 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1911 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1916 tcg_temp_free_i##bits(fp0); \
1917 tcg_temp_free_i##bits(fp1); \
1920 FOP_CONDS(, 0, d
, FMT_D
, 64)
1921 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1922 FOP_CONDS(, 0, s
, FMT_S
, 32)
1923 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1924 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1925 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1928 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1929 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1930 int ft, int fs, int fd) \
1932 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1933 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1934 if (ifmt == FMT_D) { \
1935 check_cp1_registers(ctx, fs | ft | fd); \
1937 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1938 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1941 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1944 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1947 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1950 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1953 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1956 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1959 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1962 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1965 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1968 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1971 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1974 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1977 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1980 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1983 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1986 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1989 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1992 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1995 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1998 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2001 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2004 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2010 tcg_temp_free_i ## bits(fp0); \
2011 tcg_temp_free_i ## bits(fp1); \
2014 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2015 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2017 #undef gen_ldcmp_fpr32
2018 #undef gen_ldcmp_fpr64
2020 /* load/store instructions. */
2021 #ifdef CONFIG_USER_ONLY
2022 #define OP_LD_ATOMIC(insn, fname) \
2023 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2024 DisasContext *ctx) \
2026 TCGv t0 = tcg_temp_new(); \
2027 tcg_gen_mov_tl(t0, arg1); \
2028 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2029 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2030 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2031 tcg_temp_free(t0); \
2034 #define OP_LD_ATOMIC(insn, fname) \
2035 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2036 DisasContext *ctx) \
2038 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2041 OP_LD_ATOMIC(ll
, ld32s
);
2042 #if defined(TARGET_MIPS64)
2043 OP_LD_ATOMIC(lld
, ld64
);
2047 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2050 tcg_gen_movi_tl(addr
, offset
);
2051 } else if (offset
== 0) {
2052 gen_load_gpr(addr
, base
);
2054 tcg_gen_movi_tl(addr
, offset
);
2055 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2059 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2061 target_ulong pc
= ctx
->base
.pc_next
;
2063 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2064 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2069 pc
&= ~(target_ulong
)3;
2074 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2075 int rt
, int base
, int offset
)
2078 int mem_idx
= ctx
->mem_idx
;
2080 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2083 * Loongson CPU uses a load to zero register for prefetch.
2084 * We emulate it as a NOP. On other CPU we must perform the
2085 * actual memory access.
2090 t0
= tcg_temp_new();
2091 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2094 #if defined(TARGET_MIPS64)
2096 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2097 ctx
->default_tcg_memop_mask
);
2098 gen_store_gpr(t0
, rt
);
2101 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2102 ctx
->default_tcg_memop_mask
);
2103 gen_store_gpr(t0
, rt
);
2107 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2108 gen_store_gpr(t0
, rt
);
2111 t1
= tcg_temp_new();
2113 * Do a byte access to possibly trigger a page
2114 * fault with the unaligned address.
2116 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2117 tcg_gen_andi_tl(t1
, t0
, 7);
2118 #ifndef TARGET_WORDS_BIGENDIAN
2119 tcg_gen_xori_tl(t1
, t1
, 7);
2121 tcg_gen_shli_tl(t1
, t1
, 3);
2122 tcg_gen_andi_tl(t0
, t0
, ~7);
2123 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2124 tcg_gen_shl_tl(t0
, t0
, t1
);
2125 t2
= tcg_const_tl(-1);
2126 tcg_gen_shl_tl(t2
, t2
, t1
);
2127 gen_load_gpr(t1
, rt
);
2128 tcg_gen_andc_tl(t1
, t1
, t2
);
2130 tcg_gen_or_tl(t0
, t0
, t1
);
2132 gen_store_gpr(t0
, rt
);
2135 t1
= tcg_temp_new();
2137 * Do a byte access to possibly trigger a page
2138 * fault with the unaligned address.
2140 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2141 tcg_gen_andi_tl(t1
, t0
, 7);
2142 #ifdef TARGET_WORDS_BIGENDIAN
2143 tcg_gen_xori_tl(t1
, t1
, 7);
2145 tcg_gen_shli_tl(t1
, t1
, 3);
2146 tcg_gen_andi_tl(t0
, t0
, ~7);
2147 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2148 tcg_gen_shr_tl(t0
, t0
, t1
);
2149 tcg_gen_xori_tl(t1
, t1
, 63);
2150 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2151 tcg_gen_shl_tl(t2
, t2
, t1
);
2152 gen_load_gpr(t1
, rt
);
2153 tcg_gen_and_tl(t1
, t1
, t2
);
2155 tcg_gen_or_tl(t0
, t0
, t1
);
2157 gen_store_gpr(t0
, rt
);
2160 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2161 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2163 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2164 gen_store_gpr(t0
, rt
);
2168 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2169 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2171 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2172 gen_store_gpr(t0
, rt
);
2175 mem_idx
= MIPS_HFLAG_UM
;
2178 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2179 ctx
->default_tcg_memop_mask
);
2180 gen_store_gpr(t0
, rt
);
2183 mem_idx
= MIPS_HFLAG_UM
;
2186 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2187 ctx
->default_tcg_memop_mask
);
2188 gen_store_gpr(t0
, rt
);
2191 mem_idx
= MIPS_HFLAG_UM
;
2194 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2195 ctx
->default_tcg_memop_mask
);
2196 gen_store_gpr(t0
, rt
);
2199 mem_idx
= MIPS_HFLAG_UM
;
2202 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
2203 gen_store_gpr(t0
, rt
);
2206 mem_idx
= MIPS_HFLAG_UM
;
2209 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
2210 gen_store_gpr(t0
, rt
);
2213 mem_idx
= MIPS_HFLAG_UM
;
2216 t1
= tcg_temp_new();
2218 * Do a byte access to possibly trigger a page
2219 * fault with the unaligned address.
2221 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2222 tcg_gen_andi_tl(t1
, t0
, 3);
2223 #ifndef TARGET_WORDS_BIGENDIAN
2224 tcg_gen_xori_tl(t1
, t1
, 3);
2226 tcg_gen_shli_tl(t1
, t1
, 3);
2227 tcg_gen_andi_tl(t0
, t0
, ~3);
2228 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2229 tcg_gen_shl_tl(t0
, t0
, t1
);
2230 t2
= tcg_const_tl(-1);
2231 tcg_gen_shl_tl(t2
, t2
, t1
);
2232 gen_load_gpr(t1
, rt
);
2233 tcg_gen_andc_tl(t1
, t1
, t2
);
2235 tcg_gen_or_tl(t0
, t0
, t1
);
2237 tcg_gen_ext32s_tl(t0
, t0
);
2238 gen_store_gpr(t0
, rt
);
2241 mem_idx
= MIPS_HFLAG_UM
;
2244 t1
= tcg_temp_new();
2246 * Do a byte access to possibly trigger a page
2247 * fault with the unaligned address.
2249 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2250 tcg_gen_andi_tl(t1
, t0
, 3);
2251 #ifdef TARGET_WORDS_BIGENDIAN
2252 tcg_gen_xori_tl(t1
, t1
, 3);
2254 tcg_gen_shli_tl(t1
, t1
, 3);
2255 tcg_gen_andi_tl(t0
, t0
, ~3);
2256 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2257 tcg_gen_shr_tl(t0
, t0
, t1
);
2258 tcg_gen_xori_tl(t1
, t1
, 31);
2259 t2
= tcg_const_tl(0xfffffffeull
);
2260 tcg_gen_shl_tl(t2
, t2
, t1
);
2261 gen_load_gpr(t1
, rt
);
2262 tcg_gen_and_tl(t1
, t1
, t2
);
2264 tcg_gen_or_tl(t0
, t0
, t1
);
2266 tcg_gen_ext32s_tl(t0
, t0
);
2267 gen_store_gpr(t0
, rt
);
2270 mem_idx
= MIPS_HFLAG_UM
;
2274 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
2275 gen_store_gpr(t0
, rt
);
2281 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2282 uint32_t reg1
, uint32_t reg2
)
2284 TCGv taddr
= tcg_temp_new();
2285 TCGv_i64 tval
= tcg_temp_new_i64();
2286 TCGv tmp1
= tcg_temp_new();
2287 TCGv tmp2
= tcg_temp_new();
2289 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2290 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
2291 #ifdef TARGET_WORDS_BIGENDIAN
2292 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
2294 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
2296 gen_store_gpr(tmp1
, reg1
);
2297 tcg_temp_free(tmp1
);
2298 gen_store_gpr(tmp2
, reg2
);
2299 tcg_temp_free(tmp2
);
2300 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2301 tcg_temp_free_i64(tval
);
2302 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2303 tcg_temp_free(taddr
);
2307 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
2308 int base
, int offset
)
2310 TCGv t0
= tcg_temp_new();
2311 TCGv t1
= tcg_temp_new();
2312 int mem_idx
= ctx
->mem_idx
;
2314 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2315 gen_load_gpr(t1
, rt
);
2317 #if defined(TARGET_MIPS64)
2319 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
2320 ctx
->default_tcg_memop_mask
);
2323 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
2326 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
2330 mem_idx
= MIPS_HFLAG_UM
;
2333 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
2334 ctx
->default_tcg_memop_mask
);
2337 mem_idx
= MIPS_HFLAG_UM
;
2340 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
2341 ctx
->default_tcg_memop_mask
);
2344 mem_idx
= MIPS_HFLAG_UM
;
2347 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
2350 mem_idx
= MIPS_HFLAG_UM
;
2353 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
2356 mem_idx
= MIPS_HFLAG_UM
;
2359 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
2367 /* Store conditional */
2368 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
2369 MemOp tcg_mo
, bool eva
)
2372 TCGLabel
*l1
= gen_new_label();
2373 TCGLabel
*done
= gen_new_label();
2375 t0
= tcg_temp_new();
2376 addr
= tcg_temp_new();
2377 /* compare the address against that of the preceding LL */
2378 gen_base_offset_addr(ctx
, addr
, base
, offset
);
2379 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
2380 tcg_temp_free(addr
);
2381 tcg_gen_movi_tl(t0
, 0);
2382 gen_store_gpr(t0
, rt
);
2386 /* generate cmpxchg */
2387 val
= tcg_temp_new();
2388 gen_load_gpr(val
, rt
);
2389 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
2390 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
2391 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
2392 gen_store_gpr(t0
, rt
);
2395 gen_set_label(done
);
2400 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2401 uint32_t reg1
, uint32_t reg2
, bool eva
)
2403 TCGv taddr
= tcg_temp_local_new();
2404 TCGv lladdr
= tcg_temp_local_new();
2405 TCGv_i64 tval
= tcg_temp_new_i64();
2406 TCGv_i64 llval
= tcg_temp_new_i64();
2407 TCGv_i64 val
= tcg_temp_new_i64();
2408 TCGv tmp1
= tcg_temp_new();
2409 TCGv tmp2
= tcg_temp_new();
2410 TCGLabel
*lab_fail
= gen_new_label();
2411 TCGLabel
*lab_done
= gen_new_label();
2413 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2415 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2416 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
2418 gen_load_gpr(tmp1
, reg1
);
2419 gen_load_gpr(tmp2
, reg2
);
2421 #ifdef TARGET_WORDS_BIGENDIAN
2422 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
2424 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
2427 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2428 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
2429 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
2431 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
2433 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
2435 gen_set_label(lab_fail
);
2438 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
2440 gen_set_label(lab_done
);
2441 tcg_gen_movi_tl(lladdr
, -1);
2442 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2445 /* Load and store */
2446 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
2450 * Don't do NOP if destination is zero: we must perform the actual
2456 TCGv_i32 fp0
= tcg_temp_new_i32();
2457 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2458 ctx
->default_tcg_memop_mask
);
2459 gen_store_fpr32(ctx
, fp0
, ft
);
2460 tcg_temp_free_i32(fp0
);
2465 TCGv_i32 fp0
= tcg_temp_new_i32();
2466 gen_load_fpr32(ctx
, fp0
, ft
);
2467 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2468 ctx
->default_tcg_memop_mask
);
2469 tcg_temp_free_i32(fp0
);
2474 TCGv_i64 fp0
= tcg_temp_new_i64();
2475 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2476 ctx
->default_tcg_memop_mask
);
2477 gen_store_fpr64(ctx
, fp0
, ft
);
2478 tcg_temp_free_i64(fp0
);
2483 TCGv_i64 fp0
= tcg_temp_new_i64();
2484 gen_load_fpr64(ctx
, fp0
, ft
);
2485 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2486 ctx
->default_tcg_memop_mask
);
2487 tcg_temp_free_i64(fp0
);
2491 MIPS_INVAL("flt_ldst");
2492 gen_reserved_instruction(ctx
);
2497 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2498 int rs
, int16_t imm
)
2500 TCGv t0
= tcg_temp_new();
2502 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2503 check_cp1_enabled(ctx
);
2507 check_insn(ctx
, ISA_MIPS2
);
2510 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
2511 gen_flt_ldst(ctx
, op
, rt
, t0
);
2514 generate_exception_err(ctx
, EXCP_CpU
, 1);
2519 /* Arithmetic with immediate operand */
2520 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2521 int rt
, int rs
, int imm
)
2523 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2525 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2527 * If no destination, treat it as a NOP.
2528 * For addi, we must generate the overflow exception when needed.
2535 TCGv t0
= tcg_temp_local_new();
2536 TCGv t1
= tcg_temp_new();
2537 TCGv t2
= tcg_temp_new();
2538 TCGLabel
*l1
= gen_new_label();
2540 gen_load_gpr(t1
, rs
);
2541 tcg_gen_addi_tl(t0
, t1
, uimm
);
2542 tcg_gen_ext32s_tl(t0
, t0
);
2544 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2545 tcg_gen_xori_tl(t2
, t0
, uimm
);
2546 tcg_gen_and_tl(t1
, t1
, t2
);
2548 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2550 /* operands of same sign, result different sign */
2551 generate_exception(ctx
, EXCP_OVERFLOW
);
2553 tcg_gen_ext32s_tl(t0
, t0
);
2554 gen_store_gpr(t0
, rt
);
2560 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2561 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2563 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2566 #if defined(TARGET_MIPS64)
2569 TCGv t0
= tcg_temp_local_new();
2570 TCGv t1
= tcg_temp_new();
2571 TCGv t2
= tcg_temp_new();
2572 TCGLabel
*l1
= gen_new_label();
2574 gen_load_gpr(t1
, rs
);
2575 tcg_gen_addi_tl(t0
, t1
, uimm
);
2577 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2578 tcg_gen_xori_tl(t2
, t0
, uimm
);
2579 tcg_gen_and_tl(t1
, t1
, t2
);
2581 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2583 /* operands of same sign, result different sign */
2584 generate_exception(ctx
, EXCP_OVERFLOW
);
2586 gen_store_gpr(t0
, rt
);
2592 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2594 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2601 /* Logic with immediate operand */
2602 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2603 int rt
, int rs
, int16_t imm
)
2608 /* If no destination, treat it as a NOP. */
2611 uimm
= (uint16_t)imm
;
2614 if (likely(rs
!= 0)) {
2615 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2617 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2622 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2624 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2628 if (likely(rs
!= 0)) {
2629 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2631 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2635 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
2637 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2638 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2640 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2649 /* Set on less than with immediate operand */
2650 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2651 int rt
, int rs
, int16_t imm
)
2653 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2657 /* If no destination, treat it as a NOP. */
2660 t0
= tcg_temp_new();
2661 gen_load_gpr(t0
, rs
);
2664 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2667 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2673 /* Shifts with immediate operand */
2674 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2675 int rt
, int rs
, int16_t imm
)
2677 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2681 /* If no destination, treat it as a NOP. */
2685 t0
= tcg_temp_new();
2686 gen_load_gpr(t0
, rs
);
2689 tcg_gen_shli_tl(t0
, t0
, uimm
);
2690 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2693 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2697 tcg_gen_ext32u_tl(t0
, t0
);
2698 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2700 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2705 TCGv_i32 t1
= tcg_temp_new_i32();
2707 tcg_gen_trunc_tl_i32(t1
, t0
);
2708 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2709 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2710 tcg_temp_free_i32(t1
);
2712 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2715 #if defined(TARGET_MIPS64)
2717 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2720 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2723 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2727 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2729 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2733 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2736 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2739 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2742 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2750 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2751 int rd
, int rs
, int rt
)
2753 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2754 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2756 * If no destination, treat it as a NOP.
2757 * For add & sub, we must generate the overflow exception when needed.
2765 TCGv t0
= tcg_temp_local_new();
2766 TCGv t1
= tcg_temp_new();
2767 TCGv t2
= tcg_temp_new();
2768 TCGLabel
*l1
= gen_new_label();
2770 gen_load_gpr(t1
, rs
);
2771 gen_load_gpr(t2
, rt
);
2772 tcg_gen_add_tl(t0
, t1
, t2
);
2773 tcg_gen_ext32s_tl(t0
, t0
);
2774 tcg_gen_xor_tl(t1
, t1
, t2
);
2775 tcg_gen_xor_tl(t2
, t0
, t2
);
2776 tcg_gen_andc_tl(t1
, t2
, t1
);
2778 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2780 /* operands of same sign, result different sign */
2781 generate_exception(ctx
, EXCP_OVERFLOW
);
2783 gen_store_gpr(t0
, rd
);
2788 if (rs
!= 0 && rt
!= 0) {
2789 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2790 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2791 } else if (rs
== 0 && rt
!= 0) {
2792 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2793 } else if (rs
!= 0 && rt
== 0) {
2794 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2796 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2801 TCGv t0
= tcg_temp_local_new();
2802 TCGv t1
= tcg_temp_new();
2803 TCGv t2
= tcg_temp_new();
2804 TCGLabel
*l1
= gen_new_label();
2806 gen_load_gpr(t1
, rs
);
2807 gen_load_gpr(t2
, rt
);
2808 tcg_gen_sub_tl(t0
, t1
, t2
);
2809 tcg_gen_ext32s_tl(t0
, t0
);
2810 tcg_gen_xor_tl(t2
, t1
, t2
);
2811 tcg_gen_xor_tl(t1
, t0
, t1
);
2812 tcg_gen_and_tl(t1
, t1
, t2
);
2814 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2817 * operands of different sign, first operand and the result
2820 generate_exception(ctx
, EXCP_OVERFLOW
);
2822 gen_store_gpr(t0
, rd
);
2827 if (rs
!= 0 && rt
!= 0) {
2828 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2829 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2830 } else if (rs
== 0 && rt
!= 0) {
2831 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2832 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2833 } else if (rs
!= 0 && rt
== 0) {
2834 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2836 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2839 #if defined(TARGET_MIPS64)
2842 TCGv t0
= tcg_temp_local_new();
2843 TCGv t1
= tcg_temp_new();
2844 TCGv t2
= tcg_temp_new();
2845 TCGLabel
*l1
= gen_new_label();
2847 gen_load_gpr(t1
, rs
);
2848 gen_load_gpr(t2
, rt
);
2849 tcg_gen_add_tl(t0
, t1
, t2
);
2850 tcg_gen_xor_tl(t1
, t1
, t2
);
2851 tcg_gen_xor_tl(t2
, t0
, t2
);
2852 tcg_gen_andc_tl(t1
, t2
, t1
);
2854 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2856 /* operands of same sign, result different sign */
2857 generate_exception(ctx
, EXCP_OVERFLOW
);
2859 gen_store_gpr(t0
, rd
);
2864 if (rs
!= 0 && rt
!= 0) {
2865 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2866 } else if (rs
== 0 && rt
!= 0) {
2867 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2868 } else if (rs
!= 0 && rt
== 0) {
2869 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2871 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2876 TCGv t0
= tcg_temp_local_new();
2877 TCGv t1
= tcg_temp_new();
2878 TCGv t2
= tcg_temp_new();
2879 TCGLabel
*l1
= gen_new_label();
2881 gen_load_gpr(t1
, rs
);
2882 gen_load_gpr(t2
, rt
);
2883 tcg_gen_sub_tl(t0
, t1
, t2
);
2884 tcg_gen_xor_tl(t2
, t1
, t2
);
2885 tcg_gen_xor_tl(t1
, t0
, t1
);
2886 tcg_gen_and_tl(t1
, t1
, t2
);
2888 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2891 * Operands of different sign, first operand and result different
2894 generate_exception(ctx
, EXCP_OVERFLOW
);
2896 gen_store_gpr(t0
, rd
);
2901 if (rs
!= 0 && rt
!= 0) {
2902 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2903 } else if (rs
== 0 && rt
!= 0) {
2904 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2905 } else if (rs
!= 0 && rt
== 0) {
2906 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2908 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2913 if (likely(rs
!= 0 && rt
!= 0)) {
2914 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2915 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2917 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2923 /* Conditional move */
2924 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2925 int rd
, int rs
, int rt
)
2930 /* If no destination, treat it as a NOP. */
2934 t0
= tcg_temp_new();
2935 gen_load_gpr(t0
, rt
);
2936 t1
= tcg_const_tl(0);
2937 t2
= tcg_temp_new();
2938 gen_load_gpr(t2
, rs
);
2941 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2944 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2947 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2950 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2959 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2960 int rd
, int rs
, int rt
)
2963 /* If no destination, treat it as a NOP. */
2969 if (likely(rs
!= 0 && rt
!= 0)) {
2970 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2972 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2976 if (rs
!= 0 && rt
!= 0) {
2977 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2978 } else if (rs
== 0 && rt
!= 0) {
2979 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2980 } else if (rs
!= 0 && rt
== 0) {
2981 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2983 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2987 if (likely(rs
!= 0 && rt
!= 0)) {
2988 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2989 } else if (rs
== 0 && rt
!= 0) {
2990 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2991 } else if (rs
!= 0 && rt
== 0) {
2992 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2994 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2998 if (likely(rs
!= 0 && rt
!= 0)) {
2999 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3000 } else if (rs
== 0 && rt
!= 0) {
3001 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3002 } else if (rs
!= 0 && rt
== 0) {
3003 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3005 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3011 /* Set on lower than */
3012 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3013 int rd
, int rs
, int rt
)
3018 /* If no destination, treat it as a NOP. */
3022 t0
= tcg_temp_new();
3023 t1
= tcg_temp_new();
3024 gen_load_gpr(t0
, rs
);
3025 gen_load_gpr(t1
, rt
);
3028 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3031 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3039 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3040 int rd
, int rs
, int rt
)
3046 * If no destination, treat it as a NOP.
3047 * For add & sub, we must generate the overflow exception when needed.
3052 t0
= tcg_temp_new();
3053 t1
= tcg_temp_new();
3054 gen_load_gpr(t0
, rs
);
3055 gen_load_gpr(t1
, rt
);
3058 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3059 tcg_gen_shl_tl(t0
, t1
, t0
);
3060 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3063 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3064 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3067 tcg_gen_ext32u_tl(t1
, t1
);
3068 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3069 tcg_gen_shr_tl(t0
, t1
, t0
);
3070 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3074 TCGv_i32 t2
= tcg_temp_new_i32();
3075 TCGv_i32 t3
= tcg_temp_new_i32();
3077 tcg_gen_trunc_tl_i32(t2
, t0
);
3078 tcg_gen_trunc_tl_i32(t3
, t1
);
3079 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3080 tcg_gen_rotr_i32(t2
, t3
, t2
);
3081 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3082 tcg_temp_free_i32(t2
);
3083 tcg_temp_free_i32(t3
);
3086 #if defined(TARGET_MIPS64)
3088 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3089 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3092 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3093 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3096 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3097 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3100 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3101 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3109 /* Arithmetic on HI/LO registers */
3110 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3112 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3123 #if defined(TARGET_MIPS64)
3125 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3129 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3133 #if defined(TARGET_MIPS64)
3135 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3139 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3144 #if defined(TARGET_MIPS64)
3146 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3150 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3153 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3158 #if defined(TARGET_MIPS64)
3160 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3164 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3167 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3173 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3176 TCGv t0
= tcg_const_tl(addr
);
3177 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3178 gen_store_gpr(t0
, reg
);
3182 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3188 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3191 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3192 addr
= addr_add(ctx
, pc
, offset
);
3193 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3197 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3198 addr
= addr_add(ctx
, pc
, offset
);
3199 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3201 #if defined(TARGET_MIPS64)
3204 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3205 addr
= addr_add(ctx
, pc
, offset
);
3206 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3210 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3213 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3214 addr
= addr_add(ctx
, pc
, offset
);
3215 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3220 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3221 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3222 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3225 #if defined(TARGET_MIPS64)
3226 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3227 case R6_OPC_LDPC
+ (1 << 16):
3228 case R6_OPC_LDPC
+ (2 << 16):
3229 case R6_OPC_LDPC
+ (3 << 16):
3231 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3232 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3233 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3237 MIPS_INVAL("OPC_PCREL");
3238 gen_reserved_instruction(ctx
);
3245 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3254 t0
= tcg_temp_new();
3255 t1
= tcg_temp_new();
3257 gen_load_gpr(t0
, rs
);
3258 gen_load_gpr(t1
, rt
);
3263 TCGv t2
= tcg_temp_new();
3264 TCGv t3
= tcg_temp_new();
3265 tcg_gen_ext32s_tl(t0
, t0
);
3266 tcg_gen_ext32s_tl(t1
, t1
);
3267 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3268 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3269 tcg_gen_and_tl(t2
, t2
, t3
);
3270 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3271 tcg_gen_or_tl(t2
, t2
, t3
);
3272 tcg_gen_movi_tl(t3
, 0);
3273 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3274 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3275 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3282 TCGv t2
= tcg_temp_new();
3283 TCGv t3
= tcg_temp_new();
3284 tcg_gen_ext32s_tl(t0
, t0
);
3285 tcg_gen_ext32s_tl(t1
, t1
);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3287 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3288 tcg_gen_and_tl(t2
, t2
, t3
);
3289 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3290 tcg_gen_or_tl(t2
, t2
, t3
);
3291 tcg_gen_movi_tl(t3
, 0);
3292 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3293 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3294 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3301 TCGv t2
= tcg_const_tl(0);
3302 TCGv t3
= tcg_const_tl(1);
3303 tcg_gen_ext32u_tl(t0
, t0
);
3304 tcg_gen_ext32u_tl(t1
, t1
);
3305 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3306 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3307 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3314 TCGv t2
= tcg_const_tl(0);
3315 TCGv t3
= tcg_const_tl(1);
3316 tcg_gen_ext32u_tl(t0
, t0
);
3317 tcg_gen_ext32u_tl(t1
, t1
);
3318 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3319 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3320 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3327 TCGv_i32 t2
= tcg_temp_new_i32();
3328 TCGv_i32 t3
= tcg_temp_new_i32();
3329 tcg_gen_trunc_tl_i32(t2
, t0
);
3330 tcg_gen_trunc_tl_i32(t3
, t1
);
3331 tcg_gen_mul_i32(t2
, t2
, t3
);
3332 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3333 tcg_temp_free_i32(t2
);
3334 tcg_temp_free_i32(t3
);
3339 TCGv_i32 t2
= tcg_temp_new_i32();
3340 TCGv_i32 t3
= tcg_temp_new_i32();
3341 tcg_gen_trunc_tl_i32(t2
, t0
);
3342 tcg_gen_trunc_tl_i32(t3
, t1
);
3343 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3344 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3345 tcg_temp_free_i32(t2
);
3346 tcg_temp_free_i32(t3
);
3351 TCGv_i32 t2
= tcg_temp_new_i32();
3352 TCGv_i32 t3
= tcg_temp_new_i32();
3353 tcg_gen_trunc_tl_i32(t2
, t0
);
3354 tcg_gen_trunc_tl_i32(t3
, t1
);
3355 tcg_gen_mul_i32(t2
, t2
, t3
);
3356 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3357 tcg_temp_free_i32(t2
);
3358 tcg_temp_free_i32(t3
);
3363 TCGv_i32 t2
= tcg_temp_new_i32();
3364 TCGv_i32 t3
= tcg_temp_new_i32();
3365 tcg_gen_trunc_tl_i32(t2
, t0
);
3366 tcg_gen_trunc_tl_i32(t3
, t1
);
3367 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3368 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3369 tcg_temp_free_i32(t2
);
3370 tcg_temp_free_i32(t3
);
3373 #if defined(TARGET_MIPS64)
3376 TCGv t2
= tcg_temp_new();
3377 TCGv t3
= tcg_temp_new();
3378 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3379 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3380 tcg_gen_and_tl(t2
, t2
, t3
);
3381 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3382 tcg_gen_or_tl(t2
, t2
, t3
);
3383 tcg_gen_movi_tl(t3
, 0);
3384 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3385 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3392 TCGv t2
= tcg_temp_new();
3393 TCGv t3
= tcg_temp_new();
3394 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3395 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3396 tcg_gen_and_tl(t2
, t2
, t3
);
3397 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3398 tcg_gen_or_tl(t2
, t2
, t3
);
3399 tcg_gen_movi_tl(t3
, 0);
3400 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3401 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3408 TCGv t2
= tcg_const_tl(0);
3409 TCGv t3
= tcg_const_tl(1);
3410 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3411 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3418 TCGv t2
= tcg_const_tl(0);
3419 TCGv t3
= tcg_const_tl(1);
3420 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3421 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3427 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3431 TCGv t2
= tcg_temp_new();
3432 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3437 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3441 TCGv t2
= tcg_temp_new();
3442 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3448 MIPS_INVAL("r6 mul/div");
3449 gen_reserved_instruction(ctx
);
3457 #if defined(TARGET_MIPS64)
3458 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
3462 t0
= tcg_temp_new();
3463 t1
= tcg_temp_new();
3465 gen_load_gpr(t0
, rs
);
3466 gen_load_gpr(t1
, rt
);
3471 TCGv t2
= tcg_temp_new();
3472 TCGv t3
= tcg_temp_new();
3473 tcg_gen_ext32s_tl(t0
, t0
);
3474 tcg_gen_ext32s_tl(t1
, t1
);
3475 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3476 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3477 tcg_gen_and_tl(t2
, t2
, t3
);
3478 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3479 tcg_gen_or_tl(t2
, t2
, t3
);
3480 tcg_gen_movi_tl(t3
, 0);
3481 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3482 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
3483 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
3484 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3485 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3492 TCGv t2
= tcg_const_tl(0);
3493 TCGv t3
= tcg_const_tl(1);
3494 tcg_gen_ext32u_tl(t0
, t0
);
3495 tcg_gen_ext32u_tl(t1
, t1
);
3496 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3497 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
3498 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
3499 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3500 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3506 MIPS_INVAL("div1 TX79");
3507 gen_reserved_instruction(ctx
);
3516 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3517 int acc
, int rs
, int rt
)
3521 t0
= tcg_temp_new();
3522 t1
= tcg_temp_new();
3524 gen_load_gpr(t0
, rs
);
3525 gen_load_gpr(t1
, rt
);
3534 TCGv t2
= tcg_temp_new();
3535 TCGv t3
= tcg_temp_new();
3536 tcg_gen_ext32s_tl(t0
, t0
);
3537 tcg_gen_ext32s_tl(t1
, t1
);
3538 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3539 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3540 tcg_gen_and_tl(t2
, t2
, t3
);
3541 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3542 tcg_gen_or_tl(t2
, t2
, t3
);
3543 tcg_gen_movi_tl(t3
, 0);
3544 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3545 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3546 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3547 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3548 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3555 TCGv t2
= tcg_const_tl(0);
3556 TCGv t3
= tcg_const_tl(1);
3557 tcg_gen_ext32u_tl(t0
, t0
);
3558 tcg_gen_ext32u_tl(t1
, t1
);
3559 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3560 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3561 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3562 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3563 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3570 TCGv_i32 t2
= tcg_temp_new_i32();
3571 TCGv_i32 t3
= tcg_temp_new_i32();
3572 tcg_gen_trunc_tl_i32(t2
, t0
);
3573 tcg_gen_trunc_tl_i32(t3
, t1
);
3574 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3575 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3576 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3577 tcg_temp_free_i32(t2
);
3578 tcg_temp_free_i32(t3
);
3583 TCGv_i32 t2
= tcg_temp_new_i32();
3584 TCGv_i32 t3
= tcg_temp_new_i32();
3585 tcg_gen_trunc_tl_i32(t2
, t0
);
3586 tcg_gen_trunc_tl_i32(t3
, t1
);
3587 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3588 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3589 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3590 tcg_temp_free_i32(t2
);
3591 tcg_temp_free_i32(t3
);
3594 #if defined(TARGET_MIPS64)
3597 TCGv t2
= tcg_temp_new();
3598 TCGv t3
= tcg_temp_new();
3599 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3600 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3601 tcg_gen_and_tl(t2
, t2
, t3
);
3602 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3603 tcg_gen_or_tl(t2
, t2
, t3
);
3604 tcg_gen_movi_tl(t3
, 0);
3605 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3606 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3607 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3614 TCGv t2
= tcg_const_tl(0);
3615 TCGv t3
= tcg_const_tl(1);
3616 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3617 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3618 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3624 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3627 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3632 TCGv_i64 t2
= tcg_temp_new_i64();
3633 TCGv_i64 t3
= tcg_temp_new_i64();
3635 tcg_gen_ext_tl_i64(t2
, t0
);
3636 tcg_gen_ext_tl_i64(t3
, t1
);
3637 tcg_gen_mul_i64(t2
, t2
, t3
);
3638 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3639 tcg_gen_add_i64(t2
, t2
, t3
);
3640 tcg_temp_free_i64(t3
);
3641 gen_move_low32(cpu_LO
[acc
], t2
);
3642 gen_move_high32(cpu_HI
[acc
], t2
);
3643 tcg_temp_free_i64(t2
);
3648 TCGv_i64 t2
= tcg_temp_new_i64();
3649 TCGv_i64 t3
= tcg_temp_new_i64();
3651 tcg_gen_ext32u_tl(t0
, t0
);
3652 tcg_gen_ext32u_tl(t1
, t1
);
3653 tcg_gen_extu_tl_i64(t2
, t0
);
3654 tcg_gen_extu_tl_i64(t3
, t1
);
3655 tcg_gen_mul_i64(t2
, t2
, t3
);
3656 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3657 tcg_gen_add_i64(t2
, t2
, t3
);
3658 tcg_temp_free_i64(t3
);
3659 gen_move_low32(cpu_LO
[acc
], t2
);
3660 gen_move_high32(cpu_HI
[acc
], t2
);
3661 tcg_temp_free_i64(t2
);
3666 TCGv_i64 t2
= tcg_temp_new_i64();
3667 TCGv_i64 t3
= tcg_temp_new_i64();
3669 tcg_gen_ext_tl_i64(t2
, t0
);
3670 tcg_gen_ext_tl_i64(t3
, t1
);
3671 tcg_gen_mul_i64(t2
, t2
, t3
);
3672 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3673 tcg_gen_sub_i64(t2
, t3
, t2
);
3674 tcg_temp_free_i64(t3
);
3675 gen_move_low32(cpu_LO
[acc
], t2
);
3676 gen_move_high32(cpu_HI
[acc
], t2
);
3677 tcg_temp_free_i64(t2
);
3682 TCGv_i64 t2
= tcg_temp_new_i64();
3683 TCGv_i64 t3
= tcg_temp_new_i64();
3685 tcg_gen_ext32u_tl(t0
, t0
);
3686 tcg_gen_ext32u_tl(t1
, t1
);
3687 tcg_gen_extu_tl_i64(t2
, t0
);
3688 tcg_gen_extu_tl_i64(t3
, t1
);
3689 tcg_gen_mul_i64(t2
, t2
, t3
);
3690 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3691 tcg_gen_sub_i64(t2
, t3
, t2
);
3692 tcg_temp_free_i64(t3
);
3693 gen_move_low32(cpu_LO
[acc
], t2
);
3694 gen_move_high32(cpu_HI
[acc
], t2
);
3695 tcg_temp_free_i64(t2
);
3699 MIPS_INVAL("mul/div");
3700 gen_reserved_instruction(ctx
);
3709 * These MULT[U] and MADD[U] instructions implemented in for example
3710 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3711 * architectures are special three-operand variants with the syntax
3713 * MULT[U][1] rd, rs, rt
3717 * (rd, LO, HI) <- rs * rt
3721 * MADD[U][1] rd, rs, rt
3725 * (rd, LO, HI) <- (LO, HI) + rs * rt
3727 * where the low-order 32-bits of the result is placed into both the
3728 * GPR rd and the special register LO. The high-order 32-bits of the
3729 * result is placed into the special register HI.
3731 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3732 * which is the zero register that always reads as 0.
3734 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
3735 int rd
, int rs
, int rt
)
3737 TCGv t0
= tcg_temp_new();
3738 TCGv t1
= tcg_temp_new();
3741 gen_load_gpr(t0
, rs
);
3742 gen_load_gpr(t1
, rt
);
3750 TCGv_i32 t2
= tcg_temp_new_i32();
3751 TCGv_i32 t3
= tcg_temp_new_i32();
3752 tcg_gen_trunc_tl_i32(t2
, t0
);
3753 tcg_gen_trunc_tl_i32(t3
, t1
);
3754 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3756 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3758 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3759 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3760 tcg_temp_free_i32(t2
);
3761 tcg_temp_free_i32(t3
);
3764 case MMI_OPC_MULTU1
:
3769 TCGv_i32 t2
= tcg_temp_new_i32();
3770 TCGv_i32 t3
= tcg_temp_new_i32();
3771 tcg_gen_trunc_tl_i32(t2
, t0
);
3772 tcg_gen_trunc_tl_i32(t3
, t1
);
3773 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3775 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3777 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3778 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3779 tcg_temp_free_i32(t2
);
3780 tcg_temp_free_i32(t3
);
3788 TCGv_i64 t2
= tcg_temp_new_i64();
3789 TCGv_i64 t3
= tcg_temp_new_i64();
3791 tcg_gen_ext_tl_i64(t2
, t0
);
3792 tcg_gen_ext_tl_i64(t3
, t1
);
3793 tcg_gen_mul_i64(t2
, t2
, t3
);
3794 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3795 tcg_gen_add_i64(t2
, t2
, t3
);
3796 tcg_temp_free_i64(t3
);
3797 gen_move_low32(cpu_LO
[acc
], t2
);
3798 gen_move_high32(cpu_HI
[acc
], t2
);
3800 gen_move_low32(cpu_gpr
[rd
], t2
);
3802 tcg_temp_free_i64(t2
);
3805 case MMI_OPC_MADDU1
:
3810 TCGv_i64 t2
= tcg_temp_new_i64();
3811 TCGv_i64 t3
= tcg_temp_new_i64();
3813 tcg_gen_ext32u_tl(t0
, t0
);
3814 tcg_gen_ext32u_tl(t1
, t1
);
3815 tcg_gen_extu_tl_i64(t2
, t0
);
3816 tcg_gen_extu_tl_i64(t3
, t1
);
3817 tcg_gen_mul_i64(t2
, t2
, t3
);
3818 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3819 tcg_gen_add_i64(t2
, t2
, t3
);
3820 tcg_temp_free_i64(t3
);
3821 gen_move_low32(cpu_LO
[acc
], t2
);
3822 gen_move_high32(cpu_HI
[acc
], t2
);
3824 gen_move_low32(cpu_gpr
[rd
], t2
);
3826 tcg_temp_free_i64(t2
);
3830 MIPS_INVAL("mul/madd TXx9");
3831 gen_reserved_instruction(ctx
);
3840 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
3841 int rd
, int rs
, int rt
)
3843 TCGv t0
= tcg_temp_new();
3844 TCGv t1
= tcg_temp_new();
3846 gen_load_gpr(t0
, rs
);
3847 gen_load_gpr(t1
, rt
);
3850 case OPC_VR54XX_MULS
:
3851 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3853 case OPC_VR54XX_MULSU
:
3854 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3856 case OPC_VR54XX_MACC
:
3857 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3859 case OPC_VR54XX_MACCU
:
3860 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3862 case OPC_VR54XX_MSAC
:
3863 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3865 case OPC_VR54XX_MSACU
:
3866 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3868 case OPC_VR54XX_MULHI
:
3869 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3871 case OPC_VR54XX_MULHIU
:
3872 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3874 case OPC_VR54XX_MULSHI
:
3875 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3877 case OPC_VR54XX_MULSHIU
:
3878 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3880 case OPC_VR54XX_MACCHI
:
3881 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3883 case OPC_VR54XX_MACCHIU
:
3884 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3886 case OPC_VR54XX_MSACHI
:
3887 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3889 case OPC_VR54XX_MSACHIU
:
3890 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3893 MIPS_INVAL("mul vr54xx");
3894 gen_reserved_instruction(ctx
);
3897 gen_store_gpr(t0
, rd
);
3904 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
3914 gen_load_gpr(t0
, rs
);
3919 #if defined(TARGET_MIPS64)
3923 tcg_gen_not_tl(t0
, t0
);
3932 tcg_gen_ext32u_tl(t0
, t0
);
3933 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
3934 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
3936 #if defined(TARGET_MIPS64)
3941 tcg_gen_clzi_i64(t0
, t0
, 64);
3947 /* Godson integer instructions */
3948 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3949 int rd
, int rs
, int rt
)
3961 case OPC_MULTU_G_2E
:
3962 case OPC_MULTU_G_2F
:
3963 #if defined(TARGET_MIPS64)
3964 case OPC_DMULT_G_2E
:
3965 case OPC_DMULT_G_2F
:
3966 case OPC_DMULTU_G_2E
:
3967 case OPC_DMULTU_G_2F
:
3969 t0
= tcg_temp_new();
3970 t1
= tcg_temp_new();
3973 t0
= tcg_temp_local_new();
3974 t1
= tcg_temp_local_new();
3978 gen_load_gpr(t0
, rs
);
3979 gen_load_gpr(t1
, rt
);
3984 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3985 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3987 case OPC_MULTU_G_2E
:
3988 case OPC_MULTU_G_2F
:
3989 tcg_gen_ext32u_tl(t0
, t0
);
3990 tcg_gen_ext32u_tl(t1
, t1
);
3991 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3992 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3997 TCGLabel
*l1
= gen_new_label();
3998 TCGLabel
*l2
= gen_new_label();
3999 TCGLabel
*l3
= gen_new_label();
4000 tcg_gen_ext32s_tl(t0
, t0
);
4001 tcg_gen_ext32s_tl(t1
, t1
);
4002 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4003 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4006 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4007 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4008 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4011 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4012 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4019 TCGLabel
*l1
= gen_new_label();
4020 TCGLabel
*l2
= gen_new_label();
4021 tcg_gen_ext32u_tl(t0
, t0
);
4022 tcg_gen_ext32u_tl(t1
, t1
);
4023 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4024 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4027 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4028 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4035 TCGLabel
*l1
= gen_new_label();
4036 TCGLabel
*l2
= gen_new_label();
4037 TCGLabel
*l3
= gen_new_label();
4038 tcg_gen_ext32u_tl(t0
, t0
);
4039 tcg_gen_ext32u_tl(t1
, t1
);
4040 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4041 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4042 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4044 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4047 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4048 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4055 TCGLabel
*l1
= gen_new_label();
4056 TCGLabel
*l2
= gen_new_label();
4057 tcg_gen_ext32u_tl(t0
, t0
);
4058 tcg_gen_ext32u_tl(t1
, t1
);
4059 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4060 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4063 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4064 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4068 #if defined(TARGET_MIPS64)
4069 case OPC_DMULT_G_2E
:
4070 case OPC_DMULT_G_2F
:
4071 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4073 case OPC_DMULTU_G_2E
:
4074 case OPC_DMULTU_G_2F
:
4075 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4080 TCGLabel
*l1
= gen_new_label();
4081 TCGLabel
*l2
= gen_new_label();
4082 TCGLabel
*l3
= gen_new_label();
4083 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4084 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4087 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4088 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4089 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4092 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4096 case OPC_DDIVU_G_2E
:
4097 case OPC_DDIVU_G_2F
:
4099 TCGLabel
*l1
= gen_new_label();
4100 TCGLabel
*l2
= gen_new_label();
4101 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4102 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4105 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4112 TCGLabel
*l1
= gen_new_label();
4113 TCGLabel
*l2
= gen_new_label();
4114 TCGLabel
*l3
= gen_new_label();
4115 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4116 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4117 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4119 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4122 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4126 case OPC_DMODU_G_2E
:
4127 case OPC_DMODU_G_2F
:
4129 TCGLabel
*l1
= gen_new_label();
4130 TCGLabel
*l2
= gen_new_label();
4131 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4132 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4135 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4146 /* Loongson multimedia instructions */
4147 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4149 uint32_t opc
, shift_max
;
4153 opc
= MASK_LMMI(ctx
->opcode
);
4159 t0
= tcg_temp_local_new_i64();
4160 t1
= tcg_temp_local_new_i64();
4163 t0
= tcg_temp_new_i64();
4164 t1
= tcg_temp_new_i64();
4168 check_cp1_enabled(ctx
);
4169 gen_load_fpr64(ctx
, t0
, rs
);
4170 gen_load_fpr64(ctx
, t1
, rt
);
4174 gen_helper_paddsh(t0
, t0
, t1
);
4177 gen_helper_paddush(t0
, t0
, t1
);
4180 gen_helper_paddh(t0
, t0
, t1
);
4183 gen_helper_paddw(t0
, t0
, t1
);
4186 gen_helper_paddsb(t0
, t0
, t1
);
4189 gen_helper_paddusb(t0
, t0
, t1
);
4192 gen_helper_paddb(t0
, t0
, t1
);
4196 gen_helper_psubsh(t0
, t0
, t1
);
4199 gen_helper_psubush(t0
, t0
, t1
);
4202 gen_helper_psubh(t0
, t0
, t1
);
4205 gen_helper_psubw(t0
, t0
, t1
);
4208 gen_helper_psubsb(t0
, t0
, t1
);
4211 gen_helper_psubusb(t0
, t0
, t1
);
4214 gen_helper_psubb(t0
, t0
, t1
);
4218 gen_helper_pshufh(t0
, t0
, t1
);
4221 gen_helper_packsswh(t0
, t0
, t1
);
4224 gen_helper_packsshb(t0
, t0
, t1
);
4227 gen_helper_packushb(t0
, t0
, t1
);
4231 gen_helper_punpcklhw(t0
, t0
, t1
);
4234 gen_helper_punpckhhw(t0
, t0
, t1
);
4237 gen_helper_punpcklbh(t0
, t0
, t1
);
4240 gen_helper_punpckhbh(t0
, t0
, t1
);
4243 gen_helper_punpcklwd(t0
, t0
, t1
);
4246 gen_helper_punpckhwd(t0
, t0
, t1
);
4250 gen_helper_pavgh(t0
, t0
, t1
);
4253 gen_helper_pavgb(t0
, t0
, t1
);
4256 gen_helper_pmaxsh(t0
, t0
, t1
);
4259 gen_helper_pminsh(t0
, t0
, t1
);
4262 gen_helper_pmaxub(t0
, t0
, t1
);
4265 gen_helper_pminub(t0
, t0
, t1
);
4269 gen_helper_pcmpeqw(t0
, t0
, t1
);
4272 gen_helper_pcmpgtw(t0
, t0
, t1
);
4275 gen_helper_pcmpeqh(t0
, t0
, t1
);
4278 gen_helper_pcmpgth(t0
, t0
, t1
);
4281 gen_helper_pcmpeqb(t0
, t0
, t1
);
4284 gen_helper_pcmpgtb(t0
, t0
, t1
);
4288 gen_helper_psllw(t0
, t0
, t1
);
4291 gen_helper_psllh(t0
, t0
, t1
);
4294 gen_helper_psrlw(t0
, t0
, t1
);
4297 gen_helper_psrlh(t0
, t0
, t1
);
4300 gen_helper_psraw(t0
, t0
, t1
);
4303 gen_helper_psrah(t0
, t0
, t1
);
4307 gen_helper_pmullh(t0
, t0
, t1
);
4310 gen_helper_pmulhh(t0
, t0
, t1
);
4313 gen_helper_pmulhuh(t0
, t0
, t1
);
4316 gen_helper_pmaddhw(t0
, t0
, t1
);
4320 gen_helper_pasubub(t0
, t0
, t1
);
4323 gen_helper_biadd(t0
, t0
);
4326 gen_helper_pmovmskb(t0
, t0
);
4330 tcg_gen_add_i64(t0
, t0
, t1
);
4333 tcg_gen_sub_i64(t0
, t0
, t1
);
4336 tcg_gen_xor_i64(t0
, t0
, t1
);
4339 tcg_gen_nor_i64(t0
, t0
, t1
);
4342 tcg_gen_and_i64(t0
, t0
, t1
);
4345 tcg_gen_or_i64(t0
, t0
, t1
);
4349 tcg_gen_andc_i64(t0
, t1
, t0
);
4353 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4356 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4359 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4362 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4366 tcg_gen_andi_i64(t1
, t1
, 3);
4367 tcg_gen_shli_i64(t1
, t1
, 4);
4368 tcg_gen_shr_i64(t0
, t0
, t1
);
4369 tcg_gen_ext16u_i64(t0
, t0
);
4373 tcg_gen_add_i64(t0
, t0
, t1
);
4374 tcg_gen_ext32s_i64(t0
, t0
);
4377 tcg_gen_sub_i64(t0
, t0
, t1
);
4378 tcg_gen_ext32s_i64(t0
, t0
);
4400 /* Make sure shift count isn't TCG undefined behaviour. */
4401 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4406 tcg_gen_shl_i64(t0
, t0
, t1
);
4411 * Since SRA is UndefinedResult without sign-extended inputs,
4412 * we can treat SRA and DSRA the same.
4414 tcg_gen_sar_i64(t0
, t0
, t1
);
4417 /* We want to shift in zeros for SRL; zero-extend first. */
4418 tcg_gen_ext32u_i64(t0
, t0
);
4421 tcg_gen_shr_i64(t0
, t0
, t1
);
4425 if (shift_max
== 32) {
4426 tcg_gen_ext32s_i64(t0
, t0
);
4429 /* Shifts larger than MAX produce zero. */
4430 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4431 tcg_gen_neg_i64(t1
, t1
);
4432 tcg_gen_and_i64(t0
, t0
, t1
);
4438 TCGv_i64 t2
= tcg_temp_new_i64();
4439 TCGLabel
*lab
= gen_new_label();
4441 tcg_gen_mov_i64(t2
, t0
);
4442 tcg_gen_add_i64(t0
, t1
, t2
);
4443 if (opc
== OPC_ADD_CP2
) {
4444 tcg_gen_ext32s_i64(t0
, t0
);
4446 tcg_gen_xor_i64(t1
, t1
, t2
);
4447 tcg_gen_xor_i64(t2
, t2
, t0
);
4448 tcg_gen_andc_i64(t1
, t2
, t1
);
4449 tcg_temp_free_i64(t2
);
4450 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4451 generate_exception(ctx
, EXCP_OVERFLOW
);
4459 TCGv_i64 t2
= tcg_temp_new_i64();
4460 TCGLabel
*lab
= gen_new_label();
4462 tcg_gen_mov_i64(t2
, t0
);
4463 tcg_gen_sub_i64(t0
, t1
, t2
);
4464 if (opc
== OPC_SUB_CP2
) {
4465 tcg_gen_ext32s_i64(t0
, t0
);
4467 tcg_gen_xor_i64(t1
, t1
, t2
);
4468 tcg_gen_xor_i64(t2
, t2
, t0
);
4469 tcg_gen_and_i64(t1
, t1
, t2
);
4470 tcg_temp_free_i64(t2
);
4471 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4472 generate_exception(ctx
, EXCP_OVERFLOW
);
4478 tcg_gen_ext32u_i64(t0
, t0
);
4479 tcg_gen_ext32u_i64(t1
, t1
);
4480 tcg_gen_mul_i64(t0
, t0
, t1
);
4489 cond
= TCG_COND_LTU
;
4497 cond
= TCG_COND_LEU
;
4504 int cc
= (ctx
->opcode
>> 8) & 0x7;
4505 TCGv_i64 t64
= tcg_temp_new_i64();
4506 TCGv_i32 t32
= tcg_temp_new_i32();
4508 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
4509 tcg_gen_extrl_i64_i32(t32
, t64
);
4510 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
4513 tcg_temp_free_i32(t32
);
4514 tcg_temp_free_i64(t64
);
4519 MIPS_INVAL("loongson_cp2");
4520 gen_reserved_instruction(ctx
);
4524 gen_store_fpr64(ctx
, t0
, rd
);
4527 tcg_temp_free_i64(t0
);
4528 tcg_temp_free_i64(t1
);
4531 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
4536 #if defined(TARGET_MIPS64)
4537 int lsq_rt1
= ctx
->opcode
& 0x1f;
4538 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
4540 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
4542 t0
= tcg_temp_new();
4544 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
4545 #if defined(TARGET_MIPS64)
4547 t1
= tcg_temp_new();
4548 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4549 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4550 ctx
->default_tcg_memop_mask
);
4551 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4552 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4553 ctx
->default_tcg_memop_mask
);
4554 gen_store_gpr(t1
, rt
);
4555 gen_store_gpr(t0
, lsq_rt1
);
4559 check_cp1_enabled(ctx
);
4560 t1
= tcg_temp_new();
4561 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4562 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4563 ctx
->default_tcg_memop_mask
);
4564 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4565 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4566 ctx
->default_tcg_memop_mask
);
4567 gen_store_fpr64(ctx
, t1
, rt
);
4568 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
4572 t1
= tcg_temp_new();
4573 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4574 gen_load_gpr(t1
, rt
);
4575 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4576 ctx
->default_tcg_memop_mask
);
4577 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4578 gen_load_gpr(t1
, lsq_rt1
);
4579 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4580 ctx
->default_tcg_memop_mask
);
4584 check_cp1_enabled(ctx
);
4585 t1
= tcg_temp_new();
4586 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4587 gen_load_fpr64(ctx
, t1
, rt
);
4588 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4589 ctx
->default_tcg_memop_mask
);
4590 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4591 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
4592 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4593 ctx
->default_tcg_memop_mask
);
4598 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4600 check_cp1_enabled(ctx
);
4601 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4602 t1
= tcg_temp_new();
4603 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4604 tcg_gen_andi_tl(t1
, t0
, 3);
4605 #ifndef TARGET_WORDS_BIGENDIAN
4606 tcg_gen_xori_tl(t1
, t1
, 3);
4608 tcg_gen_shli_tl(t1
, t1
, 3);
4609 tcg_gen_andi_tl(t0
, t0
, ~3);
4610 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4611 tcg_gen_shl_tl(t0
, t0
, t1
);
4612 t2
= tcg_const_tl(-1);
4613 tcg_gen_shl_tl(t2
, t2
, t1
);
4614 fp0
= tcg_temp_new_i32();
4615 gen_load_fpr32(ctx
, fp0
, rt
);
4616 tcg_gen_ext_i32_tl(t1
, fp0
);
4617 tcg_gen_andc_tl(t1
, t1
, t2
);
4619 tcg_gen_or_tl(t0
, t0
, t1
);
4621 #if defined(TARGET_MIPS64)
4622 tcg_gen_extrl_i64_i32(fp0
, t0
);
4624 tcg_gen_ext32s_tl(fp0
, t0
);
4626 gen_store_fpr32(ctx
, fp0
, rt
);
4627 tcg_temp_free_i32(fp0
);
4630 check_cp1_enabled(ctx
);
4631 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4632 t1
= tcg_temp_new();
4633 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4634 tcg_gen_andi_tl(t1
, t0
, 3);
4635 #ifdef TARGET_WORDS_BIGENDIAN
4636 tcg_gen_xori_tl(t1
, t1
, 3);
4638 tcg_gen_shli_tl(t1
, t1
, 3);
4639 tcg_gen_andi_tl(t0
, t0
, ~3);
4640 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4641 tcg_gen_shr_tl(t0
, t0
, t1
);
4642 tcg_gen_xori_tl(t1
, t1
, 31);
4643 t2
= tcg_const_tl(0xfffffffeull
);
4644 tcg_gen_shl_tl(t2
, t2
, t1
);
4645 fp0
= tcg_temp_new_i32();
4646 gen_load_fpr32(ctx
, fp0
, rt
);
4647 tcg_gen_ext_i32_tl(t1
, fp0
);
4648 tcg_gen_and_tl(t1
, t1
, t2
);
4650 tcg_gen_or_tl(t0
, t0
, t1
);
4652 #if defined(TARGET_MIPS64)
4653 tcg_gen_extrl_i64_i32(fp0
, t0
);
4655 tcg_gen_ext32s_tl(fp0
, t0
);
4657 gen_store_fpr32(ctx
, fp0
, rt
);
4658 tcg_temp_free_i32(fp0
);
4660 #if defined(TARGET_MIPS64)
4662 check_cp1_enabled(ctx
);
4663 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4664 t1
= tcg_temp_new();
4665 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4666 tcg_gen_andi_tl(t1
, t0
, 7);
4667 #ifndef TARGET_WORDS_BIGENDIAN
4668 tcg_gen_xori_tl(t1
, t1
, 7);
4670 tcg_gen_shli_tl(t1
, t1
, 3);
4671 tcg_gen_andi_tl(t0
, t0
, ~7);
4672 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4673 tcg_gen_shl_tl(t0
, t0
, t1
);
4674 t2
= tcg_const_tl(-1);
4675 tcg_gen_shl_tl(t2
, t2
, t1
);
4676 gen_load_fpr64(ctx
, t1
, rt
);
4677 tcg_gen_andc_tl(t1
, t1
, t2
);
4679 tcg_gen_or_tl(t0
, t0
, t1
);
4681 gen_store_fpr64(ctx
, t0
, rt
);
4684 check_cp1_enabled(ctx
);
4685 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4686 t1
= tcg_temp_new();
4687 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4688 tcg_gen_andi_tl(t1
, t0
, 7);
4689 #ifdef TARGET_WORDS_BIGENDIAN
4690 tcg_gen_xori_tl(t1
, t1
, 7);
4692 tcg_gen_shli_tl(t1
, t1
, 3);
4693 tcg_gen_andi_tl(t0
, t0
, ~7);
4694 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4695 tcg_gen_shr_tl(t0
, t0
, t1
);
4696 tcg_gen_xori_tl(t1
, t1
, 63);
4697 t2
= tcg_const_tl(0xfffffffffffffffeull
);
4698 tcg_gen_shl_tl(t2
, t2
, t1
);
4699 gen_load_fpr64(ctx
, t1
, rt
);
4700 tcg_gen_and_tl(t1
, t1
, t2
);
4702 tcg_gen_or_tl(t0
, t0
, t1
);
4704 gen_store_fpr64(ctx
, t0
, rt
);
4708 MIPS_INVAL("loongson_gsshfl");
4709 gen_reserved_instruction(ctx
);
4714 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4716 check_cp1_enabled(ctx
);
4717 t1
= tcg_temp_new();
4718 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4719 fp0
= tcg_temp_new_i32();
4720 gen_load_fpr32(ctx
, fp0
, rt
);
4721 tcg_gen_ext_i32_tl(t1
, fp0
);
4722 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
4723 tcg_temp_free_i32(fp0
);
4727 check_cp1_enabled(ctx
);
4728 t1
= tcg_temp_new();
4729 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4730 fp0
= tcg_temp_new_i32();
4731 gen_load_fpr32(ctx
, fp0
, rt
);
4732 tcg_gen_ext_i32_tl(t1
, fp0
);
4733 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
4734 tcg_temp_free_i32(fp0
);
4737 #if defined(TARGET_MIPS64)
4739 check_cp1_enabled(ctx
);
4740 t1
= tcg_temp_new();
4741 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4742 gen_load_fpr64(ctx
, t1
, rt
);
4743 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
4747 check_cp1_enabled(ctx
);
4748 t1
= tcg_temp_new();
4749 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4750 gen_load_fpr64(ctx
, t1
, rt
);
4751 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
4756 MIPS_INVAL("loongson_gsshfs");
4757 gen_reserved_instruction(ctx
);
4762 MIPS_INVAL("loongson_gslsq");
4763 gen_reserved_instruction(ctx
);
4769 /* Loongson EXT LDC2/SDC2 */
4770 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
4773 int offset
= sextract32(ctx
->opcode
, 3, 8);
4774 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
4778 /* Pre-conditions */
4784 /* prefetch, implement as NOP */
4795 #if defined(TARGET_MIPS64)
4798 check_cp1_enabled(ctx
);
4799 /* prefetch, implement as NOP */
4805 #if defined(TARGET_MIPS64)
4808 check_cp1_enabled(ctx
);
4811 MIPS_INVAL("loongson_lsdc2");
4812 gen_reserved_instruction(ctx
);
4817 t0
= tcg_temp_new();
4819 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4820 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4824 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
4825 gen_store_gpr(t0
, rt
);
4828 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
4829 ctx
->default_tcg_memop_mask
);
4830 gen_store_gpr(t0
, rt
);
4833 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4835 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4837 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
4838 ctx
->default_tcg_memop_mask
);
4839 gen_store_gpr(t0
, rt
);
4841 #if defined(TARGET_MIPS64)
4843 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4845 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4847 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4848 ctx
->default_tcg_memop_mask
);
4849 gen_store_gpr(t0
, rt
);
4853 check_cp1_enabled(ctx
);
4854 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4856 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4858 fp0
= tcg_temp_new_i32();
4859 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
4860 ctx
->default_tcg_memop_mask
);
4861 gen_store_fpr32(ctx
, fp0
, rt
);
4862 tcg_temp_free_i32(fp0
);
4864 #if defined(TARGET_MIPS64)
4866 check_cp1_enabled(ctx
);
4867 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4869 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4871 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4872 ctx
->default_tcg_memop_mask
);
4873 gen_store_fpr64(ctx
, t0
, rt
);
4877 t1
= tcg_temp_new();
4878 gen_load_gpr(t1
, rt
);
4879 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
4883 t1
= tcg_temp_new();
4884 gen_load_gpr(t1
, rt
);
4885 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
4886 ctx
->default_tcg_memop_mask
);
4890 t1
= tcg_temp_new();
4891 gen_load_gpr(t1
, rt
);
4892 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
4893 ctx
->default_tcg_memop_mask
);
4896 #if defined(TARGET_MIPS64)
4898 t1
= tcg_temp_new();
4899 gen_load_gpr(t1
, rt
);
4900 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4901 ctx
->default_tcg_memop_mask
);
4906 fp0
= tcg_temp_new_i32();
4907 gen_load_fpr32(ctx
, fp0
, rt
);
4908 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
4909 ctx
->default_tcg_memop_mask
);
4910 tcg_temp_free_i32(fp0
);
4912 #if defined(TARGET_MIPS64)
4914 t1
= tcg_temp_new();
4915 gen_load_fpr64(ctx
, t1
, rt
);
4916 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4917 ctx
->default_tcg_memop_mask
);
4929 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
4930 int rs
, int rt
, int16_t imm
)
4933 TCGv t0
= tcg_temp_new();
4934 TCGv t1
= tcg_temp_new();
4937 /* Load needed operands */
4945 /* Compare two registers */
4947 gen_load_gpr(t0
, rs
);
4948 gen_load_gpr(t1
, rt
);
4958 /* Compare register to immediate */
4959 if (rs
!= 0 || imm
!= 0) {
4960 gen_load_gpr(t0
, rs
);
4961 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4968 case OPC_TEQ
: /* rs == rs */
4969 case OPC_TEQI
: /* r0 == 0 */
4970 case OPC_TGE
: /* rs >= rs */
4971 case OPC_TGEI
: /* r0 >= 0 */
4972 case OPC_TGEU
: /* rs >= rs unsigned */
4973 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4975 generate_exception_end(ctx
, EXCP_TRAP
);
4977 case OPC_TLT
: /* rs < rs */
4978 case OPC_TLTI
: /* r0 < 0 */
4979 case OPC_TLTU
: /* rs < rs unsigned */
4980 case OPC_TLTIU
: /* r0 < 0 unsigned */
4981 case OPC_TNE
: /* rs != rs */
4982 case OPC_TNEI
: /* r0 != 0 */
4983 /* Never trap: treat as NOP. */
4987 TCGLabel
*l1
= gen_new_label();
4992 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4996 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5000 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5004 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5008 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5012 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5015 generate_exception(ctx
, EXCP_TRAP
);
5022 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5024 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5028 #ifndef CONFIG_USER_ONLY
5029 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5035 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5037 if (use_goto_tb(ctx
, dest
)) {
5040 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5043 if (ctx
->base
.singlestep_enabled
) {
5044 save_cpu_state(ctx
, 0);
5045 gen_helper_raise_exception_debug(cpu_env
);
5047 tcg_gen_lookup_and_goto_ptr();
5051 /* Branches (before delay slot) */
5052 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5054 int rs
, int rt
, int32_t offset
,
5057 target_ulong btgt
= -1;
5059 int bcond_compute
= 0;
5060 TCGv t0
= tcg_temp_new();
5061 TCGv t1
= tcg_temp_new();
5063 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5064 #ifdef MIPS_DEBUG_DISAS
5065 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5066 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5068 gen_reserved_instruction(ctx
);
5072 /* Load needed operands */
5078 /* Compare two registers */
5080 gen_load_gpr(t0
, rs
);
5081 gen_load_gpr(t1
, rt
);
5084 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5098 /* Compare to zero */
5100 gen_load_gpr(t0
, rs
);
5103 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5106 #if defined(TARGET_MIPS64)
5108 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5110 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5113 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5118 /* Jump to immediate */
5119 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5124 /* Jump to register */
5125 if (offset
!= 0 && offset
!= 16) {
5127 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5128 * others are reserved.
5130 MIPS_INVAL("jump hint");
5131 gen_reserved_instruction(ctx
);
5134 gen_load_gpr(btarget
, rs
);
5137 MIPS_INVAL("branch/jump");
5138 gen_reserved_instruction(ctx
);
5141 if (bcond_compute
== 0) {
5142 /* No condition to be computed */
5144 case OPC_BEQ
: /* rx == rx */
5145 case OPC_BEQL
: /* rx == rx likely */
5146 case OPC_BGEZ
: /* 0 >= 0 */
5147 case OPC_BGEZL
: /* 0 >= 0 likely */
5148 case OPC_BLEZ
: /* 0 <= 0 */
5149 case OPC_BLEZL
: /* 0 <= 0 likely */
5151 ctx
->hflags
|= MIPS_HFLAG_B
;
5153 case OPC_BGEZAL
: /* 0 >= 0 */
5154 case OPC_BGEZALL
: /* 0 >= 0 likely */
5155 /* Always take and link */
5157 ctx
->hflags
|= MIPS_HFLAG_B
;
5159 case OPC_BNE
: /* rx != rx */
5160 case OPC_BGTZ
: /* 0 > 0 */
5161 case OPC_BLTZ
: /* 0 < 0 */
5164 case OPC_BLTZAL
: /* 0 < 0 */
5166 * Handle as an unconditional branch to get correct delay
5170 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5171 ctx
->hflags
|= MIPS_HFLAG_B
;
5173 case OPC_BLTZALL
: /* 0 < 0 likely */
5174 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5175 /* Skip the instruction in the delay slot */
5176 ctx
->base
.pc_next
+= 4;
5178 case OPC_BNEL
: /* rx != rx likely */
5179 case OPC_BGTZL
: /* 0 > 0 likely */
5180 case OPC_BLTZL
: /* 0 < 0 likely */
5181 /* Skip the instruction in the delay slot */
5182 ctx
->base
.pc_next
+= 4;
5185 ctx
->hflags
|= MIPS_HFLAG_B
;
5188 ctx
->hflags
|= MIPS_HFLAG_BX
;
5192 ctx
->hflags
|= MIPS_HFLAG_B
;
5195 ctx
->hflags
|= MIPS_HFLAG_BR
;
5199 ctx
->hflags
|= MIPS_HFLAG_BR
;
5202 MIPS_INVAL("branch/jump");
5203 gen_reserved_instruction(ctx
);
5209 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5212 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5215 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5218 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5221 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5224 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5227 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5231 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5235 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5238 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5241 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5244 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5247 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5250 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5253 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5255 #if defined(TARGET_MIPS64)
5257 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
5261 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5264 ctx
->hflags
|= MIPS_HFLAG_BC
;
5267 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5270 ctx
->hflags
|= MIPS_HFLAG_BL
;
5273 MIPS_INVAL("conditional branch/jump");
5274 gen_reserved_instruction(ctx
);
5279 ctx
->btarget
= btgt
;
5281 switch (delayslot_size
) {
5283 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
5286 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
5291 int post_delay
= insn_bytes
+ delayslot_size
;
5292 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
5294 tcg_gen_movi_tl(cpu_gpr
[blink
],
5295 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
5299 if (insn_bytes
== 2) {
5300 ctx
->hflags
|= MIPS_HFLAG_B16
;
5307 /* nanoMIPS Branches */
5308 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
5310 int rs
, int rt
, int32_t offset
)
5312 target_ulong btgt
= -1;
5313 int bcond_compute
= 0;
5314 TCGv t0
= tcg_temp_new();
5315 TCGv t1
= tcg_temp_new();
5317 /* Load needed operands */
5321 /* Compare two registers */
5323 gen_load_gpr(t0
, rs
);
5324 gen_load_gpr(t1
, rt
);
5327 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5330 /* Compare to zero */
5332 gen_load_gpr(t0
, rs
);
5335 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5338 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5340 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5344 /* Jump to register */
5345 if (offset
!= 0 && offset
!= 16) {
5347 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5348 * others are reserved.
5350 MIPS_INVAL("jump hint");
5351 gen_reserved_instruction(ctx
);
5354 gen_load_gpr(btarget
, rs
);
5357 MIPS_INVAL("branch/jump");
5358 gen_reserved_instruction(ctx
);
5361 if (bcond_compute
== 0) {
5362 /* No condition to be computed */
5364 case OPC_BEQ
: /* rx == rx */
5366 ctx
->hflags
|= MIPS_HFLAG_B
;
5368 case OPC_BGEZAL
: /* 0 >= 0 */
5369 /* Always take and link */
5370 tcg_gen_movi_tl(cpu_gpr
[31],
5371 ctx
->base
.pc_next
+ insn_bytes
);
5372 ctx
->hflags
|= MIPS_HFLAG_B
;
5374 case OPC_BNE
: /* rx != rx */
5375 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5376 /* Skip the instruction in the delay slot */
5377 ctx
->base
.pc_next
+= 4;
5380 ctx
->hflags
|= MIPS_HFLAG_BR
;
5384 tcg_gen_movi_tl(cpu_gpr
[rt
],
5385 ctx
->base
.pc_next
+ insn_bytes
);
5387 ctx
->hflags
|= MIPS_HFLAG_BR
;
5390 MIPS_INVAL("branch/jump");
5391 gen_reserved_instruction(ctx
);
5397 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5400 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5403 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5404 tcg_gen_movi_tl(cpu_gpr
[31],
5405 ctx
->base
.pc_next
+ insn_bytes
);
5408 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5410 ctx
->hflags
|= MIPS_HFLAG_BC
;
5413 MIPS_INVAL("conditional branch/jump");
5414 gen_reserved_instruction(ctx
);
5419 ctx
->btarget
= btgt
;
5422 if (insn_bytes
== 2) {
5423 ctx
->hflags
|= MIPS_HFLAG_B16
;
5430 /* special3 bitfield operations */
5431 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
5432 int rs
, int lsb
, int msb
)
5434 TCGv t0
= tcg_temp_new();
5435 TCGv t1
= tcg_temp_new();
5437 gen_load_gpr(t1
, rs
);
5440 if (lsb
+ msb
> 31) {
5444 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5447 * The two checks together imply that lsb == 0,
5448 * so this is a simple sign-extension.
5450 tcg_gen_ext32s_tl(t0
, t1
);
5453 #if defined(TARGET_MIPS64)
5462 if (lsb
+ msb
> 63) {
5465 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5472 gen_load_gpr(t0
, rt
);
5473 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5474 tcg_gen_ext32s_tl(t0
, t0
);
5476 #if defined(TARGET_MIPS64)
5487 gen_load_gpr(t0
, rt
);
5488 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5493 MIPS_INVAL("bitops");
5494 gen_reserved_instruction(ctx
);
5499 gen_store_gpr(t0
, rt
);
5504 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
5509 /* If no destination, treat it as a NOP. */
5513 t0
= tcg_temp_new();
5514 gen_load_gpr(t0
, rt
);
5518 TCGv t1
= tcg_temp_new();
5519 TCGv t2
= tcg_const_tl(0x00FF00FF);
5521 tcg_gen_shri_tl(t1
, t0
, 8);
5522 tcg_gen_and_tl(t1
, t1
, t2
);
5523 tcg_gen_and_tl(t0
, t0
, t2
);
5524 tcg_gen_shli_tl(t0
, t0
, 8);
5525 tcg_gen_or_tl(t0
, t0
, t1
);
5528 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5532 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
5535 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
5537 #if defined(TARGET_MIPS64)
5540 TCGv t1
= tcg_temp_new();
5541 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
5543 tcg_gen_shri_tl(t1
, t0
, 8);
5544 tcg_gen_and_tl(t1
, t1
, t2
);
5545 tcg_gen_and_tl(t0
, t0
, t2
);
5546 tcg_gen_shli_tl(t0
, t0
, 8);
5547 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5554 TCGv t1
= tcg_temp_new();
5555 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
5557 tcg_gen_shri_tl(t1
, t0
, 16);
5558 tcg_gen_and_tl(t1
, t1
, t2
);
5559 tcg_gen_and_tl(t0
, t0
, t2
);
5560 tcg_gen_shli_tl(t0
, t0
, 16);
5561 tcg_gen_or_tl(t0
, t0
, t1
);
5562 tcg_gen_shri_tl(t1
, t0
, 32);
5563 tcg_gen_shli_tl(t0
, t0
, 32);
5564 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5571 MIPS_INVAL("bsfhl");
5572 gen_reserved_instruction(ctx
);
5579 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
5587 t0
= tcg_temp_new();
5588 if (bits
== 0 || bits
== wordsz
) {
5590 gen_load_gpr(t0
, rt
);
5592 gen_load_gpr(t0
, rs
);
5596 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5598 #if defined(TARGET_MIPS64)
5600 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5605 TCGv t1
= tcg_temp_new();
5606 gen_load_gpr(t0
, rt
);
5607 gen_load_gpr(t1
, rs
);
5611 TCGv_i64 t2
= tcg_temp_new_i64();
5612 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
5613 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
5614 gen_move_low32(cpu_gpr
[rd
], t2
);
5615 tcg_temp_free_i64(t2
);
5618 #if defined(TARGET_MIPS64)
5620 tcg_gen_shli_tl(t0
, t0
, bits
);
5621 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
5622 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
5632 void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
, int bp
)
5634 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5637 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5640 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5643 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
5650 t0
= tcg_temp_new();
5651 gen_load_gpr(t0
, rt
);
5654 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
5656 #if defined(TARGET_MIPS64)
5658 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
5665 #ifndef CONFIG_USER_ONLY
5666 /* CP0 (MMU and control) */
5667 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
5669 TCGv_i64 t0
= tcg_temp_new_i64();
5670 TCGv_i64 t1
= tcg_temp_new_i64();
5672 tcg_gen_ext_tl_i64(t0
, arg
);
5673 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5674 #if defined(TARGET_MIPS64)
5675 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
5677 tcg_gen_concat32_i64(t1
, t1
, t0
);
5679 tcg_gen_st_i64(t1
, cpu_env
, off
);
5680 tcg_temp_free_i64(t1
);
5681 tcg_temp_free_i64(t0
);
5684 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
5686 TCGv_i64 t0
= tcg_temp_new_i64();
5687 TCGv_i64 t1
= tcg_temp_new_i64();
5689 tcg_gen_ext_tl_i64(t0
, arg
);
5690 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5691 tcg_gen_concat32_i64(t1
, t1
, t0
);
5692 tcg_gen_st_i64(t1
, cpu_env
, off
);
5693 tcg_temp_free_i64(t1
);
5694 tcg_temp_free_i64(t0
);
5697 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5699 TCGv_i64 t0
= tcg_temp_new_i64();
5701 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5702 #if defined(TARGET_MIPS64)
5703 tcg_gen_shri_i64(t0
, t0
, 30);
5705 tcg_gen_shri_i64(t0
, t0
, 32);
5707 gen_move_low32(arg
, t0
);
5708 tcg_temp_free_i64(t0
);
5711 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5713 TCGv_i64 t0
= tcg_temp_new_i64();
5715 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5716 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5717 gen_move_low32(arg
, t0
);
5718 tcg_temp_free_i64(t0
);
5721 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
5723 TCGv_i32 t0
= tcg_temp_new_i32();
5725 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5726 tcg_gen_ext_i32_tl(arg
, t0
);
5727 tcg_temp_free_i32(t0
);
5730 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
5732 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5733 tcg_gen_ext32s_tl(arg
, arg
);
5736 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
5738 TCGv_i32 t0
= tcg_temp_new_i32();
5740 tcg_gen_trunc_tl_i32(t0
, arg
);
5741 tcg_gen_st_i32(t0
, cpu_env
, off
);
5742 tcg_temp_free_i32(t0
);
5745 #define CP0_CHECK(c) \
5748 goto cp0_unimplemented; \
5752 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5754 const char *register_name
= "invalid";
5757 case CP0_REGISTER_02
:
5760 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5761 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5762 register_name
= "EntryLo0";
5765 goto cp0_unimplemented
;
5768 case CP0_REGISTER_03
:
5770 case CP0_REG03__ENTRYLO1
:
5771 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5772 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5773 register_name
= "EntryLo1";
5776 goto cp0_unimplemented
;
5779 case CP0_REGISTER_09
:
5781 case CP0_REG09__SAAR
:
5782 CP0_CHECK(ctx
->saar
);
5783 gen_helper_mfhc0_saar(arg
, cpu_env
);
5784 register_name
= "SAAR";
5787 goto cp0_unimplemented
;
5790 case CP0_REGISTER_17
:
5792 case CP0_REG17__LLADDR
:
5793 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
5794 ctx
->CP0_LLAddr_shift
);
5795 register_name
= "LLAddr";
5797 case CP0_REG17__MAAR
:
5798 CP0_CHECK(ctx
->mrp
);
5799 gen_helper_mfhc0_maar(arg
, cpu_env
);
5800 register_name
= "MAAR";
5803 goto cp0_unimplemented
;
5806 case CP0_REGISTER_19
:
5808 case CP0_REG19__WATCHHI0
:
5809 case CP0_REG19__WATCHHI1
:
5810 case CP0_REG19__WATCHHI2
:
5811 case CP0_REG19__WATCHHI3
:
5812 case CP0_REG19__WATCHHI4
:
5813 case CP0_REG19__WATCHHI5
:
5814 case CP0_REG19__WATCHHI6
:
5815 case CP0_REG19__WATCHHI7
:
5816 /* upper 32 bits are only available when Config5MI != 0 */
5818 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
5819 register_name
= "WatchHi";
5822 goto cp0_unimplemented
;
5825 case CP0_REGISTER_28
:
5831 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5832 register_name
= "TagLo";
5835 goto cp0_unimplemented
;
5839 goto cp0_unimplemented
;
5841 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
5845 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
5846 register_name
, reg
, sel
);
5847 tcg_gen_movi_tl(arg
, 0);
5850 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5852 const char *register_name
= "invalid";
5853 uint64_t mask
= ctx
->PAMask
>> 36;
5856 case CP0_REGISTER_02
:
5859 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5860 tcg_gen_andi_tl(arg
, arg
, mask
);
5861 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5862 register_name
= "EntryLo0";
5865 goto cp0_unimplemented
;
5868 case CP0_REGISTER_03
:
5870 case CP0_REG03__ENTRYLO1
:
5871 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5872 tcg_gen_andi_tl(arg
, arg
, mask
);
5873 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5874 register_name
= "EntryLo1";
5877 goto cp0_unimplemented
;
5880 case CP0_REGISTER_09
:
5882 case CP0_REG09__SAAR
:
5883 CP0_CHECK(ctx
->saar
);
5884 gen_helper_mthc0_saar(cpu_env
, arg
);
5885 register_name
= "SAAR";
5888 goto cp0_unimplemented
;
5891 case CP0_REGISTER_17
:
5893 case CP0_REG17__LLADDR
:
5895 * LLAddr is read-only (the only exception is bit 0 if LLB is
5896 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5897 * relevant for modern MIPS cores supporting MTHC0, therefore
5898 * treating MTHC0 to LLAddr as NOP.
5900 register_name
= "LLAddr";
5902 case CP0_REG17__MAAR
:
5903 CP0_CHECK(ctx
->mrp
);
5904 gen_helper_mthc0_maar(cpu_env
, arg
);
5905 register_name
= "MAAR";
5908 goto cp0_unimplemented
;
5911 case CP0_REGISTER_19
:
5913 case CP0_REG19__WATCHHI0
:
5914 case CP0_REG19__WATCHHI1
:
5915 case CP0_REG19__WATCHHI2
:
5916 case CP0_REG19__WATCHHI3
:
5917 case CP0_REG19__WATCHHI4
:
5918 case CP0_REG19__WATCHHI5
:
5919 case CP0_REG19__WATCHHI6
:
5920 case CP0_REG19__WATCHHI7
:
5921 /* upper 32 bits are only available when Config5MI != 0 */
5923 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
5924 register_name
= "WatchHi";
5927 goto cp0_unimplemented
;
5930 case CP0_REGISTER_28
:
5936 tcg_gen_andi_tl(arg
, arg
, mask
);
5937 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5938 register_name
= "TagLo";
5941 goto cp0_unimplemented
;
5945 goto cp0_unimplemented
;
5947 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
5951 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
5952 register_name
, reg
, sel
);
5955 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5957 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
5958 tcg_gen_movi_tl(arg
, 0);
5960 tcg_gen_movi_tl(arg
, ~0);
5964 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5966 const char *register_name
= "invalid";
5969 check_insn(ctx
, ISA_MIPS_R1
);
5973 case CP0_REGISTER_00
:
5975 case CP0_REG00__INDEX
:
5976 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5977 register_name
= "Index";
5979 case CP0_REG00__MVPCONTROL
:
5980 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5981 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5982 register_name
= "MVPControl";
5984 case CP0_REG00__MVPCONF0
:
5985 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5986 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5987 register_name
= "MVPConf0";
5989 case CP0_REG00__MVPCONF1
:
5990 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5991 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5992 register_name
= "MVPConf1";
5994 case CP0_REG00__VPCONTROL
:
5996 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
5997 register_name
= "VPControl";
6000 goto cp0_unimplemented
;
6003 case CP0_REGISTER_01
:
6005 case CP0_REG01__RANDOM
:
6006 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6007 gen_helper_mfc0_random(arg
, cpu_env
);
6008 register_name
= "Random";
6010 case CP0_REG01__VPECONTROL
:
6011 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6012 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6013 register_name
= "VPEControl";
6015 case CP0_REG01__VPECONF0
:
6016 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6017 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6018 register_name
= "VPEConf0";
6020 case CP0_REG01__VPECONF1
:
6021 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6022 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6023 register_name
= "VPEConf1";
6025 case CP0_REG01__YQMASK
:
6026 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6027 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6028 register_name
= "YQMask";
6030 case CP0_REG01__VPESCHEDULE
:
6031 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6032 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6033 register_name
= "VPESchedule";
6035 case CP0_REG01__VPESCHEFBACK
:
6036 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6037 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6038 register_name
= "VPEScheFBack";
6040 case CP0_REG01__VPEOPT
:
6041 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6042 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6043 register_name
= "VPEOpt";
6046 goto cp0_unimplemented
;
6049 case CP0_REGISTER_02
:
6051 case CP0_REG02__ENTRYLO0
:
6053 TCGv_i64 tmp
= tcg_temp_new_i64();
6054 tcg_gen_ld_i64(tmp
, cpu_env
,
6055 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6056 #if defined(TARGET_MIPS64)
6058 /* Move RI/XI fields to bits 31:30 */
6059 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6060 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6063 gen_move_low32(arg
, tmp
);
6064 tcg_temp_free_i64(tmp
);
6066 register_name
= "EntryLo0";
6068 case CP0_REG02__TCSTATUS
:
6069 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6070 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6071 register_name
= "TCStatus";
6073 case CP0_REG02__TCBIND
:
6074 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6075 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6076 register_name
= "TCBind";
6078 case CP0_REG02__TCRESTART
:
6079 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6080 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6081 register_name
= "TCRestart";
6083 case CP0_REG02__TCHALT
:
6084 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6085 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6086 register_name
= "TCHalt";
6088 case CP0_REG02__TCCONTEXT
:
6089 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6090 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6091 register_name
= "TCContext";
6093 case CP0_REG02__TCSCHEDULE
:
6094 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6095 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6096 register_name
= "TCSchedule";
6098 case CP0_REG02__TCSCHEFBACK
:
6099 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6100 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6101 register_name
= "TCScheFBack";
6104 goto cp0_unimplemented
;
6107 case CP0_REGISTER_03
:
6109 case CP0_REG03__ENTRYLO1
:
6111 TCGv_i64 tmp
= tcg_temp_new_i64();
6112 tcg_gen_ld_i64(tmp
, cpu_env
,
6113 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6114 #if defined(TARGET_MIPS64)
6116 /* Move RI/XI fields to bits 31:30 */
6117 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6118 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6121 gen_move_low32(arg
, tmp
);
6122 tcg_temp_free_i64(tmp
);
6124 register_name
= "EntryLo1";
6126 case CP0_REG03__GLOBALNUM
:
6128 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6129 register_name
= "GlobalNumber";
6132 goto cp0_unimplemented
;
6135 case CP0_REGISTER_04
:
6137 case CP0_REG04__CONTEXT
:
6138 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6139 tcg_gen_ext32s_tl(arg
, arg
);
6140 register_name
= "Context";
6142 case CP0_REG04__CONTEXTCONFIG
:
6144 /* gen_helper_mfc0_contextconfig(arg); */
6145 register_name
= "ContextConfig";
6146 goto cp0_unimplemented
;
6147 case CP0_REG04__USERLOCAL
:
6148 CP0_CHECK(ctx
->ulri
);
6149 tcg_gen_ld_tl(arg
, cpu_env
,
6150 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6151 tcg_gen_ext32s_tl(arg
, arg
);
6152 register_name
= "UserLocal";
6154 case CP0_REG04__MMID
:
6156 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6157 register_name
= "MMID";
6160 goto cp0_unimplemented
;
6163 case CP0_REGISTER_05
:
6165 case CP0_REG05__PAGEMASK
:
6166 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6167 register_name
= "PageMask";
6169 case CP0_REG05__PAGEGRAIN
:
6170 check_insn(ctx
, ISA_MIPS_R2
);
6171 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6172 register_name
= "PageGrain";
6174 case CP0_REG05__SEGCTL0
:
6176 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6177 tcg_gen_ext32s_tl(arg
, arg
);
6178 register_name
= "SegCtl0";
6180 case CP0_REG05__SEGCTL1
:
6182 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6183 tcg_gen_ext32s_tl(arg
, arg
);
6184 register_name
= "SegCtl1";
6186 case CP0_REG05__SEGCTL2
:
6188 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6189 tcg_gen_ext32s_tl(arg
, arg
);
6190 register_name
= "SegCtl2";
6192 case CP0_REG05__PWBASE
:
6194 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6195 register_name
= "PWBase";
6197 case CP0_REG05__PWFIELD
:
6199 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6200 register_name
= "PWField";
6202 case CP0_REG05__PWSIZE
:
6204 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6205 register_name
= "PWSize";
6208 goto cp0_unimplemented
;
6211 case CP0_REGISTER_06
:
6213 case CP0_REG06__WIRED
:
6214 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6215 register_name
= "Wired";
6217 case CP0_REG06__SRSCONF0
:
6218 check_insn(ctx
, ISA_MIPS_R2
);
6219 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6220 register_name
= "SRSConf0";
6222 case CP0_REG06__SRSCONF1
:
6223 check_insn(ctx
, ISA_MIPS_R2
);
6224 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6225 register_name
= "SRSConf1";
6227 case CP0_REG06__SRSCONF2
:
6228 check_insn(ctx
, ISA_MIPS_R2
);
6229 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6230 register_name
= "SRSConf2";
6232 case CP0_REG06__SRSCONF3
:
6233 check_insn(ctx
, ISA_MIPS_R2
);
6234 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6235 register_name
= "SRSConf3";
6237 case CP0_REG06__SRSCONF4
:
6238 check_insn(ctx
, ISA_MIPS_R2
);
6239 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6240 register_name
= "SRSConf4";
6242 case CP0_REG06__PWCTL
:
6244 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6245 register_name
= "PWCtl";
6248 goto cp0_unimplemented
;
6251 case CP0_REGISTER_07
:
6253 case CP0_REG07__HWRENA
:
6254 check_insn(ctx
, ISA_MIPS_R2
);
6255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6256 register_name
= "HWREna";
6259 goto cp0_unimplemented
;
6262 case CP0_REGISTER_08
:
6264 case CP0_REG08__BADVADDR
:
6265 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6266 tcg_gen_ext32s_tl(arg
, arg
);
6267 register_name
= "BadVAddr";
6269 case CP0_REG08__BADINSTR
:
6271 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6272 register_name
= "BadInstr";
6274 case CP0_REG08__BADINSTRP
:
6276 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6277 register_name
= "BadInstrP";
6279 case CP0_REG08__BADINSTRX
:
6281 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6282 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6283 register_name
= "BadInstrX";
6286 goto cp0_unimplemented
;
6289 case CP0_REGISTER_09
:
6291 case CP0_REG09__COUNT
:
6292 /* Mark as an IO operation because we read the time. */
6293 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6296 gen_helper_mfc0_count(arg
, cpu_env
);
6298 * Break the TB to be able to take timer interrupts immediately
6299 * after reading count. DISAS_STOP isn't sufficient, we need to
6300 * ensure we break completely out of translated code.
6302 gen_save_pc(ctx
->base
.pc_next
+ 4);
6303 ctx
->base
.is_jmp
= DISAS_EXIT
;
6304 register_name
= "Count";
6306 case CP0_REG09__SAARI
:
6307 CP0_CHECK(ctx
->saar
);
6308 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6309 register_name
= "SAARI";
6311 case CP0_REG09__SAAR
:
6312 CP0_CHECK(ctx
->saar
);
6313 gen_helper_mfc0_saar(arg
, cpu_env
);
6314 register_name
= "SAAR";
6317 goto cp0_unimplemented
;
6320 case CP0_REGISTER_10
:
6322 case CP0_REG10__ENTRYHI
:
6323 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6324 tcg_gen_ext32s_tl(arg
, arg
);
6325 register_name
= "EntryHi";
6328 goto cp0_unimplemented
;
6331 case CP0_REGISTER_11
:
6333 case CP0_REG11__COMPARE
:
6334 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6335 register_name
= "Compare";
6337 /* 6,7 are implementation dependent */
6339 goto cp0_unimplemented
;
6342 case CP0_REGISTER_12
:
6344 case CP0_REG12__STATUS
:
6345 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6346 register_name
= "Status";
6348 case CP0_REG12__INTCTL
:
6349 check_insn(ctx
, ISA_MIPS_R2
);
6350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6351 register_name
= "IntCtl";
6353 case CP0_REG12__SRSCTL
:
6354 check_insn(ctx
, ISA_MIPS_R2
);
6355 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6356 register_name
= "SRSCtl";
6358 case CP0_REG12__SRSMAP
:
6359 check_insn(ctx
, ISA_MIPS_R2
);
6360 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6361 register_name
= "SRSMap";
6364 goto cp0_unimplemented
;
6367 case CP0_REGISTER_13
:
6369 case CP0_REG13__CAUSE
:
6370 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6371 register_name
= "Cause";
6374 goto cp0_unimplemented
;
6377 case CP0_REGISTER_14
:
6379 case CP0_REG14__EPC
:
6380 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6381 tcg_gen_ext32s_tl(arg
, arg
);
6382 register_name
= "EPC";
6385 goto cp0_unimplemented
;
6388 case CP0_REGISTER_15
:
6390 case CP0_REG15__PRID
:
6391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6392 register_name
= "PRid";
6394 case CP0_REG15__EBASE
:
6395 check_insn(ctx
, ISA_MIPS_R2
);
6396 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6397 tcg_gen_ext32s_tl(arg
, arg
);
6398 register_name
= "EBase";
6400 case CP0_REG15__CMGCRBASE
:
6401 check_insn(ctx
, ISA_MIPS_R2
);
6402 CP0_CHECK(ctx
->cmgcr
);
6403 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6404 tcg_gen_ext32s_tl(arg
, arg
);
6405 register_name
= "CMGCRBase";
6408 goto cp0_unimplemented
;
6411 case CP0_REGISTER_16
:
6413 case CP0_REG16__CONFIG
:
6414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6415 register_name
= "Config";
6417 case CP0_REG16__CONFIG1
:
6418 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6419 register_name
= "Config1";
6421 case CP0_REG16__CONFIG2
:
6422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6423 register_name
= "Config2";
6425 case CP0_REG16__CONFIG3
:
6426 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6427 register_name
= "Config3";
6429 case CP0_REG16__CONFIG4
:
6430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6431 register_name
= "Config4";
6433 case CP0_REG16__CONFIG5
:
6434 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6435 register_name
= "Config5";
6437 /* 6,7 are implementation dependent */
6438 case CP0_REG16__CONFIG6
:
6439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6440 register_name
= "Config6";
6442 case CP0_REG16__CONFIG7
:
6443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6444 register_name
= "Config7";
6447 goto cp0_unimplemented
;
6450 case CP0_REGISTER_17
:
6452 case CP0_REG17__LLADDR
:
6453 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6454 register_name
= "LLAddr";
6456 case CP0_REG17__MAAR
:
6457 CP0_CHECK(ctx
->mrp
);
6458 gen_helper_mfc0_maar(arg
, cpu_env
);
6459 register_name
= "MAAR";
6461 case CP0_REG17__MAARI
:
6462 CP0_CHECK(ctx
->mrp
);
6463 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6464 register_name
= "MAARI";
6467 goto cp0_unimplemented
;
6470 case CP0_REGISTER_18
:
6472 case CP0_REG18__WATCHLO0
:
6473 case CP0_REG18__WATCHLO1
:
6474 case CP0_REG18__WATCHLO2
:
6475 case CP0_REG18__WATCHLO3
:
6476 case CP0_REG18__WATCHLO4
:
6477 case CP0_REG18__WATCHLO5
:
6478 case CP0_REG18__WATCHLO6
:
6479 case CP0_REG18__WATCHLO7
:
6480 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6481 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6482 register_name
= "WatchLo";
6485 goto cp0_unimplemented
;
6488 case CP0_REGISTER_19
:
6490 case CP0_REG19__WATCHHI0
:
6491 case CP0_REG19__WATCHHI1
:
6492 case CP0_REG19__WATCHHI2
:
6493 case CP0_REG19__WATCHHI3
:
6494 case CP0_REG19__WATCHHI4
:
6495 case CP0_REG19__WATCHHI5
:
6496 case CP0_REG19__WATCHHI6
:
6497 case CP0_REG19__WATCHHI7
:
6498 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6499 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6500 register_name
= "WatchHi";
6503 goto cp0_unimplemented
;
6506 case CP0_REGISTER_20
:
6508 case CP0_REG20__XCONTEXT
:
6509 #if defined(TARGET_MIPS64)
6510 check_insn(ctx
, ISA_MIPS3
);
6511 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6512 tcg_gen_ext32s_tl(arg
, arg
);
6513 register_name
= "XContext";
6517 goto cp0_unimplemented
;
6520 case CP0_REGISTER_21
:
6521 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6522 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6525 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6526 register_name
= "Framemask";
6529 goto cp0_unimplemented
;
6532 case CP0_REGISTER_22
:
6533 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6534 register_name
= "'Diagnostic"; /* implementation dependent */
6536 case CP0_REGISTER_23
:
6538 case CP0_REG23__DEBUG
:
6539 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6540 register_name
= "Debug";
6542 case CP0_REG23__TRACECONTROL
:
6543 /* PDtrace support */
6544 /* gen_helper_mfc0_tracecontrol(arg); */
6545 register_name
= "TraceControl";
6546 goto cp0_unimplemented
;
6547 case CP0_REG23__TRACECONTROL2
:
6548 /* PDtrace support */
6549 /* gen_helper_mfc0_tracecontrol2(arg); */
6550 register_name
= "TraceControl2";
6551 goto cp0_unimplemented
;
6552 case CP0_REG23__USERTRACEDATA1
:
6553 /* PDtrace support */
6554 /* gen_helper_mfc0_usertracedata1(arg);*/
6555 register_name
= "UserTraceData1";
6556 goto cp0_unimplemented
;
6557 case CP0_REG23__TRACEIBPC
:
6558 /* PDtrace support */
6559 /* gen_helper_mfc0_traceibpc(arg); */
6560 register_name
= "TraceIBPC";
6561 goto cp0_unimplemented
;
6562 case CP0_REG23__TRACEDBPC
:
6563 /* PDtrace support */
6564 /* gen_helper_mfc0_tracedbpc(arg); */
6565 register_name
= "TraceDBPC";
6566 goto cp0_unimplemented
;
6568 goto cp0_unimplemented
;
6571 case CP0_REGISTER_24
:
6573 case CP0_REG24__DEPC
:
6575 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6576 tcg_gen_ext32s_tl(arg
, arg
);
6577 register_name
= "DEPC";
6580 goto cp0_unimplemented
;
6583 case CP0_REGISTER_25
:
6585 case CP0_REG25__PERFCTL0
:
6586 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6587 register_name
= "Performance0";
6589 case CP0_REG25__PERFCNT0
:
6590 /* gen_helper_mfc0_performance1(arg); */
6591 register_name
= "Performance1";
6592 goto cp0_unimplemented
;
6593 case CP0_REG25__PERFCTL1
:
6594 /* gen_helper_mfc0_performance2(arg); */
6595 register_name
= "Performance2";
6596 goto cp0_unimplemented
;
6597 case CP0_REG25__PERFCNT1
:
6598 /* gen_helper_mfc0_performance3(arg); */
6599 register_name
= "Performance3";
6600 goto cp0_unimplemented
;
6601 case CP0_REG25__PERFCTL2
:
6602 /* gen_helper_mfc0_performance4(arg); */
6603 register_name
= "Performance4";
6604 goto cp0_unimplemented
;
6605 case CP0_REG25__PERFCNT2
:
6606 /* gen_helper_mfc0_performance5(arg); */
6607 register_name
= "Performance5";
6608 goto cp0_unimplemented
;
6609 case CP0_REG25__PERFCTL3
:
6610 /* gen_helper_mfc0_performance6(arg); */
6611 register_name
= "Performance6";
6612 goto cp0_unimplemented
;
6613 case CP0_REG25__PERFCNT3
:
6614 /* gen_helper_mfc0_performance7(arg); */
6615 register_name
= "Performance7";
6616 goto cp0_unimplemented
;
6618 goto cp0_unimplemented
;
6621 case CP0_REGISTER_26
:
6623 case CP0_REG26__ERRCTL
:
6624 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6625 register_name
= "ErrCtl";
6628 goto cp0_unimplemented
;
6631 case CP0_REGISTER_27
:
6633 case CP0_REG27__CACHERR
:
6634 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6635 register_name
= "CacheErr";
6638 goto cp0_unimplemented
;
6641 case CP0_REGISTER_28
:
6643 case CP0_REG28__TAGLO
:
6644 case CP0_REG28__TAGLO1
:
6645 case CP0_REG28__TAGLO2
:
6646 case CP0_REG28__TAGLO3
:
6648 TCGv_i64 tmp
= tcg_temp_new_i64();
6649 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
6650 gen_move_low32(arg
, tmp
);
6651 tcg_temp_free_i64(tmp
);
6653 register_name
= "TagLo";
6655 case CP0_REG28__DATALO
:
6656 case CP0_REG28__DATALO1
:
6657 case CP0_REG28__DATALO2
:
6658 case CP0_REG28__DATALO3
:
6659 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6660 register_name
= "DataLo";
6663 goto cp0_unimplemented
;
6666 case CP0_REGISTER_29
:
6668 case CP0_REG29__TAGHI
:
6669 case CP0_REG29__TAGHI1
:
6670 case CP0_REG29__TAGHI2
:
6671 case CP0_REG29__TAGHI3
:
6672 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6673 register_name
= "TagHi";
6675 case CP0_REG29__DATAHI
:
6676 case CP0_REG29__DATAHI1
:
6677 case CP0_REG29__DATAHI2
:
6678 case CP0_REG29__DATAHI3
:
6679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6680 register_name
= "DataHi";
6683 goto cp0_unimplemented
;
6686 case CP0_REGISTER_30
:
6688 case CP0_REG30__ERROREPC
:
6689 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6690 tcg_gen_ext32s_tl(arg
, arg
);
6691 register_name
= "ErrorEPC";
6694 goto cp0_unimplemented
;
6697 case CP0_REGISTER_31
:
6699 case CP0_REG31__DESAVE
:
6701 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6702 register_name
= "DESAVE";
6704 case CP0_REG31__KSCRATCH1
:
6705 case CP0_REG31__KSCRATCH2
:
6706 case CP0_REG31__KSCRATCH3
:
6707 case CP0_REG31__KSCRATCH4
:
6708 case CP0_REG31__KSCRATCH5
:
6709 case CP0_REG31__KSCRATCH6
:
6710 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6711 tcg_gen_ld_tl(arg
, cpu_env
,
6712 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
6713 tcg_gen_ext32s_tl(arg
, arg
);
6714 register_name
= "KScratch";
6717 goto cp0_unimplemented
;
6721 goto cp0_unimplemented
;
6723 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
6727 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
6728 register_name
, reg
, sel
);
6729 gen_mfc0_unimplemented(ctx
, arg
);
6732 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6734 const char *register_name
= "invalid";
6737 check_insn(ctx
, ISA_MIPS_R1
);
6740 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6745 case CP0_REGISTER_00
:
6747 case CP0_REG00__INDEX
:
6748 gen_helper_mtc0_index(cpu_env
, arg
);
6749 register_name
= "Index";
6751 case CP0_REG00__MVPCONTROL
:
6752 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6753 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6754 register_name
= "MVPControl";
6756 case CP0_REG00__MVPCONF0
:
6757 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6759 register_name
= "MVPConf0";
6761 case CP0_REG00__MVPCONF1
:
6762 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6764 register_name
= "MVPConf1";
6766 case CP0_REG00__VPCONTROL
:
6769 register_name
= "VPControl";
6772 goto cp0_unimplemented
;
6775 case CP0_REGISTER_01
:
6777 case CP0_REG01__RANDOM
:
6779 register_name
= "Random";
6781 case CP0_REG01__VPECONTROL
:
6782 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6783 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6784 register_name
= "VPEControl";
6786 case CP0_REG01__VPECONF0
:
6787 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6788 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6789 register_name
= "VPEConf0";
6791 case CP0_REG01__VPECONF1
:
6792 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6793 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6794 register_name
= "VPEConf1";
6796 case CP0_REG01__YQMASK
:
6797 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6798 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6799 register_name
= "YQMask";
6801 case CP0_REG01__VPESCHEDULE
:
6802 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6803 tcg_gen_st_tl(arg
, cpu_env
,
6804 offsetof(CPUMIPSState
, CP0_VPESchedule
));
6805 register_name
= "VPESchedule";
6807 case CP0_REG01__VPESCHEFBACK
:
6808 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6809 tcg_gen_st_tl(arg
, cpu_env
,
6810 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6811 register_name
= "VPEScheFBack";
6813 case CP0_REG01__VPEOPT
:
6814 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6815 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6816 register_name
= "VPEOpt";
6819 goto cp0_unimplemented
;
6822 case CP0_REGISTER_02
:
6824 case CP0_REG02__ENTRYLO0
:
6825 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6826 register_name
= "EntryLo0";
6828 case CP0_REG02__TCSTATUS
:
6829 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6830 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6831 register_name
= "TCStatus";
6833 case CP0_REG02__TCBIND
:
6834 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6835 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6836 register_name
= "TCBind";
6838 case CP0_REG02__TCRESTART
:
6839 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6840 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6841 register_name
= "TCRestart";
6843 case CP0_REG02__TCHALT
:
6844 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6845 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6846 register_name
= "TCHalt";
6848 case CP0_REG02__TCCONTEXT
:
6849 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6850 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6851 register_name
= "TCContext";
6853 case CP0_REG02__TCSCHEDULE
:
6854 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6855 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6856 register_name
= "TCSchedule";
6858 case CP0_REG02__TCSCHEFBACK
:
6859 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6860 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6861 register_name
= "TCScheFBack";
6864 goto cp0_unimplemented
;
6867 case CP0_REGISTER_03
:
6869 case CP0_REG03__ENTRYLO1
:
6870 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6871 register_name
= "EntryLo1";
6873 case CP0_REG03__GLOBALNUM
:
6876 register_name
= "GlobalNumber";
6879 goto cp0_unimplemented
;
6882 case CP0_REGISTER_04
:
6884 case CP0_REG04__CONTEXT
:
6885 gen_helper_mtc0_context(cpu_env
, arg
);
6886 register_name
= "Context";
6888 case CP0_REG04__CONTEXTCONFIG
:
6890 /* gen_helper_mtc0_contextconfig(arg); */
6891 register_name
= "ContextConfig";
6892 goto cp0_unimplemented
;
6893 case CP0_REG04__USERLOCAL
:
6894 CP0_CHECK(ctx
->ulri
);
6895 tcg_gen_st_tl(arg
, cpu_env
,
6896 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6897 register_name
= "UserLocal";
6899 case CP0_REG04__MMID
:
6901 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
6902 register_name
= "MMID";
6905 goto cp0_unimplemented
;
6908 case CP0_REGISTER_05
:
6910 case CP0_REG05__PAGEMASK
:
6911 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6912 register_name
= "PageMask";
6914 case CP0_REG05__PAGEGRAIN
:
6915 check_insn(ctx
, ISA_MIPS_R2
);
6916 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6917 register_name
= "PageGrain";
6918 ctx
->base
.is_jmp
= DISAS_STOP
;
6920 case CP0_REG05__SEGCTL0
:
6922 gen_helper_mtc0_segctl0(cpu_env
, arg
);
6923 register_name
= "SegCtl0";
6925 case CP0_REG05__SEGCTL1
:
6927 gen_helper_mtc0_segctl1(cpu_env
, arg
);
6928 register_name
= "SegCtl1";
6930 case CP0_REG05__SEGCTL2
:
6932 gen_helper_mtc0_segctl2(cpu_env
, arg
);
6933 register_name
= "SegCtl2";
6935 case CP0_REG05__PWBASE
:
6937 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6938 register_name
= "PWBase";
6940 case CP0_REG05__PWFIELD
:
6942 gen_helper_mtc0_pwfield(cpu_env
, arg
);
6943 register_name
= "PWField";
6945 case CP0_REG05__PWSIZE
:
6947 gen_helper_mtc0_pwsize(cpu_env
, arg
);
6948 register_name
= "PWSize";
6951 goto cp0_unimplemented
;
6954 case CP0_REGISTER_06
:
6956 case CP0_REG06__WIRED
:
6957 gen_helper_mtc0_wired(cpu_env
, arg
);
6958 register_name
= "Wired";
6960 case CP0_REG06__SRSCONF0
:
6961 check_insn(ctx
, ISA_MIPS_R2
);
6962 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6963 register_name
= "SRSConf0";
6965 case CP0_REG06__SRSCONF1
:
6966 check_insn(ctx
, ISA_MIPS_R2
);
6967 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6968 register_name
= "SRSConf1";
6970 case CP0_REG06__SRSCONF2
:
6971 check_insn(ctx
, ISA_MIPS_R2
);
6972 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6973 register_name
= "SRSConf2";
6975 case CP0_REG06__SRSCONF3
:
6976 check_insn(ctx
, ISA_MIPS_R2
);
6977 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6978 register_name
= "SRSConf3";
6980 case CP0_REG06__SRSCONF4
:
6981 check_insn(ctx
, ISA_MIPS_R2
);
6982 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6983 register_name
= "SRSConf4";
6985 case CP0_REG06__PWCTL
:
6987 gen_helper_mtc0_pwctl(cpu_env
, arg
);
6988 register_name
= "PWCtl";
6991 goto cp0_unimplemented
;
6994 case CP0_REGISTER_07
:
6996 case CP0_REG07__HWRENA
:
6997 check_insn(ctx
, ISA_MIPS_R2
);
6998 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6999 ctx
->base
.is_jmp
= DISAS_STOP
;
7000 register_name
= "HWREna";
7003 goto cp0_unimplemented
;
7006 case CP0_REGISTER_08
:
7008 case CP0_REG08__BADVADDR
:
7010 register_name
= "BadVAddr";
7012 case CP0_REG08__BADINSTR
:
7014 register_name
= "BadInstr";
7016 case CP0_REG08__BADINSTRP
:
7018 register_name
= "BadInstrP";
7020 case CP0_REG08__BADINSTRX
:
7022 register_name
= "BadInstrX";
7025 goto cp0_unimplemented
;
7028 case CP0_REGISTER_09
:
7030 case CP0_REG09__COUNT
:
7031 gen_helper_mtc0_count(cpu_env
, arg
);
7032 register_name
= "Count";
7034 case CP0_REG09__SAARI
:
7035 CP0_CHECK(ctx
->saar
);
7036 gen_helper_mtc0_saari(cpu_env
, arg
);
7037 register_name
= "SAARI";
7039 case CP0_REG09__SAAR
:
7040 CP0_CHECK(ctx
->saar
);
7041 gen_helper_mtc0_saar(cpu_env
, arg
);
7042 register_name
= "SAAR";
7045 goto cp0_unimplemented
;
7048 case CP0_REGISTER_10
:
7050 case CP0_REG10__ENTRYHI
:
7051 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7052 register_name
= "EntryHi";
7055 goto cp0_unimplemented
;
7058 case CP0_REGISTER_11
:
7060 case CP0_REG11__COMPARE
:
7061 gen_helper_mtc0_compare(cpu_env
, arg
);
7062 register_name
= "Compare";
7064 /* 6,7 are implementation dependent */
7066 goto cp0_unimplemented
;
7069 case CP0_REGISTER_12
:
7071 case CP0_REG12__STATUS
:
7072 save_cpu_state(ctx
, 1);
7073 gen_helper_mtc0_status(cpu_env
, arg
);
7074 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7075 gen_save_pc(ctx
->base
.pc_next
+ 4);
7076 ctx
->base
.is_jmp
= DISAS_EXIT
;
7077 register_name
= "Status";
7079 case CP0_REG12__INTCTL
:
7080 check_insn(ctx
, ISA_MIPS_R2
);
7081 gen_helper_mtc0_intctl(cpu_env
, arg
);
7082 /* Stop translation as we may have switched the execution mode */
7083 ctx
->base
.is_jmp
= DISAS_STOP
;
7084 register_name
= "IntCtl";
7086 case CP0_REG12__SRSCTL
:
7087 check_insn(ctx
, ISA_MIPS_R2
);
7088 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7089 /* Stop translation as we may have switched the execution mode */
7090 ctx
->base
.is_jmp
= DISAS_STOP
;
7091 register_name
= "SRSCtl";
7093 case CP0_REG12__SRSMAP
:
7094 check_insn(ctx
, ISA_MIPS_R2
);
7095 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7096 /* Stop translation as we may have switched the execution mode */
7097 ctx
->base
.is_jmp
= DISAS_STOP
;
7098 register_name
= "SRSMap";
7101 goto cp0_unimplemented
;
7104 case CP0_REGISTER_13
:
7106 case CP0_REG13__CAUSE
:
7107 save_cpu_state(ctx
, 1);
7108 gen_helper_mtc0_cause(cpu_env
, arg
);
7110 * Stop translation as we may have triggered an interrupt.
7111 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7112 * translated code to check for pending interrupts.
7114 gen_save_pc(ctx
->base
.pc_next
+ 4);
7115 ctx
->base
.is_jmp
= DISAS_EXIT
;
7116 register_name
= "Cause";
7119 goto cp0_unimplemented
;
7122 case CP0_REGISTER_14
:
7124 case CP0_REG14__EPC
:
7125 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7126 register_name
= "EPC";
7129 goto cp0_unimplemented
;
7132 case CP0_REGISTER_15
:
7134 case CP0_REG15__PRID
:
7136 register_name
= "PRid";
7138 case CP0_REG15__EBASE
:
7139 check_insn(ctx
, ISA_MIPS_R2
);
7140 gen_helper_mtc0_ebase(cpu_env
, arg
);
7141 register_name
= "EBase";
7144 goto cp0_unimplemented
;
7147 case CP0_REGISTER_16
:
7149 case CP0_REG16__CONFIG
:
7150 gen_helper_mtc0_config0(cpu_env
, arg
);
7151 register_name
= "Config";
7152 /* Stop translation as we may have switched the execution mode */
7153 ctx
->base
.is_jmp
= DISAS_STOP
;
7155 case CP0_REG16__CONFIG1
:
7156 /* ignored, read only */
7157 register_name
= "Config1";
7159 case CP0_REG16__CONFIG2
:
7160 gen_helper_mtc0_config2(cpu_env
, arg
);
7161 register_name
= "Config2";
7162 /* Stop translation as we may have switched the execution mode */
7163 ctx
->base
.is_jmp
= DISAS_STOP
;
7165 case CP0_REG16__CONFIG3
:
7166 gen_helper_mtc0_config3(cpu_env
, arg
);
7167 register_name
= "Config3";
7168 /* Stop translation as we may have switched the execution mode */
7169 ctx
->base
.is_jmp
= DISAS_STOP
;
7171 case CP0_REG16__CONFIG4
:
7172 gen_helper_mtc0_config4(cpu_env
, arg
);
7173 register_name
= "Config4";
7174 ctx
->base
.is_jmp
= DISAS_STOP
;
7176 case CP0_REG16__CONFIG5
:
7177 gen_helper_mtc0_config5(cpu_env
, arg
);
7178 register_name
= "Config5";
7179 /* Stop translation as we may have switched the execution mode */
7180 ctx
->base
.is_jmp
= DISAS_STOP
;
7182 /* 6,7 are implementation dependent */
7183 case CP0_REG16__CONFIG6
:
7185 register_name
= "Config6";
7187 case CP0_REG16__CONFIG7
:
7189 register_name
= "Config7";
7192 register_name
= "Invalid config selector";
7193 goto cp0_unimplemented
;
7196 case CP0_REGISTER_17
:
7198 case CP0_REG17__LLADDR
:
7199 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7200 register_name
= "LLAddr";
7202 case CP0_REG17__MAAR
:
7203 CP0_CHECK(ctx
->mrp
);
7204 gen_helper_mtc0_maar(cpu_env
, arg
);
7205 register_name
= "MAAR";
7207 case CP0_REG17__MAARI
:
7208 CP0_CHECK(ctx
->mrp
);
7209 gen_helper_mtc0_maari(cpu_env
, arg
);
7210 register_name
= "MAARI";
7213 goto cp0_unimplemented
;
7216 case CP0_REGISTER_18
:
7218 case CP0_REG18__WATCHLO0
:
7219 case CP0_REG18__WATCHLO1
:
7220 case CP0_REG18__WATCHLO2
:
7221 case CP0_REG18__WATCHLO3
:
7222 case CP0_REG18__WATCHLO4
:
7223 case CP0_REG18__WATCHLO5
:
7224 case CP0_REG18__WATCHLO6
:
7225 case CP0_REG18__WATCHLO7
:
7226 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7227 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7228 register_name
= "WatchLo";
7231 goto cp0_unimplemented
;
7234 case CP0_REGISTER_19
:
7236 case CP0_REG19__WATCHHI0
:
7237 case CP0_REG19__WATCHHI1
:
7238 case CP0_REG19__WATCHHI2
:
7239 case CP0_REG19__WATCHHI3
:
7240 case CP0_REG19__WATCHHI4
:
7241 case CP0_REG19__WATCHHI5
:
7242 case CP0_REG19__WATCHHI6
:
7243 case CP0_REG19__WATCHHI7
:
7244 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7245 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7246 register_name
= "WatchHi";
7249 goto cp0_unimplemented
;
7252 case CP0_REGISTER_20
:
7254 case CP0_REG20__XCONTEXT
:
7255 #if defined(TARGET_MIPS64)
7256 check_insn(ctx
, ISA_MIPS3
);
7257 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7258 register_name
= "XContext";
7262 goto cp0_unimplemented
;
7265 case CP0_REGISTER_21
:
7266 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7267 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7270 gen_helper_mtc0_framemask(cpu_env
, arg
);
7271 register_name
= "Framemask";
7274 goto cp0_unimplemented
;
7277 case CP0_REGISTER_22
:
7279 register_name
= "Diagnostic"; /* implementation dependent */
7281 case CP0_REGISTER_23
:
7283 case CP0_REG23__DEBUG
:
7284 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7285 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7286 gen_save_pc(ctx
->base
.pc_next
+ 4);
7287 ctx
->base
.is_jmp
= DISAS_EXIT
;
7288 register_name
= "Debug";
7290 case CP0_REG23__TRACECONTROL
:
7291 /* PDtrace support */
7292 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7293 register_name
= "TraceControl";
7294 /* Stop translation as we may have switched the execution mode */
7295 ctx
->base
.is_jmp
= DISAS_STOP
;
7296 goto cp0_unimplemented
;
7297 case CP0_REG23__TRACECONTROL2
:
7298 /* PDtrace support */
7299 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7300 register_name
= "TraceControl2";
7301 /* Stop translation as we may have switched the execution mode */
7302 ctx
->base
.is_jmp
= DISAS_STOP
;
7303 goto cp0_unimplemented
;
7304 case CP0_REG23__USERTRACEDATA1
:
7305 /* Stop translation as we may have switched the execution mode */
7306 ctx
->base
.is_jmp
= DISAS_STOP
;
7307 /* PDtrace support */
7308 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7309 register_name
= "UserTraceData";
7310 /* Stop translation as we may have switched the execution mode */
7311 ctx
->base
.is_jmp
= DISAS_STOP
;
7312 goto cp0_unimplemented
;
7313 case CP0_REG23__TRACEIBPC
:
7314 /* PDtrace support */
7315 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7316 /* Stop translation as we may have switched the execution mode */
7317 ctx
->base
.is_jmp
= DISAS_STOP
;
7318 register_name
= "TraceIBPC";
7319 goto cp0_unimplemented
;
7320 case CP0_REG23__TRACEDBPC
:
7321 /* PDtrace support */
7322 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7323 /* Stop translation as we may have switched the execution mode */
7324 ctx
->base
.is_jmp
= DISAS_STOP
;
7325 register_name
= "TraceDBPC";
7326 goto cp0_unimplemented
;
7328 goto cp0_unimplemented
;
7331 case CP0_REGISTER_24
:
7333 case CP0_REG24__DEPC
:
7335 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7336 register_name
= "DEPC";
7339 goto cp0_unimplemented
;
7342 case CP0_REGISTER_25
:
7344 case CP0_REG25__PERFCTL0
:
7345 gen_helper_mtc0_performance0(cpu_env
, arg
);
7346 register_name
= "Performance0";
7348 case CP0_REG25__PERFCNT0
:
7349 /* gen_helper_mtc0_performance1(arg); */
7350 register_name
= "Performance1";
7351 goto cp0_unimplemented
;
7352 case CP0_REG25__PERFCTL1
:
7353 /* gen_helper_mtc0_performance2(arg); */
7354 register_name
= "Performance2";
7355 goto cp0_unimplemented
;
7356 case CP0_REG25__PERFCNT1
:
7357 /* gen_helper_mtc0_performance3(arg); */
7358 register_name
= "Performance3";
7359 goto cp0_unimplemented
;
7360 case CP0_REG25__PERFCTL2
:
7361 /* gen_helper_mtc0_performance4(arg); */
7362 register_name
= "Performance4";
7363 goto cp0_unimplemented
;
7364 case CP0_REG25__PERFCNT2
:
7365 /* gen_helper_mtc0_performance5(arg); */
7366 register_name
= "Performance5";
7367 goto cp0_unimplemented
;
7368 case CP0_REG25__PERFCTL3
:
7369 /* gen_helper_mtc0_performance6(arg); */
7370 register_name
= "Performance6";
7371 goto cp0_unimplemented
;
7372 case CP0_REG25__PERFCNT3
:
7373 /* gen_helper_mtc0_performance7(arg); */
7374 register_name
= "Performance7";
7375 goto cp0_unimplemented
;
7377 goto cp0_unimplemented
;
7380 case CP0_REGISTER_26
:
7382 case CP0_REG26__ERRCTL
:
7383 gen_helper_mtc0_errctl(cpu_env
, arg
);
7384 ctx
->base
.is_jmp
= DISAS_STOP
;
7385 register_name
= "ErrCtl";
7388 goto cp0_unimplemented
;
7391 case CP0_REGISTER_27
:
7393 case CP0_REG27__CACHERR
:
7395 register_name
= "CacheErr";
7398 goto cp0_unimplemented
;
7401 case CP0_REGISTER_28
:
7403 case CP0_REG28__TAGLO
:
7404 case CP0_REG28__TAGLO1
:
7405 case CP0_REG28__TAGLO2
:
7406 case CP0_REG28__TAGLO3
:
7407 gen_helper_mtc0_taglo(cpu_env
, arg
);
7408 register_name
= "TagLo";
7410 case CP0_REG28__DATALO
:
7411 case CP0_REG28__DATALO1
:
7412 case CP0_REG28__DATALO2
:
7413 case CP0_REG28__DATALO3
:
7414 gen_helper_mtc0_datalo(cpu_env
, arg
);
7415 register_name
= "DataLo";
7418 goto cp0_unimplemented
;
7421 case CP0_REGISTER_29
:
7423 case CP0_REG29__TAGHI
:
7424 case CP0_REG29__TAGHI1
:
7425 case CP0_REG29__TAGHI2
:
7426 case CP0_REG29__TAGHI3
:
7427 gen_helper_mtc0_taghi(cpu_env
, arg
);
7428 register_name
= "TagHi";
7430 case CP0_REG29__DATAHI
:
7431 case CP0_REG29__DATAHI1
:
7432 case CP0_REG29__DATAHI2
:
7433 case CP0_REG29__DATAHI3
:
7434 gen_helper_mtc0_datahi(cpu_env
, arg
);
7435 register_name
= "DataHi";
7438 register_name
= "invalid sel";
7439 goto cp0_unimplemented
;
7442 case CP0_REGISTER_30
:
7444 case CP0_REG30__ERROREPC
:
7445 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7446 register_name
= "ErrorEPC";
7449 goto cp0_unimplemented
;
7452 case CP0_REGISTER_31
:
7454 case CP0_REG31__DESAVE
:
7456 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7457 register_name
= "DESAVE";
7459 case CP0_REG31__KSCRATCH1
:
7460 case CP0_REG31__KSCRATCH2
:
7461 case CP0_REG31__KSCRATCH3
:
7462 case CP0_REG31__KSCRATCH4
:
7463 case CP0_REG31__KSCRATCH5
:
7464 case CP0_REG31__KSCRATCH6
:
7465 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7466 tcg_gen_st_tl(arg
, cpu_env
,
7467 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7468 register_name
= "KScratch";
7471 goto cp0_unimplemented
;
7475 goto cp0_unimplemented
;
7477 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7479 /* For simplicity assume that all writes can cause interrupts. */
7480 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7482 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7483 * translated code to check for pending interrupts.
7485 gen_save_pc(ctx
->base
.pc_next
+ 4);
7486 ctx
->base
.is_jmp
= DISAS_EXIT
;
7491 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7492 register_name
, reg
, sel
);
7495 #if defined(TARGET_MIPS64)
7496 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7498 const char *register_name
= "invalid";
7501 check_insn(ctx
, ISA_MIPS_R1
);
7505 case CP0_REGISTER_00
:
7507 case CP0_REG00__INDEX
:
7508 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7509 register_name
= "Index";
7511 case CP0_REG00__MVPCONTROL
:
7512 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7513 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7514 register_name
= "MVPControl";
7516 case CP0_REG00__MVPCONF0
:
7517 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7518 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7519 register_name
= "MVPConf0";
7521 case CP0_REG00__MVPCONF1
:
7522 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7523 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7524 register_name
= "MVPConf1";
7526 case CP0_REG00__VPCONTROL
:
7528 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7529 register_name
= "VPControl";
7532 goto cp0_unimplemented
;
7535 case CP0_REGISTER_01
:
7537 case CP0_REG01__RANDOM
:
7538 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7539 gen_helper_mfc0_random(arg
, cpu_env
);
7540 register_name
= "Random";
7542 case CP0_REG01__VPECONTROL
:
7543 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7544 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7545 register_name
= "VPEControl";
7547 case CP0_REG01__VPECONF0
:
7548 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7549 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7550 register_name
= "VPEConf0";
7552 case CP0_REG01__VPECONF1
:
7553 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7554 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7555 register_name
= "VPEConf1";
7557 case CP0_REG01__YQMASK
:
7558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7559 tcg_gen_ld_tl(arg
, cpu_env
,
7560 offsetof(CPUMIPSState
, CP0_YQMask
));
7561 register_name
= "YQMask";
7563 case CP0_REG01__VPESCHEDULE
:
7564 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7565 tcg_gen_ld_tl(arg
, cpu_env
,
7566 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7567 register_name
= "VPESchedule";
7569 case CP0_REG01__VPESCHEFBACK
:
7570 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7571 tcg_gen_ld_tl(arg
, cpu_env
,
7572 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7573 register_name
= "VPEScheFBack";
7575 case CP0_REG01__VPEOPT
:
7576 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7577 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7578 register_name
= "VPEOpt";
7581 goto cp0_unimplemented
;
7584 case CP0_REGISTER_02
:
7586 case CP0_REG02__ENTRYLO0
:
7587 tcg_gen_ld_tl(arg
, cpu_env
,
7588 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7589 register_name
= "EntryLo0";
7591 case CP0_REG02__TCSTATUS
:
7592 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7593 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7594 register_name
= "TCStatus";
7596 case CP0_REG02__TCBIND
:
7597 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7598 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7599 register_name
= "TCBind";
7601 case CP0_REG02__TCRESTART
:
7602 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7603 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7604 register_name
= "TCRestart";
7606 case CP0_REG02__TCHALT
:
7607 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7608 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7609 register_name
= "TCHalt";
7611 case CP0_REG02__TCCONTEXT
:
7612 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7613 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7614 register_name
= "TCContext";
7616 case CP0_REG02__TCSCHEDULE
:
7617 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7618 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7619 register_name
= "TCSchedule";
7621 case CP0_REG02__TCSCHEFBACK
:
7622 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7623 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7624 register_name
= "TCScheFBack";
7627 goto cp0_unimplemented
;
7630 case CP0_REGISTER_03
:
7632 case CP0_REG03__ENTRYLO1
:
7633 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7634 register_name
= "EntryLo1";
7636 case CP0_REG03__GLOBALNUM
:
7638 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7639 register_name
= "GlobalNumber";
7642 goto cp0_unimplemented
;
7645 case CP0_REGISTER_04
:
7647 case CP0_REG04__CONTEXT
:
7648 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7649 register_name
= "Context";
7651 case CP0_REG04__CONTEXTCONFIG
:
7653 /* gen_helper_dmfc0_contextconfig(arg); */
7654 register_name
= "ContextConfig";
7655 goto cp0_unimplemented
;
7656 case CP0_REG04__USERLOCAL
:
7657 CP0_CHECK(ctx
->ulri
);
7658 tcg_gen_ld_tl(arg
, cpu_env
,
7659 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7660 register_name
= "UserLocal";
7662 case CP0_REG04__MMID
:
7664 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7665 register_name
= "MMID";
7668 goto cp0_unimplemented
;
7671 case CP0_REGISTER_05
:
7673 case CP0_REG05__PAGEMASK
:
7674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7675 register_name
= "PageMask";
7677 case CP0_REG05__PAGEGRAIN
:
7678 check_insn(ctx
, ISA_MIPS_R2
);
7679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7680 register_name
= "PageGrain";
7682 case CP0_REG05__SEGCTL0
:
7684 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7685 register_name
= "SegCtl0";
7687 case CP0_REG05__SEGCTL1
:
7689 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7690 register_name
= "SegCtl1";
7692 case CP0_REG05__SEGCTL2
:
7694 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7695 register_name
= "SegCtl2";
7697 case CP0_REG05__PWBASE
:
7699 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
7700 register_name
= "PWBase";
7702 case CP0_REG05__PWFIELD
:
7704 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
7705 register_name
= "PWField";
7707 case CP0_REG05__PWSIZE
:
7709 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
7710 register_name
= "PWSize";
7713 goto cp0_unimplemented
;
7716 case CP0_REGISTER_06
:
7718 case CP0_REG06__WIRED
:
7719 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7720 register_name
= "Wired";
7722 case CP0_REG06__SRSCONF0
:
7723 check_insn(ctx
, ISA_MIPS_R2
);
7724 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7725 register_name
= "SRSConf0";
7727 case CP0_REG06__SRSCONF1
:
7728 check_insn(ctx
, ISA_MIPS_R2
);
7729 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7730 register_name
= "SRSConf1";
7732 case CP0_REG06__SRSCONF2
:
7733 check_insn(ctx
, ISA_MIPS_R2
);
7734 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7735 register_name
= "SRSConf2";
7737 case CP0_REG06__SRSCONF3
:
7738 check_insn(ctx
, ISA_MIPS_R2
);
7739 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7740 register_name
= "SRSConf3";
7742 case CP0_REG06__SRSCONF4
:
7743 check_insn(ctx
, ISA_MIPS_R2
);
7744 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7745 register_name
= "SRSConf4";
7747 case CP0_REG06__PWCTL
:
7749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7750 register_name
= "PWCtl";
7753 goto cp0_unimplemented
;
7756 case CP0_REGISTER_07
:
7758 case CP0_REG07__HWRENA
:
7759 check_insn(ctx
, ISA_MIPS_R2
);
7760 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7761 register_name
= "HWREna";
7764 goto cp0_unimplemented
;
7767 case CP0_REGISTER_08
:
7769 case CP0_REG08__BADVADDR
:
7770 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7771 register_name
= "BadVAddr";
7773 case CP0_REG08__BADINSTR
:
7775 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7776 register_name
= "BadInstr";
7778 case CP0_REG08__BADINSTRP
:
7780 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7781 register_name
= "BadInstrP";
7783 case CP0_REG08__BADINSTRX
:
7785 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7786 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7787 register_name
= "BadInstrX";
7790 goto cp0_unimplemented
;
7793 case CP0_REGISTER_09
:
7795 case CP0_REG09__COUNT
:
7796 /* Mark as an IO operation because we read the time. */
7797 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7800 gen_helper_mfc0_count(arg
, cpu_env
);
7802 * Break the TB to be able to take timer interrupts immediately
7803 * after reading count. DISAS_STOP isn't sufficient, we need to
7804 * ensure we break completely out of translated code.
7806 gen_save_pc(ctx
->base
.pc_next
+ 4);
7807 ctx
->base
.is_jmp
= DISAS_EXIT
;
7808 register_name
= "Count";
7810 case CP0_REG09__SAARI
:
7811 CP0_CHECK(ctx
->saar
);
7812 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7813 register_name
= "SAARI";
7815 case CP0_REG09__SAAR
:
7816 CP0_CHECK(ctx
->saar
);
7817 gen_helper_dmfc0_saar(arg
, cpu_env
);
7818 register_name
= "SAAR";
7821 goto cp0_unimplemented
;
7824 case CP0_REGISTER_10
:
7826 case CP0_REG10__ENTRYHI
:
7827 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7828 register_name
= "EntryHi";
7831 goto cp0_unimplemented
;
7834 case CP0_REGISTER_11
:
7836 case CP0_REG11__COMPARE
:
7837 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7838 register_name
= "Compare";
7840 /* 6,7 are implementation dependent */
7842 goto cp0_unimplemented
;
7845 case CP0_REGISTER_12
:
7847 case CP0_REG12__STATUS
:
7848 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7849 register_name
= "Status";
7851 case CP0_REG12__INTCTL
:
7852 check_insn(ctx
, ISA_MIPS_R2
);
7853 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7854 register_name
= "IntCtl";
7856 case CP0_REG12__SRSCTL
:
7857 check_insn(ctx
, ISA_MIPS_R2
);
7858 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7859 register_name
= "SRSCtl";
7861 case CP0_REG12__SRSMAP
:
7862 check_insn(ctx
, ISA_MIPS_R2
);
7863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7864 register_name
= "SRSMap";
7867 goto cp0_unimplemented
;
7870 case CP0_REGISTER_13
:
7872 case CP0_REG13__CAUSE
:
7873 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7874 register_name
= "Cause";
7877 goto cp0_unimplemented
;
7880 case CP0_REGISTER_14
:
7882 case CP0_REG14__EPC
:
7883 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7884 register_name
= "EPC";
7887 goto cp0_unimplemented
;
7890 case CP0_REGISTER_15
:
7892 case CP0_REG15__PRID
:
7893 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7894 register_name
= "PRid";
7896 case CP0_REG15__EBASE
:
7897 check_insn(ctx
, ISA_MIPS_R2
);
7898 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7899 register_name
= "EBase";
7901 case CP0_REG15__CMGCRBASE
:
7902 check_insn(ctx
, ISA_MIPS_R2
);
7903 CP0_CHECK(ctx
->cmgcr
);
7904 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7905 register_name
= "CMGCRBase";
7908 goto cp0_unimplemented
;
7911 case CP0_REGISTER_16
:
7913 case CP0_REG16__CONFIG
:
7914 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7915 register_name
= "Config";
7917 case CP0_REG16__CONFIG1
:
7918 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7919 register_name
= "Config1";
7921 case CP0_REG16__CONFIG2
:
7922 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7923 register_name
= "Config2";
7925 case CP0_REG16__CONFIG3
:
7926 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7927 register_name
= "Config3";
7929 case CP0_REG16__CONFIG4
:
7930 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7931 register_name
= "Config4";
7933 case CP0_REG16__CONFIG5
:
7934 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7935 register_name
= "Config5";
7937 /* 6,7 are implementation dependent */
7938 case CP0_REG16__CONFIG6
:
7939 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7940 register_name
= "Config6";
7942 case CP0_REG16__CONFIG7
:
7943 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7944 register_name
= "Config7";
7947 goto cp0_unimplemented
;
7950 case CP0_REGISTER_17
:
7952 case CP0_REG17__LLADDR
:
7953 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
7954 register_name
= "LLAddr";
7956 case CP0_REG17__MAAR
:
7957 CP0_CHECK(ctx
->mrp
);
7958 gen_helper_dmfc0_maar(arg
, cpu_env
);
7959 register_name
= "MAAR";
7961 case CP0_REG17__MAARI
:
7962 CP0_CHECK(ctx
->mrp
);
7963 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7964 register_name
= "MAARI";
7967 goto cp0_unimplemented
;
7970 case CP0_REGISTER_18
:
7972 case CP0_REG18__WATCHLO0
:
7973 case CP0_REG18__WATCHLO1
:
7974 case CP0_REG18__WATCHLO2
:
7975 case CP0_REG18__WATCHLO3
:
7976 case CP0_REG18__WATCHLO4
:
7977 case CP0_REG18__WATCHLO5
:
7978 case CP0_REG18__WATCHLO6
:
7979 case CP0_REG18__WATCHLO7
:
7980 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7981 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
7982 register_name
= "WatchLo";
7985 goto cp0_unimplemented
;
7988 case CP0_REGISTER_19
:
7990 case CP0_REG19__WATCHHI0
:
7991 case CP0_REG19__WATCHHI1
:
7992 case CP0_REG19__WATCHHI2
:
7993 case CP0_REG19__WATCHHI3
:
7994 case CP0_REG19__WATCHHI4
:
7995 case CP0_REG19__WATCHHI5
:
7996 case CP0_REG19__WATCHHI6
:
7997 case CP0_REG19__WATCHHI7
:
7998 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7999 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8000 register_name
= "WatchHi";
8003 goto cp0_unimplemented
;
8006 case CP0_REGISTER_20
:
8008 case CP0_REG20__XCONTEXT
:
8009 check_insn(ctx
, ISA_MIPS3
);
8010 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8011 register_name
= "XContext";
8014 goto cp0_unimplemented
;
8017 case CP0_REGISTER_21
:
8018 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8019 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8022 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8023 register_name
= "Framemask";
8026 goto cp0_unimplemented
;
8029 case CP0_REGISTER_22
:
8030 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8031 register_name
= "'Diagnostic"; /* implementation dependent */
8033 case CP0_REGISTER_23
:
8035 case CP0_REG23__DEBUG
:
8036 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8037 register_name
= "Debug";
8039 case CP0_REG23__TRACECONTROL
:
8040 /* PDtrace support */
8041 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8042 register_name
= "TraceControl";
8043 goto cp0_unimplemented
;
8044 case CP0_REG23__TRACECONTROL2
:
8045 /* PDtrace support */
8046 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8047 register_name
= "TraceControl2";
8048 goto cp0_unimplemented
;
8049 case CP0_REG23__USERTRACEDATA1
:
8050 /* PDtrace support */
8051 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8052 register_name
= "UserTraceData1";
8053 goto cp0_unimplemented
;
8054 case CP0_REG23__TRACEIBPC
:
8055 /* PDtrace support */
8056 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8057 register_name
= "TraceIBPC";
8058 goto cp0_unimplemented
;
8059 case CP0_REG23__TRACEDBPC
:
8060 /* PDtrace support */
8061 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8062 register_name
= "TraceDBPC";
8063 goto cp0_unimplemented
;
8065 goto cp0_unimplemented
;
8068 case CP0_REGISTER_24
:
8070 case CP0_REG24__DEPC
:
8072 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8073 register_name
= "DEPC";
8076 goto cp0_unimplemented
;
8079 case CP0_REGISTER_25
:
8081 case CP0_REG25__PERFCTL0
:
8082 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8083 register_name
= "Performance0";
8085 case CP0_REG25__PERFCNT0
:
8086 /* gen_helper_dmfc0_performance1(arg); */
8087 register_name
= "Performance1";
8088 goto cp0_unimplemented
;
8089 case CP0_REG25__PERFCTL1
:
8090 /* gen_helper_dmfc0_performance2(arg); */
8091 register_name
= "Performance2";
8092 goto cp0_unimplemented
;
8093 case CP0_REG25__PERFCNT1
:
8094 /* gen_helper_dmfc0_performance3(arg); */
8095 register_name
= "Performance3";
8096 goto cp0_unimplemented
;
8097 case CP0_REG25__PERFCTL2
:
8098 /* gen_helper_dmfc0_performance4(arg); */
8099 register_name
= "Performance4";
8100 goto cp0_unimplemented
;
8101 case CP0_REG25__PERFCNT2
:
8102 /* gen_helper_dmfc0_performance5(arg); */
8103 register_name
= "Performance5";
8104 goto cp0_unimplemented
;
8105 case CP0_REG25__PERFCTL3
:
8106 /* gen_helper_dmfc0_performance6(arg); */
8107 register_name
= "Performance6";
8108 goto cp0_unimplemented
;
8109 case CP0_REG25__PERFCNT3
:
8110 /* gen_helper_dmfc0_performance7(arg); */
8111 register_name
= "Performance7";
8112 goto cp0_unimplemented
;
8114 goto cp0_unimplemented
;
8117 case CP0_REGISTER_26
:
8119 case CP0_REG26__ERRCTL
:
8120 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8121 register_name
= "ErrCtl";
8124 goto cp0_unimplemented
;
8127 case CP0_REGISTER_27
:
8130 case CP0_REG27__CACHERR
:
8131 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8132 register_name
= "CacheErr";
8135 goto cp0_unimplemented
;
8138 case CP0_REGISTER_28
:
8140 case CP0_REG28__TAGLO
:
8141 case CP0_REG28__TAGLO1
:
8142 case CP0_REG28__TAGLO2
:
8143 case CP0_REG28__TAGLO3
:
8144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8145 register_name
= "TagLo";
8147 case CP0_REG28__DATALO
:
8148 case CP0_REG28__DATALO1
:
8149 case CP0_REG28__DATALO2
:
8150 case CP0_REG28__DATALO3
:
8151 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8152 register_name
= "DataLo";
8155 goto cp0_unimplemented
;
8158 case CP0_REGISTER_29
:
8160 case CP0_REG29__TAGHI
:
8161 case CP0_REG29__TAGHI1
:
8162 case CP0_REG29__TAGHI2
:
8163 case CP0_REG29__TAGHI3
:
8164 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8165 register_name
= "TagHi";
8167 case CP0_REG29__DATAHI
:
8168 case CP0_REG29__DATAHI1
:
8169 case CP0_REG29__DATAHI2
:
8170 case CP0_REG29__DATAHI3
:
8171 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8172 register_name
= "DataHi";
8175 goto cp0_unimplemented
;
8178 case CP0_REGISTER_30
:
8180 case CP0_REG30__ERROREPC
:
8181 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8182 register_name
= "ErrorEPC";
8185 goto cp0_unimplemented
;
8188 case CP0_REGISTER_31
:
8190 case CP0_REG31__DESAVE
:
8192 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8193 register_name
= "DESAVE";
8195 case CP0_REG31__KSCRATCH1
:
8196 case CP0_REG31__KSCRATCH2
:
8197 case CP0_REG31__KSCRATCH3
:
8198 case CP0_REG31__KSCRATCH4
:
8199 case CP0_REG31__KSCRATCH5
:
8200 case CP0_REG31__KSCRATCH6
:
8201 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8202 tcg_gen_ld_tl(arg
, cpu_env
,
8203 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8204 register_name
= "KScratch";
8207 goto cp0_unimplemented
;
8211 goto cp0_unimplemented
;
8213 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8217 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8218 register_name
, reg
, sel
);
8219 gen_mfc0_unimplemented(ctx
, arg
);
8222 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8224 const char *register_name
= "invalid";
8227 check_insn(ctx
, ISA_MIPS_R1
);
8230 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8235 case CP0_REGISTER_00
:
8237 case CP0_REG00__INDEX
:
8238 gen_helper_mtc0_index(cpu_env
, arg
);
8239 register_name
= "Index";
8241 case CP0_REG00__MVPCONTROL
:
8242 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8243 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8244 register_name
= "MVPControl";
8246 case CP0_REG00__MVPCONF0
:
8247 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8249 register_name
= "MVPConf0";
8251 case CP0_REG00__MVPCONF1
:
8252 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8254 register_name
= "MVPConf1";
8256 case CP0_REG00__VPCONTROL
:
8259 register_name
= "VPControl";
8262 goto cp0_unimplemented
;
8265 case CP0_REGISTER_01
:
8267 case CP0_REG01__RANDOM
:
8269 register_name
= "Random";
8271 case CP0_REG01__VPECONTROL
:
8272 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8273 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8274 register_name
= "VPEControl";
8276 case CP0_REG01__VPECONF0
:
8277 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8278 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8279 register_name
= "VPEConf0";
8281 case CP0_REG01__VPECONF1
:
8282 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8283 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8284 register_name
= "VPEConf1";
8286 case CP0_REG01__YQMASK
:
8287 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8288 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8289 register_name
= "YQMask";
8291 case CP0_REG01__VPESCHEDULE
:
8292 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8293 tcg_gen_st_tl(arg
, cpu_env
,
8294 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8295 register_name
= "VPESchedule";
8297 case CP0_REG01__VPESCHEFBACK
:
8298 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8299 tcg_gen_st_tl(arg
, cpu_env
,
8300 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8301 register_name
= "VPEScheFBack";
8303 case CP0_REG01__VPEOPT
:
8304 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8305 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8306 register_name
= "VPEOpt";
8309 goto cp0_unimplemented
;
8312 case CP0_REGISTER_02
:
8314 case CP0_REG02__ENTRYLO0
:
8315 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8316 register_name
= "EntryLo0";
8318 case CP0_REG02__TCSTATUS
:
8319 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8320 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8321 register_name
= "TCStatus";
8323 case CP0_REG02__TCBIND
:
8324 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8325 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8326 register_name
= "TCBind";
8328 case CP0_REG02__TCRESTART
:
8329 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8330 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8331 register_name
= "TCRestart";
8333 case CP0_REG02__TCHALT
:
8334 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8335 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8336 register_name
= "TCHalt";
8338 case CP0_REG02__TCCONTEXT
:
8339 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8340 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8341 register_name
= "TCContext";
8343 case CP0_REG02__TCSCHEDULE
:
8344 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8345 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8346 register_name
= "TCSchedule";
8348 case CP0_REG02__TCSCHEFBACK
:
8349 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8350 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8351 register_name
= "TCScheFBack";
8354 goto cp0_unimplemented
;
8357 case CP0_REGISTER_03
:
8359 case CP0_REG03__ENTRYLO1
:
8360 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8361 register_name
= "EntryLo1";
8363 case CP0_REG03__GLOBALNUM
:
8366 register_name
= "GlobalNumber";
8369 goto cp0_unimplemented
;
8372 case CP0_REGISTER_04
:
8374 case CP0_REG04__CONTEXT
:
8375 gen_helper_mtc0_context(cpu_env
, arg
);
8376 register_name
= "Context";
8378 case CP0_REG04__CONTEXTCONFIG
:
8380 /* gen_helper_dmtc0_contextconfig(arg); */
8381 register_name
= "ContextConfig";
8382 goto cp0_unimplemented
;
8383 case CP0_REG04__USERLOCAL
:
8384 CP0_CHECK(ctx
->ulri
);
8385 tcg_gen_st_tl(arg
, cpu_env
,
8386 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8387 register_name
= "UserLocal";
8389 case CP0_REG04__MMID
:
8391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8392 register_name
= "MMID";
8395 goto cp0_unimplemented
;
8398 case CP0_REGISTER_05
:
8400 case CP0_REG05__PAGEMASK
:
8401 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8402 register_name
= "PageMask";
8404 case CP0_REG05__PAGEGRAIN
:
8405 check_insn(ctx
, ISA_MIPS_R2
);
8406 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8407 register_name
= "PageGrain";
8409 case CP0_REG05__SEGCTL0
:
8411 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8412 register_name
= "SegCtl0";
8414 case CP0_REG05__SEGCTL1
:
8416 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8417 register_name
= "SegCtl1";
8419 case CP0_REG05__SEGCTL2
:
8421 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8422 register_name
= "SegCtl2";
8424 case CP0_REG05__PWBASE
:
8426 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8427 register_name
= "PWBase";
8429 case CP0_REG05__PWFIELD
:
8431 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8432 register_name
= "PWField";
8434 case CP0_REG05__PWSIZE
:
8436 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8437 register_name
= "PWSize";
8440 goto cp0_unimplemented
;
8443 case CP0_REGISTER_06
:
8445 case CP0_REG06__WIRED
:
8446 gen_helper_mtc0_wired(cpu_env
, arg
);
8447 register_name
= "Wired";
8449 case CP0_REG06__SRSCONF0
:
8450 check_insn(ctx
, ISA_MIPS_R2
);
8451 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8452 register_name
= "SRSConf0";
8454 case CP0_REG06__SRSCONF1
:
8455 check_insn(ctx
, ISA_MIPS_R2
);
8456 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8457 register_name
= "SRSConf1";
8459 case CP0_REG06__SRSCONF2
:
8460 check_insn(ctx
, ISA_MIPS_R2
);
8461 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8462 register_name
= "SRSConf2";
8464 case CP0_REG06__SRSCONF3
:
8465 check_insn(ctx
, ISA_MIPS_R2
);
8466 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8467 register_name
= "SRSConf3";
8469 case CP0_REG06__SRSCONF4
:
8470 check_insn(ctx
, ISA_MIPS_R2
);
8471 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8472 register_name
= "SRSConf4";
8474 case CP0_REG06__PWCTL
:
8476 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8477 register_name
= "PWCtl";
8480 goto cp0_unimplemented
;
8483 case CP0_REGISTER_07
:
8485 case CP0_REG07__HWRENA
:
8486 check_insn(ctx
, ISA_MIPS_R2
);
8487 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8488 ctx
->base
.is_jmp
= DISAS_STOP
;
8489 register_name
= "HWREna";
8492 goto cp0_unimplemented
;
8495 case CP0_REGISTER_08
:
8497 case CP0_REG08__BADVADDR
:
8499 register_name
= "BadVAddr";
8501 case CP0_REG08__BADINSTR
:
8503 register_name
= "BadInstr";
8505 case CP0_REG08__BADINSTRP
:
8507 register_name
= "BadInstrP";
8509 case CP0_REG08__BADINSTRX
:
8511 register_name
= "BadInstrX";
8514 goto cp0_unimplemented
;
8517 case CP0_REGISTER_09
:
8519 case CP0_REG09__COUNT
:
8520 gen_helper_mtc0_count(cpu_env
, arg
);
8521 register_name
= "Count";
8523 case CP0_REG09__SAARI
:
8524 CP0_CHECK(ctx
->saar
);
8525 gen_helper_mtc0_saari(cpu_env
, arg
);
8526 register_name
= "SAARI";
8528 case CP0_REG09__SAAR
:
8529 CP0_CHECK(ctx
->saar
);
8530 gen_helper_mtc0_saar(cpu_env
, arg
);
8531 register_name
= "SAAR";
8534 goto cp0_unimplemented
;
8536 /* Stop translation as we may have switched the execution mode */
8537 ctx
->base
.is_jmp
= DISAS_STOP
;
8539 case CP0_REGISTER_10
:
8541 case CP0_REG10__ENTRYHI
:
8542 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8543 register_name
= "EntryHi";
8546 goto cp0_unimplemented
;
8549 case CP0_REGISTER_11
:
8551 case CP0_REG11__COMPARE
:
8552 gen_helper_mtc0_compare(cpu_env
, arg
);
8553 register_name
= "Compare";
8555 /* 6,7 are implementation dependent */
8557 goto cp0_unimplemented
;
8559 /* Stop translation as we may have switched the execution mode */
8560 ctx
->base
.is_jmp
= DISAS_STOP
;
8562 case CP0_REGISTER_12
:
8564 case CP0_REG12__STATUS
:
8565 save_cpu_state(ctx
, 1);
8566 gen_helper_mtc0_status(cpu_env
, arg
);
8567 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8568 gen_save_pc(ctx
->base
.pc_next
+ 4);
8569 ctx
->base
.is_jmp
= DISAS_EXIT
;
8570 register_name
= "Status";
8572 case CP0_REG12__INTCTL
:
8573 check_insn(ctx
, ISA_MIPS_R2
);
8574 gen_helper_mtc0_intctl(cpu_env
, arg
);
8575 /* Stop translation as we may have switched the execution mode */
8576 ctx
->base
.is_jmp
= DISAS_STOP
;
8577 register_name
= "IntCtl";
8579 case CP0_REG12__SRSCTL
:
8580 check_insn(ctx
, ISA_MIPS_R2
);
8581 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8582 /* Stop translation as we may have switched the execution mode */
8583 ctx
->base
.is_jmp
= DISAS_STOP
;
8584 register_name
= "SRSCtl";
8586 case CP0_REG12__SRSMAP
:
8587 check_insn(ctx
, ISA_MIPS_R2
);
8588 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8589 /* Stop translation as we may have switched the execution mode */
8590 ctx
->base
.is_jmp
= DISAS_STOP
;
8591 register_name
= "SRSMap";
8594 goto cp0_unimplemented
;
8597 case CP0_REGISTER_13
:
8599 case CP0_REG13__CAUSE
:
8600 save_cpu_state(ctx
, 1);
8601 gen_helper_mtc0_cause(cpu_env
, arg
);
8603 * Stop translation as we may have triggered an interrupt.
8604 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8605 * translated code to check for pending interrupts.
8607 gen_save_pc(ctx
->base
.pc_next
+ 4);
8608 ctx
->base
.is_jmp
= DISAS_EXIT
;
8609 register_name
= "Cause";
8612 goto cp0_unimplemented
;
8615 case CP0_REGISTER_14
:
8617 case CP0_REG14__EPC
:
8618 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8619 register_name
= "EPC";
8622 goto cp0_unimplemented
;
8625 case CP0_REGISTER_15
:
8627 case CP0_REG15__PRID
:
8629 register_name
= "PRid";
8631 case CP0_REG15__EBASE
:
8632 check_insn(ctx
, ISA_MIPS_R2
);
8633 gen_helper_mtc0_ebase(cpu_env
, arg
);
8634 register_name
= "EBase";
8637 goto cp0_unimplemented
;
8640 case CP0_REGISTER_16
:
8642 case CP0_REG16__CONFIG
:
8643 gen_helper_mtc0_config0(cpu_env
, arg
);
8644 register_name
= "Config";
8645 /* Stop translation as we may have switched the execution mode */
8646 ctx
->base
.is_jmp
= DISAS_STOP
;
8648 case CP0_REG16__CONFIG1
:
8649 /* ignored, read only */
8650 register_name
= "Config1";
8652 case CP0_REG16__CONFIG2
:
8653 gen_helper_mtc0_config2(cpu_env
, arg
);
8654 register_name
= "Config2";
8655 /* Stop translation as we may have switched the execution mode */
8656 ctx
->base
.is_jmp
= DISAS_STOP
;
8658 case CP0_REG16__CONFIG3
:
8659 gen_helper_mtc0_config3(cpu_env
, arg
);
8660 register_name
= "Config3";
8661 /* Stop translation as we may have switched the execution mode */
8662 ctx
->base
.is_jmp
= DISAS_STOP
;
8664 case CP0_REG16__CONFIG4
:
8665 /* currently ignored */
8666 register_name
= "Config4";
8668 case CP0_REG16__CONFIG5
:
8669 gen_helper_mtc0_config5(cpu_env
, arg
);
8670 register_name
= "Config5";
8671 /* Stop translation as we may have switched the execution mode */
8672 ctx
->base
.is_jmp
= DISAS_STOP
;
8674 /* 6,7 are implementation dependent */
8676 register_name
= "Invalid config selector";
8677 goto cp0_unimplemented
;
8680 case CP0_REGISTER_17
:
8682 case CP0_REG17__LLADDR
:
8683 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8684 register_name
= "LLAddr";
8686 case CP0_REG17__MAAR
:
8687 CP0_CHECK(ctx
->mrp
);
8688 gen_helper_mtc0_maar(cpu_env
, arg
);
8689 register_name
= "MAAR";
8691 case CP0_REG17__MAARI
:
8692 CP0_CHECK(ctx
->mrp
);
8693 gen_helper_mtc0_maari(cpu_env
, arg
);
8694 register_name
= "MAARI";
8697 goto cp0_unimplemented
;
8700 case CP0_REGISTER_18
:
8702 case CP0_REG18__WATCHLO0
:
8703 case CP0_REG18__WATCHLO1
:
8704 case CP0_REG18__WATCHLO2
:
8705 case CP0_REG18__WATCHLO3
:
8706 case CP0_REG18__WATCHLO4
:
8707 case CP0_REG18__WATCHLO5
:
8708 case CP0_REG18__WATCHLO6
:
8709 case CP0_REG18__WATCHLO7
:
8710 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8711 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8712 register_name
= "WatchLo";
8715 goto cp0_unimplemented
;
8718 case CP0_REGISTER_19
:
8720 case CP0_REG19__WATCHHI0
:
8721 case CP0_REG19__WATCHHI1
:
8722 case CP0_REG19__WATCHHI2
:
8723 case CP0_REG19__WATCHHI3
:
8724 case CP0_REG19__WATCHHI4
:
8725 case CP0_REG19__WATCHHI5
:
8726 case CP0_REG19__WATCHHI6
:
8727 case CP0_REG19__WATCHHI7
:
8728 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8729 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8730 register_name
= "WatchHi";
8733 goto cp0_unimplemented
;
8736 case CP0_REGISTER_20
:
8738 case CP0_REG20__XCONTEXT
:
8739 check_insn(ctx
, ISA_MIPS3
);
8740 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8741 register_name
= "XContext";
8744 goto cp0_unimplemented
;
8747 case CP0_REGISTER_21
:
8748 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8749 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8752 gen_helper_mtc0_framemask(cpu_env
, arg
);
8753 register_name
= "Framemask";
8756 goto cp0_unimplemented
;
8759 case CP0_REGISTER_22
:
8761 register_name
= "Diagnostic"; /* implementation dependent */
8763 case CP0_REGISTER_23
:
8765 case CP0_REG23__DEBUG
:
8766 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8767 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8768 gen_save_pc(ctx
->base
.pc_next
+ 4);
8769 ctx
->base
.is_jmp
= DISAS_EXIT
;
8770 register_name
= "Debug";
8772 case CP0_REG23__TRACECONTROL
:
8773 /* PDtrace support */
8774 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8775 /* Stop translation as we may have switched the execution mode */
8776 ctx
->base
.is_jmp
= DISAS_STOP
;
8777 register_name
= "TraceControl";
8778 goto cp0_unimplemented
;
8779 case CP0_REG23__TRACECONTROL2
:
8780 /* PDtrace support */
8781 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8782 /* Stop translation as we may have switched the execution mode */
8783 ctx
->base
.is_jmp
= DISAS_STOP
;
8784 register_name
= "TraceControl2";
8785 goto cp0_unimplemented
;
8786 case CP0_REG23__USERTRACEDATA1
:
8787 /* PDtrace support */
8788 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8789 /* Stop translation as we may have switched the execution mode */
8790 ctx
->base
.is_jmp
= DISAS_STOP
;
8791 register_name
= "UserTraceData1";
8792 goto cp0_unimplemented
;
8793 case CP0_REG23__TRACEIBPC
:
8794 /* PDtrace support */
8795 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8796 /* Stop translation as we may have switched the execution mode */
8797 ctx
->base
.is_jmp
= DISAS_STOP
;
8798 register_name
= "TraceIBPC";
8799 goto cp0_unimplemented
;
8800 case CP0_REG23__TRACEDBPC
:
8801 /* PDtrace support */
8802 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8803 /* Stop translation as we may have switched the execution mode */
8804 ctx
->base
.is_jmp
= DISAS_STOP
;
8805 register_name
= "TraceDBPC";
8806 goto cp0_unimplemented
;
8808 goto cp0_unimplemented
;
8811 case CP0_REGISTER_24
:
8813 case CP0_REG24__DEPC
:
8815 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8816 register_name
= "DEPC";
8819 goto cp0_unimplemented
;
8822 case CP0_REGISTER_25
:
8824 case CP0_REG25__PERFCTL0
:
8825 gen_helper_mtc0_performance0(cpu_env
, arg
);
8826 register_name
= "Performance0";
8828 case CP0_REG25__PERFCNT0
:
8829 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8830 register_name
= "Performance1";
8831 goto cp0_unimplemented
;
8832 case CP0_REG25__PERFCTL1
:
8833 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8834 register_name
= "Performance2";
8835 goto cp0_unimplemented
;
8836 case CP0_REG25__PERFCNT1
:
8837 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8838 register_name
= "Performance3";
8839 goto cp0_unimplemented
;
8840 case CP0_REG25__PERFCTL2
:
8841 /* gen_helper_mtc0_performance4(cpu_env, arg); */
8842 register_name
= "Performance4";
8843 goto cp0_unimplemented
;
8844 case CP0_REG25__PERFCNT2
:
8845 /* gen_helper_mtc0_performance5(cpu_env, arg); */
8846 register_name
= "Performance5";
8847 goto cp0_unimplemented
;
8848 case CP0_REG25__PERFCTL3
:
8849 /* gen_helper_mtc0_performance6(cpu_env, arg); */
8850 register_name
= "Performance6";
8851 goto cp0_unimplemented
;
8852 case CP0_REG25__PERFCNT3
:
8853 /* gen_helper_mtc0_performance7(cpu_env, arg); */
8854 register_name
= "Performance7";
8855 goto cp0_unimplemented
;
8857 goto cp0_unimplemented
;
8860 case CP0_REGISTER_26
:
8862 case CP0_REG26__ERRCTL
:
8863 gen_helper_mtc0_errctl(cpu_env
, arg
);
8864 ctx
->base
.is_jmp
= DISAS_STOP
;
8865 register_name
= "ErrCtl";
8868 goto cp0_unimplemented
;
8871 case CP0_REGISTER_27
:
8873 case CP0_REG27__CACHERR
:
8875 register_name
= "CacheErr";
8878 goto cp0_unimplemented
;
8881 case CP0_REGISTER_28
:
8883 case CP0_REG28__TAGLO
:
8884 case CP0_REG28__TAGLO1
:
8885 case CP0_REG28__TAGLO2
:
8886 case CP0_REG28__TAGLO3
:
8887 gen_helper_mtc0_taglo(cpu_env
, arg
);
8888 register_name
= "TagLo";
8890 case CP0_REG28__DATALO
:
8891 case CP0_REG28__DATALO1
:
8892 case CP0_REG28__DATALO2
:
8893 case CP0_REG28__DATALO3
:
8894 gen_helper_mtc0_datalo(cpu_env
, arg
);
8895 register_name
= "DataLo";
8898 goto cp0_unimplemented
;
8901 case CP0_REGISTER_29
:
8903 case CP0_REG29__TAGHI
:
8904 case CP0_REG29__TAGHI1
:
8905 case CP0_REG29__TAGHI2
:
8906 case CP0_REG29__TAGHI3
:
8907 gen_helper_mtc0_taghi(cpu_env
, arg
);
8908 register_name
= "TagHi";
8910 case CP0_REG29__DATAHI
:
8911 case CP0_REG29__DATAHI1
:
8912 case CP0_REG29__DATAHI2
:
8913 case CP0_REG29__DATAHI3
:
8914 gen_helper_mtc0_datahi(cpu_env
, arg
);
8915 register_name
= "DataHi";
8918 register_name
= "invalid sel";
8919 goto cp0_unimplemented
;
8922 case CP0_REGISTER_30
:
8924 case CP0_REG30__ERROREPC
:
8925 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8926 register_name
= "ErrorEPC";
8929 goto cp0_unimplemented
;
8932 case CP0_REGISTER_31
:
8934 case CP0_REG31__DESAVE
:
8936 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8937 register_name
= "DESAVE";
8939 case CP0_REG31__KSCRATCH1
:
8940 case CP0_REG31__KSCRATCH2
:
8941 case CP0_REG31__KSCRATCH3
:
8942 case CP0_REG31__KSCRATCH4
:
8943 case CP0_REG31__KSCRATCH5
:
8944 case CP0_REG31__KSCRATCH6
:
8945 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8946 tcg_gen_st_tl(arg
, cpu_env
,
8947 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8948 register_name
= "KScratch";
8951 goto cp0_unimplemented
;
8955 goto cp0_unimplemented
;
8957 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
8959 /* For simplicity assume that all writes can cause interrupts. */
8960 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8962 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8963 * translated code to check for pending interrupts.
8965 gen_save_pc(ctx
->base
.pc_next
+ 4);
8966 ctx
->base
.is_jmp
= DISAS_EXIT
;
8971 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
8972 register_name
, reg
, sel
);
8974 #endif /* TARGET_MIPS64 */
8976 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
8977 int u
, int sel
, int h
)
8979 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
8980 TCGv t0
= tcg_temp_local_new();
8982 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
8983 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
8984 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
8985 tcg_gen_movi_tl(t0
, -1);
8986 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
8987 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
8988 tcg_gen_movi_tl(t0
, -1);
8989 } else if (u
== 0) {
8994 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
8997 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9007 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9010 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9013 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9016 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9019 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9022 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9025 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9028 gen_mfc0(ctx
, t0
, rt
, sel
);
9035 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9038 gen_mfc0(ctx
, t0
, rt
, sel
);
9045 gen_helper_mftc0_status(t0
, cpu_env
);
9048 gen_mfc0(ctx
, t0
, rt
, sel
);
9055 gen_helper_mftc0_cause(t0
, cpu_env
);
9065 gen_helper_mftc0_epc(t0
, cpu_env
);
9075 gen_helper_mftc0_ebase(t0
, cpu_env
);
9092 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9102 gen_helper_mftc0_debug(t0
, cpu_env
);
9105 gen_mfc0(ctx
, t0
, rt
, sel
);
9110 gen_mfc0(ctx
, t0
, rt
, sel
);
9114 /* GPR registers. */
9116 gen_helper_1e0i(mftgpr
, t0
, rt
);
9118 /* Auxiliary CPU registers */
9122 gen_helper_1e0i(mftlo
, t0
, 0);
9125 gen_helper_1e0i(mfthi
, t0
, 0);
9128 gen_helper_1e0i(mftacx
, t0
, 0);
9131 gen_helper_1e0i(mftlo
, t0
, 1);
9134 gen_helper_1e0i(mfthi
, t0
, 1);
9137 gen_helper_1e0i(mftacx
, t0
, 1);
9140 gen_helper_1e0i(mftlo
, t0
, 2);
9143 gen_helper_1e0i(mfthi
, t0
, 2);
9146 gen_helper_1e0i(mftacx
, t0
, 2);
9149 gen_helper_1e0i(mftlo
, t0
, 3);
9152 gen_helper_1e0i(mfthi
, t0
, 3);
9155 gen_helper_1e0i(mftacx
, t0
, 3);
9158 gen_helper_mftdsp(t0
, cpu_env
);
9164 /* Floating point (COP1). */
9166 /* XXX: For now we support only a single FPU context. */
9168 TCGv_i32 fp0
= tcg_temp_new_i32();
9170 gen_load_fpr32(ctx
, fp0
, rt
);
9171 tcg_gen_ext_i32_tl(t0
, fp0
);
9172 tcg_temp_free_i32(fp0
);
9174 TCGv_i32 fp0
= tcg_temp_new_i32();
9176 gen_load_fpr32h(ctx
, fp0
, rt
);
9177 tcg_gen_ext_i32_tl(t0
, fp0
);
9178 tcg_temp_free_i32(fp0
);
9182 /* XXX: For now we support only a single FPU context. */
9183 gen_helper_1e0i(cfc1
, t0
, rt
);
9185 /* COP2: Not implemented. */
9193 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9194 gen_store_gpr(t0
, rd
);
9200 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9201 gen_reserved_instruction(ctx
);
9204 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9205 int u
, int sel
, int h
)
9207 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9208 TCGv t0
= tcg_temp_local_new();
9210 gen_load_gpr(t0
, rt
);
9211 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9212 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9213 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9216 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9217 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9220 } else if (u
== 0) {
9225 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9228 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9238 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9241 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9244 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9247 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9250 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9253 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9256 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9259 gen_mtc0(ctx
, t0
, rd
, sel
);
9266 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9269 gen_mtc0(ctx
, t0
, rd
, sel
);
9276 gen_helper_mttc0_status(cpu_env
, t0
);
9279 gen_mtc0(ctx
, t0
, rd
, sel
);
9286 gen_helper_mttc0_cause(cpu_env
, t0
);
9296 gen_helper_mttc0_ebase(cpu_env
, t0
);
9306 gen_helper_mttc0_debug(cpu_env
, t0
);
9309 gen_mtc0(ctx
, t0
, rd
, sel
);
9314 gen_mtc0(ctx
, t0
, rd
, sel
);
9318 /* GPR registers. */
9320 gen_helper_0e1i(mttgpr
, t0
, rd
);
9322 /* Auxiliary CPU registers */
9326 gen_helper_0e1i(mttlo
, t0
, 0);
9329 gen_helper_0e1i(mtthi
, t0
, 0);
9332 gen_helper_0e1i(mttacx
, t0
, 0);
9335 gen_helper_0e1i(mttlo
, t0
, 1);
9338 gen_helper_0e1i(mtthi
, t0
, 1);
9341 gen_helper_0e1i(mttacx
, t0
, 1);
9344 gen_helper_0e1i(mttlo
, t0
, 2);
9347 gen_helper_0e1i(mtthi
, t0
, 2);
9350 gen_helper_0e1i(mttacx
, t0
, 2);
9353 gen_helper_0e1i(mttlo
, t0
, 3);
9356 gen_helper_0e1i(mtthi
, t0
, 3);
9359 gen_helper_0e1i(mttacx
, t0
, 3);
9362 gen_helper_mttdsp(cpu_env
, t0
);
9368 /* Floating point (COP1). */
9370 /* XXX: For now we support only a single FPU context. */
9372 TCGv_i32 fp0
= tcg_temp_new_i32();
9374 tcg_gen_trunc_tl_i32(fp0
, t0
);
9375 gen_store_fpr32(ctx
, fp0
, rd
);
9376 tcg_temp_free_i32(fp0
);
9378 TCGv_i32 fp0
= tcg_temp_new_i32();
9380 tcg_gen_trunc_tl_i32(fp0
, t0
);
9381 gen_store_fpr32h(ctx
, fp0
, rd
);
9382 tcg_temp_free_i32(fp0
);
9386 /* XXX: For now we support only a single FPU context. */
9388 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9390 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9391 tcg_temp_free_i32(fs_tmp
);
9393 /* Stop translation as we may have changed hflags */
9394 ctx
->base
.is_jmp
= DISAS_STOP
;
9396 /* COP2: Not implemented. */
9404 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9410 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9411 gen_reserved_instruction(ctx
);
9414 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9417 const char *opn
= "ldst";
9419 check_cp0_enabled(ctx
);
9426 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9431 TCGv t0
= tcg_temp_new();
9433 gen_load_gpr(t0
, rt
);
9434 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9439 #if defined(TARGET_MIPS64)
9441 check_insn(ctx
, ISA_MIPS3
);
9446 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9450 check_insn(ctx
, ISA_MIPS3
);
9452 TCGv t0
= tcg_temp_new();
9454 gen_load_gpr(t0
, rt
);
9455 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9467 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9473 TCGv t0
= tcg_temp_new();
9474 gen_load_gpr(t0
, rt
);
9475 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9481 check_cp0_enabled(ctx
);
9486 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9487 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9491 check_cp0_enabled(ctx
);
9492 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9493 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9498 if (!env
->tlb
->helper_tlbwi
) {
9501 gen_helper_tlbwi(cpu_env
);
9506 if (!env
->tlb
->helper_tlbinv
) {
9509 gen_helper_tlbinv(cpu_env
);
9510 } /* treat as nop if TLBINV not supported */
9515 if (!env
->tlb
->helper_tlbinvf
) {
9518 gen_helper_tlbinvf(cpu_env
);
9519 } /* treat as nop if TLBINV not supported */
9523 if (!env
->tlb
->helper_tlbwr
) {
9526 gen_helper_tlbwr(cpu_env
);
9530 if (!env
->tlb
->helper_tlbp
) {
9533 gen_helper_tlbp(cpu_env
);
9537 if (!env
->tlb
->helper_tlbr
) {
9540 gen_helper_tlbr(cpu_env
);
9542 case OPC_ERET
: /* OPC_ERETNC */
9543 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9544 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9547 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9548 if (ctx
->opcode
& (1 << bit_shift
)) {
9551 check_insn(ctx
, ISA_MIPS_R5
);
9552 gen_helper_eretnc(cpu_env
);
9556 check_insn(ctx
, ISA_MIPS2
);
9557 gen_helper_eret(cpu_env
);
9559 ctx
->base
.is_jmp
= DISAS_EXIT
;
9564 check_insn(ctx
, ISA_MIPS_R1
);
9565 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9566 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9569 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9571 gen_reserved_instruction(ctx
);
9573 gen_helper_deret(cpu_env
);
9574 ctx
->base
.is_jmp
= DISAS_EXIT
;
9579 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9580 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9581 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9584 /* If we get an exception, we want to restart at next instruction */
9585 ctx
->base
.pc_next
+= 4;
9586 save_cpu_state(ctx
, 1);
9587 ctx
->base
.pc_next
-= 4;
9588 gen_helper_wait(cpu_env
);
9589 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9594 gen_reserved_instruction(ctx
);
9597 (void)opn
; /* avoid a compiler warning */
9599 #endif /* !CONFIG_USER_ONLY */
9601 /* CP1 Branches (before delay slot) */
9602 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9603 int32_t cc
, int32_t offset
)
9605 target_ulong btarget
;
9606 TCGv_i32 t0
= tcg_temp_new_i32();
9608 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9609 gen_reserved_instruction(ctx
);
9614 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9617 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9621 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9622 tcg_gen_not_i32(t0
, t0
);
9623 tcg_gen_andi_i32(t0
, t0
, 1);
9624 tcg_gen_extu_i32_tl(bcond
, t0
);
9627 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9628 tcg_gen_not_i32(t0
, t0
);
9629 tcg_gen_andi_i32(t0
, t0
, 1);
9630 tcg_gen_extu_i32_tl(bcond
, t0
);
9633 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9634 tcg_gen_andi_i32(t0
, t0
, 1);
9635 tcg_gen_extu_i32_tl(bcond
, t0
);
9638 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9639 tcg_gen_andi_i32(t0
, t0
, 1);
9640 tcg_gen_extu_i32_tl(bcond
, t0
);
9642 ctx
->hflags
|= MIPS_HFLAG_BL
;
9646 TCGv_i32 t1
= tcg_temp_new_i32();
9647 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9648 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9649 tcg_gen_nand_i32(t0
, t0
, t1
);
9650 tcg_temp_free_i32(t1
);
9651 tcg_gen_andi_i32(t0
, t0
, 1);
9652 tcg_gen_extu_i32_tl(bcond
, t0
);
9657 TCGv_i32 t1
= tcg_temp_new_i32();
9658 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9659 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9660 tcg_gen_or_i32(t0
, t0
, t1
);
9661 tcg_temp_free_i32(t1
);
9662 tcg_gen_andi_i32(t0
, t0
, 1);
9663 tcg_gen_extu_i32_tl(bcond
, t0
);
9668 TCGv_i32 t1
= tcg_temp_new_i32();
9669 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9670 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9671 tcg_gen_and_i32(t0
, t0
, t1
);
9672 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9673 tcg_gen_and_i32(t0
, t0
, t1
);
9674 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9675 tcg_gen_nand_i32(t0
, t0
, t1
);
9676 tcg_temp_free_i32(t1
);
9677 tcg_gen_andi_i32(t0
, t0
, 1);
9678 tcg_gen_extu_i32_tl(bcond
, t0
);
9683 TCGv_i32 t1
= tcg_temp_new_i32();
9684 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9685 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9686 tcg_gen_or_i32(t0
, t0
, t1
);
9687 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9688 tcg_gen_or_i32(t0
, t0
, t1
);
9689 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9690 tcg_gen_or_i32(t0
, t0
, t1
);
9691 tcg_temp_free_i32(t1
);
9692 tcg_gen_andi_i32(t0
, t0
, 1);
9693 tcg_gen_extu_i32_tl(bcond
, t0
);
9696 ctx
->hflags
|= MIPS_HFLAG_BC
;
9699 MIPS_INVAL("cp1 cond branch");
9700 gen_reserved_instruction(ctx
);
9703 ctx
->btarget
= btarget
;
9704 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9706 tcg_temp_free_i32(t0
);
9709 /* R6 CP1 Branches */
9710 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
9711 int32_t ft
, int32_t offset
,
9714 target_ulong btarget
;
9715 TCGv_i64 t0
= tcg_temp_new_i64();
9717 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9718 #ifdef MIPS_DEBUG_DISAS
9719 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9720 "\n", ctx
->base
.pc_next
);
9722 gen_reserved_instruction(ctx
);
9726 gen_load_fpr64(ctx
, t0
, ft
);
9727 tcg_gen_andi_i64(t0
, t0
, 1);
9729 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
9733 tcg_gen_xori_i64(t0
, t0
, 1);
9734 ctx
->hflags
|= MIPS_HFLAG_BC
;
9737 /* t0 already set */
9738 ctx
->hflags
|= MIPS_HFLAG_BC
;
9741 MIPS_INVAL("cp1 cond branch");
9742 gen_reserved_instruction(ctx
);
9746 tcg_gen_trunc_i64_tl(bcond
, t0
);
9748 ctx
->btarget
= btarget
;
9750 switch (delayslot_size
) {
9752 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
9755 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9760 tcg_temp_free_i64(t0
);
9763 /* Coprocessor 1 (FPU) */
9765 #define FOP(func, fmt) (((fmt) << 21) | (func))
9768 OPC_ADD_S
= FOP(0, FMT_S
),
9769 OPC_SUB_S
= FOP(1, FMT_S
),
9770 OPC_MUL_S
= FOP(2, FMT_S
),
9771 OPC_DIV_S
= FOP(3, FMT_S
),
9772 OPC_SQRT_S
= FOP(4, FMT_S
),
9773 OPC_ABS_S
= FOP(5, FMT_S
),
9774 OPC_MOV_S
= FOP(6, FMT_S
),
9775 OPC_NEG_S
= FOP(7, FMT_S
),
9776 OPC_ROUND_L_S
= FOP(8, FMT_S
),
9777 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
9778 OPC_CEIL_L_S
= FOP(10, FMT_S
),
9779 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
9780 OPC_ROUND_W_S
= FOP(12, FMT_S
),
9781 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
9782 OPC_CEIL_W_S
= FOP(14, FMT_S
),
9783 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
9784 OPC_SEL_S
= FOP(16, FMT_S
),
9785 OPC_MOVCF_S
= FOP(17, FMT_S
),
9786 OPC_MOVZ_S
= FOP(18, FMT_S
),
9787 OPC_MOVN_S
= FOP(19, FMT_S
),
9788 OPC_SELEQZ_S
= FOP(20, FMT_S
),
9789 OPC_RECIP_S
= FOP(21, FMT_S
),
9790 OPC_RSQRT_S
= FOP(22, FMT_S
),
9791 OPC_SELNEZ_S
= FOP(23, FMT_S
),
9792 OPC_MADDF_S
= FOP(24, FMT_S
),
9793 OPC_MSUBF_S
= FOP(25, FMT_S
),
9794 OPC_RINT_S
= FOP(26, FMT_S
),
9795 OPC_CLASS_S
= FOP(27, FMT_S
),
9796 OPC_MIN_S
= FOP(28, FMT_S
),
9797 OPC_RECIP2_S
= FOP(28, FMT_S
),
9798 OPC_MINA_S
= FOP(29, FMT_S
),
9799 OPC_RECIP1_S
= FOP(29, FMT_S
),
9800 OPC_MAX_S
= FOP(30, FMT_S
),
9801 OPC_RSQRT1_S
= FOP(30, FMT_S
),
9802 OPC_MAXA_S
= FOP(31, FMT_S
),
9803 OPC_RSQRT2_S
= FOP(31, FMT_S
),
9804 OPC_CVT_D_S
= FOP(33, FMT_S
),
9805 OPC_CVT_W_S
= FOP(36, FMT_S
),
9806 OPC_CVT_L_S
= FOP(37, FMT_S
),
9807 OPC_CVT_PS_S
= FOP(38, FMT_S
),
9808 OPC_CMP_F_S
= FOP(48, FMT_S
),
9809 OPC_CMP_UN_S
= FOP(49, FMT_S
),
9810 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
9811 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
9812 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
9813 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
9814 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
9815 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
9816 OPC_CMP_SF_S
= FOP(56, FMT_S
),
9817 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
9818 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
9819 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
9820 OPC_CMP_LT_S
= FOP(60, FMT_S
),
9821 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
9822 OPC_CMP_LE_S
= FOP(62, FMT_S
),
9823 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
9825 OPC_ADD_D
= FOP(0, FMT_D
),
9826 OPC_SUB_D
= FOP(1, FMT_D
),
9827 OPC_MUL_D
= FOP(2, FMT_D
),
9828 OPC_DIV_D
= FOP(3, FMT_D
),
9829 OPC_SQRT_D
= FOP(4, FMT_D
),
9830 OPC_ABS_D
= FOP(5, FMT_D
),
9831 OPC_MOV_D
= FOP(6, FMT_D
),
9832 OPC_NEG_D
= FOP(7, FMT_D
),
9833 OPC_ROUND_L_D
= FOP(8, FMT_D
),
9834 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
9835 OPC_CEIL_L_D
= FOP(10, FMT_D
),
9836 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
9837 OPC_ROUND_W_D
= FOP(12, FMT_D
),
9838 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
9839 OPC_CEIL_W_D
= FOP(14, FMT_D
),
9840 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
9841 OPC_SEL_D
= FOP(16, FMT_D
),
9842 OPC_MOVCF_D
= FOP(17, FMT_D
),
9843 OPC_MOVZ_D
= FOP(18, FMT_D
),
9844 OPC_MOVN_D
= FOP(19, FMT_D
),
9845 OPC_SELEQZ_D
= FOP(20, FMT_D
),
9846 OPC_RECIP_D
= FOP(21, FMT_D
),
9847 OPC_RSQRT_D
= FOP(22, FMT_D
),
9848 OPC_SELNEZ_D
= FOP(23, FMT_D
),
9849 OPC_MADDF_D
= FOP(24, FMT_D
),
9850 OPC_MSUBF_D
= FOP(25, FMT_D
),
9851 OPC_RINT_D
= FOP(26, FMT_D
),
9852 OPC_CLASS_D
= FOP(27, FMT_D
),
9853 OPC_MIN_D
= FOP(28, FMT_D
),
9854 OPC_RECIP2_D
= FOP(28, FMT_D
),
9855 OPC_MINA_D
= FOP(29, FMT_D
),
9856 OPC_RECIP1_D
= FOP(29, FMT_D
),
9857 OPC_MAX_D
= FOP(30, FMT_D
),
9858 OPC_RSQRT1_D
= FOP(30, FMT_D
),
9859 OPC_MAXA_D
= FOP(31, FMT_D
),
9860 OPC_RSQRT2_D
= FOP(31, FMT_D
),
9861 OPC_CVT_S_D
= FOP(32, FMT_D
),
9862 OPC_CVT_W_D
= FOP(36, FMT_D
),
9863 OPC_CVT_L_D
= FOP(37, FMT_D
),
9864 OPC_CMP_F_D
= FOP(48, FMT_D
),
9865 OPC_CMP_UN_D
= FOP(49, FMT_D
),
9866 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
9867 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
9868 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
9869 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
9870 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
9871 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
9872 OPC_CMP_SF_D
= FOP(56, FMT_D
),
9873 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
9874 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
9875 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
9876 OPC_CMP_LT_D
= FOP(60, FMT_D
),
9877 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
9878 OPC_CMP_LE_D
= FOP(62, FMT_D
),
9879 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
9881 OPC_CVT_S_W
= FOP(32, FMT_W
),
9882 OPC_CVT_D_W
= FOP(33, FMT_W
),
9883 OPC_CVT_S_L
= FOP(32, FMT_L
),
9884 OPC_CVT_D_L
= FOP(33, FMT_L
),
9885 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
9887 OPC_ADD_PS
= FOP(0, FMT_PS
),
9888 OPC_SUB_PS
= FOP(1, FMT_PS
),
9889 OPC_MUL_PS
= FOP(2, FMT_PS
),
9890 OPC_DIV_PS
= FOP(3, FMT_PS
),
9891 OPC_ABS_PS
= FOP(5, FMT_PS
),
9892 OPC_MOV_PS
= FOP(6, FMT_PS
),
9893 OPC_NEG_PS
= FOP(7, FMT_PS
),
9894 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
9895 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
9896 OPC_MOVN_PS
= FOP(19, FMT_PS
),
9897 OPC_ADDR_PS
= FOP(24, FMT_PS
),
9898 OPC_MULR_PS
= FOP(26, FMT_PS
),
9899 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
9900 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
9901 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
9902 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
9904 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
9905 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
9906 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
9907 OPC_PLL_PS
= FOP(44, FMT_PS
),
9908 OPC_PLU_PS
= FOP(45, FMT_PS
),
9909 OPC_PUL_PS
= FOP(46, FMT_PS
),
9910 OPC_PUU_PS
= FOP(47, FMT_PS
),
9911 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
9912 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
9913 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
9914 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
9915 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
9916 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
9917 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
9918 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
9919 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
9920 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
9921 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
9922 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
9923 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
9924 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
9925 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
9926 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
9930 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
9931 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
9932 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
9933 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
9934 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
9935 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
9936 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
9937 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
9938 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
9939 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
9940 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
9941 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
9942 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
9943 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
9944 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
9945 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
9946 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
9947 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
9948 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
9949 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
9950 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
9951 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
9953 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
9954 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
9955 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
9956 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
9957 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
9958 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
9959 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
9960 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
9961 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
9962 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
9963 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
9964 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
9965 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
9966 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
9967 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
9968 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
9969 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
9970 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
9971 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
9972 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
9973 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
9974 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
9977 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
9979 TCGv t0
= tcg_temp_new();
9984 TCGv_i32 fp0
= tcg_temp_new_i32();
9986 gen_load_fpr32(ctx
, fp0
, fs
);
9987 tcg_gen_ext_i32_tl(t0
, fp0
);
9988 tcg_temp_free_i32(fp0
);
9990 gen_store_gpr(t0
, rt
);
9993 gen_load_gpr(t0
, rt
);
9995 TCGv_i32 fp0
= tcg_temp_new_i32();
9997 tcg_gen_trunc_tl_i32(fp0
, t0
);
9998 gen_store_fpr32(ctx
, fp0
, fs
);
9999 tcg_temp_free_i32(fp0
);
10003 gen_helper_1e0i(cfc1
, t0
, fs
);
10004 gen_store_gpr(t0
, rt
);
10007 gen_load_gpr(t0
, rt
);
10008 save_cpu_state(ctx
, 0);
10010 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10012 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10013 tcg_temp_free_i32(fs_tmp
);
10015 /* Stop translation as we may have changed hflags */
10016 ctx
->base
.is_jmp
= DISAS_STOP
;
10018 #if defined(TARGET_MIPS64)
10020 gen_load_fpr64(ctx
, t0
, fs
);
10021 gen_store_gpr(t0
, rt
);
10024 gen_load_gpr(t0
, rt
);
10025 gen_store_fpr64(ctx
, t0
, fs
);
10030 TCGv_i32 fp0
= tcg_temp_new_i32();
10032 gen_load_fpr32h(ctx
, fp0
, fs
);
10033 tcg_gen_ext_i32_tl(t0
, fp0
);
10034 tcg_temp_free_i32(fp0
);
10036 gen_store_gpr(t0
, rt
);
10039 gen_load_gpr(t0
, rt
);
10041 TCGv_i32 fp0
= tcg_temp_new_i32();
10043 tcg_gen_trunc_tl_i32(fp0
, t0
);
10044 gen_store_fpr32h(ctx
, fp0
, fs
);
10045 tcg_temp_free_i32(fp0
);
10049 MIPS_INVAL("cp1 move");
10050 gen_reserved_instruction(ctx
);
10058 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10065 /* Treat as NOP. */
10070 cond
= TCG_COND_EQ
;
10072 cond
= TCG_COND_NE
;
10075 l1
= gen_new_label();
10076 t0
= tcg_temp_new_i32();
10077 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10078 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10079 tcg_temp_free_i32(t0
);
10080 gen_load_gpr(cpu_gpr
[rd
], rs
);
10084 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10088 TCGv_i32 t0
= tcg_temp_new_i32();
10089 TCGLabel
*l1
= gen_new_label();
10092 cond
= TCG_COND_EQ
;
10094 cond
= TCG_COND_NE
;
10097 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10098 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10099 gen_load_fpr32(ctx
, t0
, fs
);
10100 gen_store_fpr32(ctx
, t0
, fd
);
10102 tcg_temp_free_i32(t0
);
10105 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10109 TCGv_i32 t0
= tcg_temp_new_i32();
10111 TCGLabel
*l1
= gen_new_label();
10114 cond
= TCG_COND_EQ
;
10116 cond
= TCG_COND_NE
;
10119 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10120 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10121 tcg_temp_free_i32(t0
);
10122 fp0
= tcg_temp_new_i64();
10123 gen_load_fpr64(ctx
, fp0
, fs
);
10124 gen_store_fpr64(ctx
, fp0
, fd
);
10125 tcg_temp_free_i64(fp0
);
10129 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10133 TCGv_i32 t0
= tcg_temp_new_i32();
10134 TCGLabel
*l1
= gen_new_label();
10135 TCGLabel
*l2
= gen_new_label();
10138 cond
= TCG_COND_EQ
;
10140 cond
= TCG_COND_NE
;
10143 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10144 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10145 gen_load_fpr32(ctx
, t0
, fs
);
10146 gen_store_fpr32(ctx
, t0
, fd
);
10149 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10150 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10151 gen_load_fpr32h(ctx
, t0
, fs
);
10152 gen_store_fpr32h(ctx
, t0
, fd
);
10153 tcg_temp_free_i32(t0
);
10157 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10160 TCGv_i32 t1
= tcg_const_i32(0);
10161 TCGv_i32 fp0
= tcg_temp_new_i32();
10162 TCGv_i32 fp1
= tcg_temp_new_i32();
10163 TCGv_i32 fp2
= tcg_temp_new_i32();
10164 gen_load_fpr32(ctx
, fp0
, fd
);
10165 gen_load_fpr32(ctx
, fp1
, ft
);
10166 gen_load_fpr32(ctx
, fp2
, fs
);
10170 tcg_gen_andi_i32(fp0
, fp0
, 1);
10171 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10174 tcg_gen_andi_i32(fp1
, fp1
, 1);
10175 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10178 tcg_gen_andi_i32(fp1
, fp1
, 1);
10179 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10182 MIPS_INVAL("gen_sel_s");
10183 gen_reserved_instruction(ctx
);
10187 gen_store_fpr32(ctx
, fp0
, fd
);
10188 tcg_temp_free_i32(fp2
);
10189 tcg_temp_free_i32(fp1
);
10190 tcg_temp_free_i32(fp0
);
10191 tcg_temp_free_i32(t1
);
10194 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10197 TCGv_i64 t1
= tcg_const_i64(0);
10198 TCGv_i64 fp0
= tcg_temp_new_i64();
10199 TCGv_i64 fp1
= tcg_temp_new_i64();
10200 TCGv_i64 fp2
= tcg_temp_new_i64();
10201 gen_load_fpr64(ctx
, fp0
, fd
);
10202 gen_load_fpr64(ctx
, fp1
, ft
);
10203 gen_load_fpr64(ctx
, fp2
, fs
);
10207 tcg_gen_andi_i64(fp0
, fp0
, 1);
10208 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10211 tcg_gen_andi_i64(fp1
, fp1
, 1);
10212 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10215 tcg_gen_andi_i64(fp1
, fp1
, 1);
10216 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10219 MIPS_INVAL("gen_sel_d");
10220 gen_reserved_instruction(ctx
);
10224 gen_store_fpr64(ctx
, fp0
, fd
);
10225 tcg_temp_free_i64(fp2
);
10226 tcg_temp_free_i64(fp1
);
10227 tcg_temp_free_i64(fp0
);
10228 tcg_temp_free_i64(t1
);
10231 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10232 int ft
, int fs
, int fd
, int cc
)
10234 uint32_t func
= ctx
->opcode
& 0x3f;
10238 TCGv_i32 fp0
= tcg_temp_new_i32();
10239 TCGv_i32 fp1
= tcg_temp_new_i32();
10241 gen_load_fpr32(ctx
, fp0
, fs
);
10242 gen_load_fpr32(ctx
, fp1
, ft
);
10243 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10244 tcg_temp_free_i32(fp1
);
10245 gen_store_fpr32(ctx
, fp0
, fd
);
10246 tcg_temp_free_i32(fp0
);
10251 TCGv_i32 fp0
= tcg_temp_new_i32();
10252 TCGv_i32 fp1
= tcg_temp_new_i32();
10254 gen_load_fpr32(ctx
, fp0
, fs
);
10255 gen_load_fpr32(ctx
, fp1
, ft
);
10256 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10257 tcg_temp_free_i32(fp1
);
10258 gen_store_fpr32(ctx
, fp0
, fd
);
10259 tcg_temp_free_i32(fp0
);
10264 TCGv_i32 fp0
= tcg_temp_new_i32();
10265 TCGv_i32 fp1
= tcg_temp_new_i32();
10267 gen_load_fpr32(ctx
, fp0
, fs
);
10268 gen_load_fpr32(ctx
, fp1
, ft
);
10269 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10270 tcg_temp_free_i32(fp1
);
10271 gen_store_fpr32(ctx
, fp0
, fd
);
10272 tcg_temp_free_i32(fp0
);
10277 TCGv_i32 fp0
= tcg_temp_new_i32();
10278 TCGv_i32 fp1
= tcg_temp_new_i32();
10280 gen_load_fpr32(ctx
, fp0
, fs
);
10281 gen_load_fpr32(ctx
, fp1
, ft
);
10282 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10283 tcg_temp_free_i32(fp1
);
10284 gen_store_fpr32(ctx
, fp0
, fd
);
10285 tcg_temp_free_i32(fp0
);
10290 TCGv_i32 fp0
= tcg_temp_new_i32();
10292 gen_load_fpr32(ctx
, fp0
, fs
);
10293 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10294 gen_store_fpr32(ctx
, fp0
, fd
);
10295 tcg_temp_free_i32(fp0
);
10300 TCGv_i32 fp0
= tcg_temp_new_i32();
10302 gen_load_fpr32(ctx
, fp0
, fs
);
10303 if (ctx
->abs2008
) {
10304 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10306 gen_helper_float_abs_s(fp0
, fp0
);
10308 gen_store_fpr32(ctx
, fp0
, fd
);
10309 tcg_temp_free_i32(fp0
);
10314 TCGv_i32 fp0
= tcg_temp_new_i32();
10316 gen_load_fpr32(ctx
, fp0
, fs
);
10317 gen_store_fpr32(ctx
, fp0
, fd
);
10318 tcg_temp_free_i32(fp0
);
10323 TCGv_i32 fp0
= tcg_temp_new_i32();
10325 gen_load_fpr32(ctx
, fp0
, fs
);
10326 if (ctx
->abs2008
) {
10327 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10329 gen_helper_float_chs_s(fp0
, fp0
);
10331 gen_store_fpr32(ctx
, fp0
, fd
);
10332 tcg_temp_free_i32(fp0
);
10335 case OPC_ROUND_L_S
:
10336 check_cp1_64bitmode(ctx
);
10338 TCGv_i32 fp32
= tcg_temp_new_i32();
10339 TCGv_i64 fp64
= tcg_temp_new_i64();
10341 gen_load_fpr32(ctx
, fp32
, fs
);
10342 if (ctx
->nan2008
) {
10343 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10345 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10347 tcg_temp_free_i32(fp32
);
10348 gen_store_fpr64(ctx
, fp64
, fd
);
10349 tcg_temp_free_i64(fp64
);
10352 case OPC_TRUNC_L_S
:
10353 check_cp1_64bitmode(ctx
);
10355 TCGv_i32 fp32
= tcg_temp_new_i32();
10356 TCGv_i64 fp64
= tcg_temp_new_i64();
10358 gen_load_fpr32(ctx
, fp32
, fs
);
10359 if (ctx
->nan2008
) {
10360 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10362 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10364 tcg_temp_free_i32(fp32
);
10365 gen_store_fpr64(ctx
, fp64
, fd
);
10366 tcg_temp_free_i64(fp64
);
10370 check_cp1_64bitmode(ctx
);
10372 TCGv_i32 fp32
= tcg_temp_new_i32();
10373 TCGv_i64 fp64
= tcg_temp_new_i64();
10375 gen_load_fpr32(ctx
, fp32
, fs
);
10376 if (ctx
->nan2008
) {
10377 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10379 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10381 tcg_temp_free_i32(fp32
);
10382 gen_store_fpr64(ctx
, fp64
, fd
);
10383 tcg_temp_free_i64(fp64
);
10386 case OPC_FLOOR_L_S
:
10387 check_cp1_64bitmode(ctx
);
10389 TCGv_i32 fp32
= tcg_temp_new_i32();
10390 TCGv_i64 fp64
= tcg_temp_new_i64();
10392 gen_load_fpr32(ctx
, fp32
, fs
);
10393 if (ctx
->nan2008
) {
10394 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10396 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10398 tcg_temp_free_i32(fp32
);
10399 gen_store_fpr64(ctx
, fp64
, fd
);
10400 tcg_temp_free_i64(fp64
);
10403 case OPC_ROUND_W_S
:
10405 TCGv_i32 fp0
= tcg_temp_new_i32();
10407 gen_load_fpr32(ctx
, fp0
, fs
);
10408 if (ctx
->nan2008
) {
10409 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10411 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10413 gen_store_fpr32(ctx
, fp0
, fd
);
10414 tcg_temp_free_i32(fp0
);
10417 case OPC_TRUNC_W_S
:
10419 TCGv_i32 fp0
= tcg_temp_new_i32();
10421 gen_load_fpr32(ctx
, fp0
, fs
);
10422 if (ctx
->nan2008
) {
10423 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10425 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10427 gen_store_fpr32(ctx
, fp0
, fd
);
10428 tcg_temp_free_i32(fp0
);
10433 TCGv_i32 fp0
= tcg_temp_new_i32();
10435 gen_load_fpr32(ctx
, fp0
, fs
);
10436 if (ctx
->nan2008
) {
10437 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10439 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10441 gen_store_fpr32(ctx
, fp0
, fd
);
10442 tcg_temp_free_i32(fp0
);
10445 case OPC_FLOOR_W_S
:
10447 TCGv_i32 fp0
= tcg_temp_new_i32();
10449 gen_load_fpr32(ctx
, fp0
, fs
);
10450 if (ctx
->nan2008
) {
10451 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10453 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10455 gen_store_fpr32(ctx
, fp0
, fd
);
10456 tcg_temp_free_i32(fp0
);
10460 check_insn(ctx
, ISA_MIPS_R6
);
10461 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10464 check_insn(ctx
, ISA_MIPS_R6
);
10465 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10468 check_insn(ctx
, ISA_MIPS_R6
);
10469 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10472 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10473 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10476 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10478 TCGLabel
*l1
= gen_new_label();
10482 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10484 fp0
= tcg_temp_new_i32();
10485 gen_load_fpr32(ctx
, fp0
, fs
);
10486 gen_store_fpr32(ctx
, fp0
, fd
);
10487 tcg_temp_free_i32(fp0
);
10492 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10494 TCGLabel
*l1
= gen_new_label();
10498 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10499 fp0
= tcg_temp_new_i32();
10500 gen_load_fpr32(ctx
, fp0
, fs
);
10501 gen_store_fpr32(ctx
, fp0
, fd
);
10502 tcg_temp_free_i32(fp0
);
10509 TCGv_i32 fp0
= tcg_temp_new_i32();
10511 gen_load_fpr32(ctx
, fp0
, fs
);
10512 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10513 gen_store_fpr32(ctx
, fp0
, fd
);
10514 tcg_temp_free_i32(fp0
);
10519 TCGv_i32 fp0
= tcg_temp_new_i32();
10521 gen_load_fpr32(ctx
, fp0
, fs
);
10522 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10523 gen_store_fpr32(ctx
, fp0
, fd
);
10524 tcg_temp_free_i32(fp0
);
10528 check_insn(ctx
, ISA_MIPS_R6
);
10530 TCGv_i32 fp0
= tcg_temp_new_i32();
10531 TCGv_i32 fp1
= tcg_temp_new_i32();
10532 TCGv_i32 fp2
= tcg_temp_new_i32();
10533 gen_load_fpr32(ctx
, fp0
, fs
);
10534 gen_load_fpr32(ctx
, fp1
, ft
);
10535 gen_load_fpr32(ctx
, fp2
, fd
);
10536 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10537 gen_store_fpr32(ctx
, fp2
, fd
);
10538 tcg_temp_free_i32(fp2
);
10539 tcg_temp_free_i32(fp1
);
10540 tcg_temp_free_i32(fp0
);
10544 check_insn(ctx
, ISA_MIPS_R6
);
10546 TCGv_i32 fp0
= tcg_temp_new_i32();
10547 TCGv_i32 fp1
= tcg_temp_new_i32();
10548 TCGv_i32 fp2
= tcg_temp_new_i32();
10549 gen_load_fpr32(ctx
, fp0
, fs
);
10550 gen_load_fpr32(ctx
, fp1
, ft
);
10551 gen_load_fpr32(ctx
, fp2
, fd
);
10552 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10553 gen_store_fpr32(ctx
, fp2
, fd
);
10554 tcg_temp_free_i32(fp2
);
10555 tcg_temp_free_i32(fp1
);
10556 tcg_temp_free_i32(fp0
);
10560 check_insn(ctx
, ISA_MIPS_R6
);
10562 TCGv_i32 fp0
= tcg_temp_new_i32();
10563 gen_load_fpr32(ctx
, fp0
, fs
);
10564 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10565 gen_store_fpr32(ctx
, fp0
, fd
);
10566 tcg_temp_free_i32(fp0
);
10570 check_insn(ctx
, ISA_MIPS_R6
);
10572 TCGv_i32 fp0
= tcg_temp_new_i32();
10573 gen_load_fpr32(ctx
, fp0
, fs
);
10574 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10575 gen_store_fpr32(ctx
, fp0
, fd
);
10576 tcg_temp_free_i32(fp0
);
10579 case OPC_MIN_S
: /* OPC_RECIP2_S */
10580 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10582 TCGv_i32 fp0
= tcg_temp_new_i32();
10583 TCGv_i32 fp1
= tcg_temp_new_i32();
10584 TCGv_i32 fp2
= tcg_temp_new_i32();
10585 gen_load_fpr32(ctx
, fp0
, fs
);
10586 gen_load_fpr32(ctx
, fp1
, ft
);
10587 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10588 gen_store_fpr32(ctx
, fp2
, fd
);
10589 tcg_temp_free_i32(fp2
);
10590 tcg_temp_free_i32(fp1
);
10591 tcg_temp_free_i32(fp0
);
10594 check_cp1_64bitmode(ctx
);
10596 TCGv_i32 fp0
= tcg_temp_new_i32();
10597 TCGv_i32 fp1
= tcg_temp_new_i32();
10599 gen_load_fpr32(ctx
, fp0
, fs
);
10600 gen_load_fpr32(ctx
, fp1
, ft
);
10601 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10602 tcg_temp_free_i32(fp1
);
10603 gen_store_fpr32(ctx
, fp0
, fd
);
10604 tcg_temp_free_i32(fp0
);
10608 case OPC_MINA_S
: /* OPC_RECIP1_S */
10609 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10611 TCGv_i32 fp0
= tcg_temp_new_i32();
10612 TCGv_i32 fp1
= tcg_temp_new_i32();
10613 TCGv_i32 fp2
= tcg_temp_new_i32();
10614 gen_load_fpr32(ctx
, fp0
, fs
);
10615 gen_load_fpr32(ctx
, fp1
, ft
);
10616 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10617 gen_store_fpr32(ctx
, fp2
, fd
);
10618 tcg_temp_free_i32(fp2
);
10619 tcg_temp_free_i32(fp1
);
10620 tcg_temp_free_i32(fp0
);
10623 check_cp1_64bitmode(ctx
);
10625 TCGv_i32 fp0
= tcg_temp_new_i32();
10627 gen_load_fpr32(ctx
, fp0
, fs
);
10628 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10629 gen_store_fpr32(ctx
, fp0
, fd
);
10630 tcg_temp_free_i32(fp0
);
10634 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10635 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10637 TCGv_i32 fp0
= tcg_temp_new_i32();
10638 TCGv_i32 fp1
= tcg_temp_new_i32();
10639 gen_load_fpr32(ctx
, fp0
, fs
);
10640 gen_load_fpr32(ctx
, fp1
, ft
);
10641 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10642 gen_store_fpr32(ctx
, fp1
, fd
);
10643 tcg_temp_free_i32(fp1
);
10644 tcg_temp_free_i32(fp0
);
10647 check_cp1_64bitmode(ctx
);
10649 TCGv_i32 fp0
= tcg_temp_new_i32();
10651 gen_load_fpr32(ctx
, fp0
, fs
);
10652 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
10653 gen_store_fpr32(ctx
, fp0
, fd
);
10654 tcg_temp_free_i32(fp0
);
10658 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
10659 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10661 TCGv_i32 fp0
= tcg_temp_new_i32();
10662 TCGv_i32 fp1
= tcg_temp_new_i32();
10663 gen_load_fpr32(ctx
, fp0
, fs
);
10664 gen_load_fpr32(ctx
, fp1
, ft
);
10665 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
10666 gen_store_fpr32(ctx
, fp1
, fd
);
10667 tcg_temp_free_i32(fp1
);
10668 tcg_temp_free_i32(fp0
);
10671 check_cp1_64bitmode(ctx
);
10673 TCGv_i32 fp0
= tcg_temp_new_i32();
10674 TCGv_i32 fp1
= tcg_temp_new_i32();
10676 gen_load_fpr32(ctx
, fp0
, fs
);
10677 gen_load_fpr32(ctx
, fp1
, ft
);
10678 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
10679 tcg_temp_free_i32(fp1
);
10680 gen_store_fpr32(ctx
, fp0
, fd
);
10681 tcg_temp_free_i32(fp0
);
10686 check_cp1_registers(ctx
, fd
);
10688 TCGv_i32 fp32
= tcg_temp_new_i32();
10689 TCGv_i64 fp64
= tcg_temp_new_i64();
10691 gen_load_fpr32(ctx
, fp32
, fs
);
10692 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
10693 tcg_temp_free_i32(fp32
);
10694 gen_store_fpr64(ctx
, fp64
, fd
);
10695 tcg_temp_free_i64(fp64
);
10700 TCGv_i32 fp0
= tcg_temp_new_i32();
10702 gen_load_fpr32(ctx
, fp0
, fs
);
10703 if (ctx
->nan2008
) {
10704 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
10706 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
10708 gen_store_fpr32(ctx
, fp0
, fd
);
10709 tcg_temp_free_i32(fp0
);
10713 check_cp1_64bitmode(ctx
);
10715 TCGv_i32 fp32
= tcg_temp_new_i32();
10716 TCGv_i64 fp64
= tcg_temp_new_i64();
10718 gen_load_fpr32(ctx
, fp32
, fs
);
10719 if (ctx
->nan2008
) {
10720 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
10722 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
10724 tcg_temp_free_i32(fp32
);
10725 gen_store_fpr64(ctx
, fp64
, fd
);
10726 tcg_temp_free_i64(fp64
);
10732 TCGv_i64 fp64
= tcg_temp_new_i64();
10733 TCGv_i32 fp32_0
= tcg_temp_new_i32();
10734 TCGv_i32 fp32_1
= tcg_temp_new_i32();
10736 gen_load_fpr32(ctx
, fp32_0
, fs
);
10737 gen_load_fpr32(ctx
, fp32_1
, ft
);
10738 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
10739 tcg_temp_free_i32(fp32_1
);
10740 tcg_temp_free_i32(fp32_0
);
10741 gen_store_fpr64(ctx
, fp64
, fd
);
10742 tcg_temp_free_i64(fp64
);
10748 case OPC_CMP_UEQ_S
:
10749 case OPC_CMP_OLT_S
:
10750 case OPC_CMP_ULT_S
:
10751 case OPC_CMP_OLE_S
:
10752 case OPC_CMP_ULE_S
:
10754 case OPC_CMP_NGLE_S
:
10755 case OPC_CMP_SEQ_S
:
10756 case OPC_CMP_NGL_S
:
10758 case OPC_CMP_NGE_S
:
10760 case OPC_CMP_NGT_S
:
10761 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10762 if (ctx
->opcode
& (1 << 6)) {
10763 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
10765 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
10769 check_cp1_registers(ctx
, fs
| ft
| fd
);
10771 TCGv_i64 fp0
= tcg_temp_new_i64();
10772 TCGv_i64 fp1
= tcg_temp_new_i64();
10774 gen_load_fpr64(ctx
, fp0
, fs
);
10775 gen_load_fpr64(ctx
, fp1
, ft
);
10776 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
10777 tcg_temp_free_i64(fp1
);
10778 gen_store_fpr64(ctx
, fp0
, fd
);
10779 tcg_temp_free_i64(fp0
);
10783 check_cp1_registers(ctx
, fs
| ft
| fd
);
10785 TCGv_i64 fp0
= tcg_temp_new_i64();
10786 TCGv_i64 fp1
= tcg_temp_new_i64();
10788 gen_load_fpr64(ctx
, fp0
, fs
);
10789 gen_load_fpr64(ctx
, fp1
, ft
);
10790 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
10791 tcg_temp_free_i64(fp1
);
10792 gen_store_fpr64(ctx
, fp0
, fd
);
10793 tcg_temp_free_i64(fp0
);
10797 check_cp1_registers(ctx
, fs
| ft
| fd
);
10799 TCGv_i64 fp0
= tcg_temp_new_i64();
10800 TCGv_i64 fp1
= tcg_temp_new_i64();
10802 gen_load_fpr64(ctx
, fp0
, fs
);
10803 gen_load_fpr64(ctx
, fp1
, ft
);
10804 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
10805 tcg_temp_free_i64(fp1
);
10806 gen_store_fpr64(ctx
, fp0
, fd
);
10807 tcg_temp_free_i64(fp0
);
10811 check_cp1_registers(ctx
, fs
| ft
| fd
);
10813 TCGv_i64 fp0
= tcg_temp_new_i64();
10814 TCGv_i64 fp1
= tcg_temp_new_i64();
10816 gen_load_fpr64(ctx
, fp0
, fs
);
10817 gen_load_fpr64(ctx
, fp1
, ft
);
10818 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
10819 tcg_temp_free_i64(fp1
);
10820 gen_store_fpr64(ctx
, fp0
, fd
);
10821 tcg_temp_free_i64(fp0
);
10825 check_cp1_registers(ctx
, fs
| fd
);
10827 TCGv_i64 fp0
= tcg_temp_new_i64();
10829 gen_load_fpr64(ctx
, fp0
, fs
);
10830 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
10831 gen_store_fpr64(ctx
, fp0
, fd
);
10832 tcg_temp_free_i64(fp0
);
10836 check_cp1_registers(ctx
, fs
| fd
);
10838 TCGv_i64 fp0
= tcg_temp_new_i64();
10840 gen_load_fpr64(ctx
, fp0
, fs
);
10841 if (ctx
->abs2008
) {
10842 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
10844 gen_helper_float_abs_d(fp0
, fp0
);
10846 gen_store_fpr64(ctx
, fp0
, fd
);
10847 tcg_temp_free_i64(fp0
);
10851 check_cp1_registers(ctx
, fs
| fd
);
10853 TCGv_i64 fp0
= tcg_temp_new_i64();
10855 gen_load_fpr64(ctx
, fp0
, fs
);
10856 gen_store_fpr64(ctx
, fp0
, fd
);
10857 tcg_temp_free_i64(fp0
);
10861 check_cp1_registers(ctx
, fs
| fd
);
10863 TCGv_i64 fp0
= tcg_temp_new_i64();
10865 gen_load_fpr64(ctx
, fp0
, fs
);
10866 if (ctx
->abs2008
) {
10867 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
10869 gen_helper_float_chs_d(fp0
, fp0
);
10871 gen_store_fpr64(ctx
, fp0
, fd
);
10872 tcg_temp_free_i64(fp0
);
10875 case OPC_ROUND_L_D
:
10876 check_cp1_64bitmode(ctx
);
10878 TCGv_i64 fp0
= tcg_temp_new_i64();
10880 gen_load_fpr64(ctx
, fp0
, fs
);
10881 if (ctx
->nan2008
) {
10882 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
10884 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
10886 gen_store_fpr64(ctx
, fp0
, fd
);
10887 tcg_temp_free_i64(fp0
);
10890 case OPC_TRUNC_L_D
:
10891 check_cp1_64bitmode(ctx
);
10893 TCGv_i64 fp0
= tcg_temp_new_i64();
10895 gen_load_fpr64(ctx
, fp0
, fs
);
10896 if (ctx
->nan2008
) {
10897 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
10899 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
10901 gen_store_fpr64(ctx
, fp0
, fd
);
10902 tcg_temp_free_i64(fp0
);
10906 check_cp1_64bitmode(ctx
);
10908 TCGv_i64 fp0
= tcg_temp_new_i64();
10910 gen_load_fpr64(ctx
, fp0
, fs
);
10911 if (ctx
->nan2008
) {
10912 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
10914 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
10916 gen_store_fpr64(ctx
, fp0
, fd
);
10917 tcg_temp_free_i64(fp0
);
10920 case OPC_FLOOR_L_D
:
10921 check_cp1_64bitmode(ctx
);
10923 TCGv_i64 fp0
= tcg_temp_new_i64();
10925 gen_load_fpr64(ctx
, fp0
, fs
);
10926 if (ctx
->nan2008
) {
10927 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
10929 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
10931 gen_store_fpr64(ctx
, fp0
, fd
);
10932 tcg_temp_free_i64(fp0
);
10935 case OPC_ROUND_W_D
:
10936 check_cp1_registers(ctx
, fs
);
10938 TCGv_i32 fp32
= tcg_temp_new_i32();
10939 TCGv_i64 fp64
= tcg_temp_new_i64();
10941 gen_load_fpr64(ctx
, fp64
, fs
);
10942 if (ctx
->nan2008
) {
10943 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
10945 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
10947 tcg_temp_free_i64(fp64
);
10948 gen_store_fpr32(ctx
, fp32
, fd
);
10949 tcg_temp_free_i32(fp32
);
10952 case OPC_TRUNC_W_D
:
10953 check_cp1_registers(ctx
, fs
);
10955 TCGv_i32 fp32
= tcg_temp_new_i32();
10956 TCGv_i64 fp64
= tcg_temp_new_i64();
10958 gen_load_fpr64(ctx
, fp64
, fs
);
10959 if (ctx
->nan2008
) {
10960 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
10962 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
10964 tcg_temp_free_i64(fp64
);
10965 gen_store_fpr32(ctx
, fp32
, fd
);
10966 tcg_temp_free_i32(fp32
);
10970 check_cp1_registers(ctx
, fs
);
10972 TCGv_i32 fp32
= tcg_temp_new_i32();
10973 TCGv_i64 fp64
= tcg_temp_new_i64();
10975 gen_load_fpr64(ctx
, fp64
, fs
);
10976 if (ctx
->nan2008
) {
10977 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
10979 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
10981 tcg_temp_free_i64(fp64
);
10982 gen_store_fpr32(ctx
, fp32
, fd
);
10983 tcg_temp_free_i32(fp32
);
10986 case OPC_FLOOR_W_D
:
10987 check_cp1_registers(ctx
, fs
);
10989 TCGv_i32 fp32
= tcg_temp_new_i32();
10990 TCGv_i64 fp64
= tcg_temp_new_i64();
10992 gen_load_fpr64(ctx
, fp64
, fs
);
10993 if (ctx
->nan2008
) {
10994 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
10996 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
10998 tcg_temp_free_i64(fp64
);
10999 gen_store_fpr32(ctx
, fp32
, fd
);
11000 tcg_temp_free_i32(fp32
);
11004 check_insn(ctx
, ISA_MIPS_R6
);
11005 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11008 check_insn(ctx
, ISA_MIPS_R6
);
11009 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11012 check_insn(ctx
, ISA_MIPS_R6
);
11013 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11016 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11017 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11020 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11022 TCGLabel
*l1
= gen_new_label();
11026 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11028 fp0
= tcg_temp_new_i64();
11029 gen_load_fpr64(ctx
, fp0
, fs
);
11030 gen_store_fpr64(ctx
, fp0
, fd
);
11031 tcg_temp_free_i64(fp0
);
11036 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11038 TCGLabel
*l1
= gen_new_label();
11042 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11043 fp0
= tcg_temp_new_i64();
11044 gen_load_fpr64(ctx
, fp0
, fs
);
11045 gen_store_fpr64(ctx
, fp0
, fd
);
11046 tcg_temp_free_i64(fp0
);
11052 check_cp1_registers(ctx
, fs
| fd
);
11054 TCGv_i64 fp0
= tcg_temp_new_i64();
11056 gen_load_fpr64(ctx
, fp0
, fs
);
11057 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11058 gen_store_fpr64(ctx
, fp0
, fd
);
11059 tcg_temp_free_i64(fp0
);
11063 check_cp1_registers(ctx
, fs
| fd
);
11065 TCGv_i64 fp0
= tcg_temp_new_i64();
11067 gen_load_fpr64(ctx
, fp0
, fs
);
11068 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11069 gen_store_fpr64(ctx
, fp0
, fd
);
11070 tcg_temp_free_i64(fp0
);
11074 check_insn(ctx
, ISA_MIPS_R6
);
11076 TCGv_i64 fp0
= tcg_temp_new_i64();
11077 TCGv_i64 fp1
= tcg_temp_new_i64();
11078 TCGv_i64 fp2
= tcg_temp_new_i64();
11079 gen_load_fpr64(ctx
, fp0
, fs
);
11080 gen_load_fpr64(ctx
, fp1
, ft
);
11081 gen_load_fpr64(ctx
, fp2
, fd
);
11082 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11083 gen_store_fpr64(ctx
, fp2
, fd
);
11084 tcg_temp_free_i64(fp2
);
11085 tcg_temp_free_i64(fp1
);
11086 tcg_temp_free_i64(fp0
);
11090 check_insn(ctx
, ISA_MIPS_R6
);
11092 TCGv_i64 fp0
= tcg_temp_new_i64();
11093 TCGv_i64 fp1
= tcg_temp_new_i64();
11094 TCGv_i64 fp2
= tcg_temp_new_i64();
11095 gen_load_fpr64(ctx
, fp0
, fs
);
11096 gen_load_fpr64(ctx
, fp1
, ft
);
11097 gen_load_fpr64(ctx
, fp2
, fd
);
11098 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11099 gen_store_fpr64(ctx
, fp2
, fd
);
11100 tcg_temp_free_i64(fp2
);
11101 tcg_temp_free_i64(fp1
);
11102 tcg_temp_free_i64(fp0
);
11106 check_insn(ctx
, ISA_MIPS_R6
);
11108 TCGv_i64 fp0
= tcg_temp_new_i64();
11109 gen_load_fpr64(ctx
, fp0
, fs
);
11110 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11111 gen_store_fpr64(ctx
, fp0
, fd
);
11112 tcg_temp_free_i64(fp0
);
11116 check_insn(ctx
, ISA_MIPS_R6
);
11118 TCGv_i64 fp0
= tcg_temp_new_i64();
11119 gen_load_fpr64(ctx
, fp0
, fs
);
11120 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11121 gen_store_fpr64(ctx
, fp0
, fd
);
11122 tcg_temp_free_i64(fp0
);
11125 case OPC_MIN_D
: /* OPC_RECIP2_D */
11126 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11128 TCGv_i64 fp0
= tcg_temp_new_i64();
11129 TCGv_i64 fp1
= tcg_temp_new_i64();
11130 gen_load_fpr64(ctx
, fp0
, fs
);
11131 gen_load_fpr64(ctx
, fp1
, ft
);
11132 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11133 gen_store_fpr64(ctx
, fp1
, fd
);
11134 tcg_temp_free_i64(fp1
);
11135 tcg_temp_free_i64(fp0
);
11138 check_cp1_64bitmode(ctx
);
11140 TCGv_i64 fp0
= tcg_temp_new_i64();
11141 TCGv_i64 fp1
= tcg_temp_new_i64();
11143 gen_load_fpr64(ctx
, fp0
, fs
);
11144 gen_load_fpr64(ctx
, fp1
, ft
);
11145 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11146 tcg_temp_free_i64(fp1
);
11147 gen_store_fpr64(ctx
, fp0
, fd
);
11148 tcg_temp_free_i64(fp0
);
11152 case OPC_MINA_D
: /* OPC_RECIP1_D */
11153 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11155 TCGv_i64 fp0
= tcg_temp_new_i64();
11156 TCGv_i64 fp1
= tcg_temp_new_i64();
11157 gen_load_fpr64(ctx
, fp0
, fs
);
11158 gen_load_fpr64(ctx
, fp1
, ft
);
11159 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11160 gen_store_fpr64(ctx
, fp1
, fd
);
11161 tcg_temp_free_i64(fp1
);
11162 tcg_temp_free_i64(fp0
);
11165 check_cp1_64bitmode(ctx
);
11167 TCGv_i64 fp0
= tcg_temp_new_i64();
11169 gen_load_fpr64(ctx
, fp0
, fs
);
11170 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11171 gen_store_fpr64(ctx
, fp0
, fd
);
11172 tcg_temp_free_i64(fp0
);
11176 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11177 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11179 TCGv_i64 fp0
= tcg_temp_new_i64();
11180 TCGv_i64 fp1
= tcg_temp_new_i64();
11181 gen_load_fpr64(ctx
, fp0
, fs
);
11182 gen_load_fpr64(ctx
, fp1
, ft
);
11183 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11184 gen_store_fpr64(ctx
, fp1
, fd
);
11185 tcg_temp_free_i64(fp1
);
11186 tcg_temp_free_i64(fp0
);
11189 check_cp1_64bitmode(ctx
);
11191 TCGv_i64 fp0
= tcg_temp_new_i64();
11193 gen_load_fpr64(ctx
, fp0
, fs
);
11194 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11195 gen_store_fpr64(ctx
, fp0
, fd
);
11196 tcg_temp_free_i64(fp0
);
11200 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11201 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11203 TCGv_i64 fp0
= tcg_temp_new_i64();
11204 TCGv_i64 fp1
= tcg_temp_new_i64();
11205 gen_load_fpr64(ctx
, fp0
, fs
);
11206 gen_load_fpr64(ctx
, fp1
, ft
);
11207 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11208 gen_store_fpr64(ctx
, fp1
, fd
);
11209 tcg_temp_free_i64(fp1
);
11210 tcg_temp_free_i64(fp0
);
11213 check_cp1_64bitmode(ctx
);
11215 TCGv_i64 fp0
= tcg_temp_new_i64();
11216 TCGv_i64 fp1
= tcg_temp_new_i64();
11218 gen_load_fpr64(ctx
, fp0
, fs
);
11219 gen_load_fpr64(ctx
, fp1
, ft
);
11220 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11221 tcg_temp_free_i64(fp1
);
11222 gen_store_fpr64(ctx
, fp0
, fd
);
11223 tcg_temp_free_i64(fp0
);
11230 case OPC_CMP_UEQ_D
:
11231 case OPC_CMP_OLT_D
:
11232 case OPC_CMP_ULT_D
:
11233 case OPC_CMP_OLE_D
:
11234 case OPC_CMP_ULE_D
:
11236 case OPC_CMP_NGLE_D
:
11237 case OPC_CMP_SEQ_D
:
11238 case OPC_CMP_NGL_D
:
11240 case OPC_CMP_NGE_D
:
11242 case OPC_CMP_NGT_D
:
11243 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11244 if (ctx
->opcode
& (1 << 6)) {
11245 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11247 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11251 check_cp1_registers(ctx
, fs
);
11253 TCGv_i32 fp32
= tcg_temp_new_i32();
11254 TCGv_i64 fp64
= tcg_temp_new_i64();
11256 gen_load_fpr64(ctx
, fp64
, fs
);
11257 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11258 tcg_temp_free_i64(fp64
);
11259 gen_store_fpr32(ctx
, fp32
, fd
);
11260 tcg_temp_free_i32(fp32
);
11264 check_cp1_registers(ctx
, fs
);
11266 TCGv_i32 fp32
= tcg_temp_new_i32();
11267 TCGv_i64 fp64
= tcg_temp_new_i64();
11269 gen_load_fpr64(ctx
, fp64
, fs
);
11270 if (ctx
->nan2008
) {
11271 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11273 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11275 tcg_temp_free_i64(fp64
);
11276 gen_store_fpr32(ctx
, fp32
, fd
);
11277 tcg_temp_free_i32(fp32
);
11281 check_cp1_64bitmode(ctx
);
11283 TCGv_i64 fp0
= tcg_temp_new_i64();
11285 gen_load_fpr64(ctx
, fp0
, fs
);
11286 if (ctx
->nan2008
) {
11287 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11289 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11291 gen_store_fpr64(ctx
, fp0
, fd
);
11292 tcg_temp_free_i64(fp0
);
11297 TCGv_i32 fp0
= tcg_temp_new_i32();
11299 gen_load_fpr32(ctx
, fp0
, fs
);
11300 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11301 gen_store_fpr32(ctx
, fp0
, fd
);
11302 tcg_temp_free_i32(fp0
);
11306 check_cp1_registers(ctx
, fd
);
11308 TCGv_i32 fp32
= tcg_temp_new_i32();
11309 TCGv_i64 fp64
= tcg_temp_new_i64();
11311 gen_load_fpr32(ctx
, fp32
, fs
);
11312 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11313 tcg_temp_free_i32(fp32
);
11314 gen_store_fpr64(ctx
, fp64
, fd
);
11315 tcg_temp_free_i64(fp64
);
11319 check_cp1_64bitmode(ctx
);
11321 TCGv_i32 fp32
= tcg_temp_new_i32();
11322 TCGv_i64 fp64
= tcg_temp_new_i64();
11324 gen_load_fpr64(ctx
, fp64
, fs
);
11325 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11326 tcg_temp_free_i64(fp64
);
11327 gen_store_fpr32(ctx
, fp32
, fd
);
11328 tcg_temp_free_i32(fp32
);
11332 check_cp1_64bitmode(ctx
);
11334 TCGv_i64 fp0
= tcg_temp_new_i64();
11336 gen_load_fpr64(ctx
, fp0
, fs
);
11337 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11338 gen_store_fpr64(ctx
, fp0
, fd
);
11339 tcg_temp_free_i64(fp0
);
11342 case OPC_CVT_PS_PW
:
11345 TCGv_i64 fp0
= tcg_temp_new_i64();
11347 gen_load_fpr64(ctx
, fp0
, fs
);
11348 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11349 gen_store_fpr64(ctx
, fp0
, fd
);
11350 tcg_temp_free_i64(fp0
);
11356 TCGv_i64 fp0
= tcg_temp_new_i64();
11357 TCGv_i64 fp1
= tcg_temp_new_i64();
11359 gen_load_fpr64(ctx
, fp0
, fs
);
11360 gen_load_fpr64(ctx
, fp1
, ft
);
11361 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11362 tcg_temp_free_i64(fp1
);
11363 gen_store_fpr64(ctx
, fp0
, fd
);
11364 tcg_temp_free_i64(fp0
);
11370 TCGv_i64 fp0
= tcg_temp_new_i64();
11371 TCGv_i64 fp1
= tcg_temp_new_i64();
11373 gen_load_fpr64(ctx
, fp0
, fs
);
11374 gen_load_fpr64(ctx
, fp1
, ft
);
11375 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11376 tcg_temp_free_i64(fp1
);
11377 gen_store_fpr64(ctx
, fp0
, fd
);
11378 tcg_temp_free_i64(fp0
);
11384 TCGv_i64 fp0
= tcg_temp_new_i64();
11385 TCGv_i64 fp1
= tcg_temp_new_i64();
11387 gen_load_fpr64(ctx
, fp0
, fs
);
11388 gen_load_fpr64(ctx
, fp1
, ft
);
11389 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11390 tcg_temp_free_i64(fp1
);
11391 gen_store_fpr64(ctx
, fp0
, fd
);
11392 tcg_temp_free_i64(fp0
);
11398 TCGv_i64 fp0
= tcg_temp_new_i64();
11400 gen_load_fpr64(ctx
, fp0
, fs
);
11401 gen_helper_float_abs_ps(fp0
, fp0
);
11402 gen_store_fpr64(ctx
, fp0
, fd
);
11403 tcg_temp_free_i64(fp0
);
11409 TCGv_i64 fp0
= tcg_temp_new_i64();
11411 gen_load_fpr64(ctx
, fp0
, fs
);
11412 gen_store_fpr64(ctx
, fp0
, fd
);
11413 tcg_temp_free_i64(fp0
);
11419 TCGv_i64 fp0
= tcg_temp_new_i64();
11421 gen_load_fpr64(ctx
, fp0
, fs
);
11422 gen_helper_float_chs_ps(fp0
, fp0
);
11423 gen_store_fpr64(ctx
, fp0
, fd
);
11424 tcg_temp_free_i64(fp0
);
11429 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11434 TCGLabel
*l1
= gen_new_label();
11438 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11440 fp0
= tcg_temp_new_i64();
11441 gen_load_fpr64(ctx
, fp0
, fs
);
11442 gen_store_fpr64(ctx
, fp0
, fd
);
11443 tcg_temp_free_i64(fp0
);
11450 TCGLabel
*l1
= gen_new_label();
11454 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11455 fp0
= tcg_temp_new_i64();
11456 gen_load_fpr64(ctx
, fp0
, fs
);
11457 gen_store_fpr64(ctx
, fp0
, fd
);
11458 tcg_temp_free_i64(fp0
);
11466 TCGv_i64 fp0
= tcg_temp_new_i64();
11467 TCGv_i64 fp1
= tcg_temp_new_i64();
11469 gen_load_fpr64(ctx
, fp0
, ft
);
11470 gen_load_fpr64(ctx
, fp1
, fs
);
11471 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11472 tcg_temp_free_i64(fp1
);
11473 gen_store_fpr64(ctx
, fp0
, fd
);
11474 tcg_temp_free_i64(fp0
);
11480 TCGv_i64 fp0
= tcg_temp_new_i64();
11481 TCGv_i64 fp1
= tcg_temp_new_i64();
11483 gen_load_fpr64(ctx
, fp0
, ft
);
11484 gen_load_fpr64(ctx
, fp1
, fs
);
11485 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11486 tcg_temp_free_i64(fp1
);
11487 gen_store_fpr64(ctx
, fp0
, fd
);
11488 tcg_temp_free_i64(fp0
);
11491 case OPC_RECIP2_PS
:
11494 TCGv_i64 fp0
= tcg_temp_new_i64();
11495 TCGv_i64 fp1
= tcg_temp_new_i64();
11497 gen_load_fpr64(ctx
, fp0
, fs
);
11498 gen_load_fpr64(ctx
, fp1
, ft
);
11499 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11500 tcg_temp_free_i64(fp1
);
11501 gen_store_fpr64(ctx
, fp0
, fd
);
11502 tcg_temp_free_i64(fp0
);
11505 case OPC_RECIP1_PS
:
11508 TCGv_i64 fp0
= tcg_temp_new_i64();
11510 gen_load_fpr64(ctx
, fp0
, fs
);
11511 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11512 gen_store_fpr64(ctx
, fp0
, fd
);
11513 tcg_temp_free_i64(fp0
);
11516 case OPC_RSQRT1_PS
:
11519 TCGv_i64 fp0
= tcg_temp_new_i64();
11521 gen_load_fpr64(ctx
, fp0
, fs
);
11522 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11523 gen_store_fpr64(ctx
, fp0
, fd
);
11524 tcg_temp_free_i64(fp0
);
11527 case OPC_RSQRT2_PS
:
11530 TCGv_i64 fp0
= tcg_temp_new_i64();
11531 TCGv_i64 fp1
= tcg_temp_new_i64();
11533 gen_load_fpr64(ctx
, fp0
, fs
);
11534 gen_load_fpr64(ctx
, fp1
, ft
);
11535 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
11536 tcg_temp_free_i64(fp1
);
11537 gen_store_fpr64(ctx
, fp0
, fd
);
11538 tcg_temp_free_i64(fp0
);
11542 check_cp1_64bitmode(ctx
);
11544 TCGv_i32 fp0
= tcg_temp_new_i32();
11546 gen_load_fpr32h(ctx
, fp0
, fs
);
11547 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11548 gen_store_fpr32(ctx
, fp0
, fd
);
11549 tcg_temp_free_i32(fp0
);
11552 case OPC_CVT_PW_PS
:
11555 TCGv_i64 fp0
= tcg_temp_new_i64();
11557 gen_load_fpr64(ctx
, fp0
, fs
);
11558 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11559 gen_store_fpr64(ctx
, fp0
, fd
);
11560 tcg_temp_free_i64(fp0
);
11564 check_cp1_64bitmode(ctx
);
11566 TCGv_i32 fp0
= tcg_temp_new_i32();
11568 gen_load_fpr32(ctx
, fp0
, fs
);
11569 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11570 gen_store_fpr32(ctx
, fp0
, fd
);
11571 tcg_temp_free_i32(fp0
);
11577 TCGv_i32 fp0
= tcg_temp_new_i32();
11578 TCGv_i32 fp1
= tcg_temp_new_i32();
11580 gen_load_fpr32(ctx
, fp0
, fs
);
11581 gen_load_fpr32(ctx
, fp1
, ft
);
11582 gen_store_fpr32h(ctx
, fp0
, fd
);
11583 gen_store_fpr32(ctx
, fp1
, fd
);
11584 tcg_temp_free_i32(fp0
);
11585 tcg_temp_free_i32(fp1
);
11591 TCGv_i32 fp0
= tcg_temp_new_i32();
11592 TCGv_i32 fp1
= tcg_temp_new_i32();
11594 gen_load_fpr32(ctx
, fp0
, fs
);
11595 gen_load_fpr32h(ctx
, fp1
, ft
);
11596 gen_store_fpr32(ctx
, fp1
, fd
);
11597 gen_store_fpr32h(ctx
, fp0
, fd
);
11598 tcg_temp_free_i32(fp0
);
11599 tcg_temp_free_i32(fp1
);
11605 TCGv_i32 fp0
= tcg_temp_new_i32();
11606 TCGv_i32 fp1
= tcg_temp_new_i32();
11608 gen_load_fpr32h(ctx
, fp0
, fs
);
11609 gen_load_fpr32(ctx
, fp1
, ft
);
11610 gen_store_fpr32(ctx
, fp1
, fd
);
11611 gen_store_fpr32h(ctx
, fp0
, fd
);
11612 tcg_temp_free_i32(fp0
);
11613 tcg_temp_free_i32(fp1
);
11619 TCGv_i32 fp0
= tcg_temp_new_i32();
11620 TCGv_i32 fp1
= tcg_temp_new_i32();
11622 gen_load_fpr32h(ctx
, fp0
, fs
);
11623 gen_load_fpr32h(ctx
, fp1
, ft
);
11624 gen_store_fpr32(ctx
, fp1
, fd
);
11625 gen_store_fpr32h(ctx
, fp0
, fd
);
11626 tcg_temp_free_i32(fp0
);
11627 tcg_temp_free_i32(fp1
);
11631 case OPC_CMP_UN_PS
:
11632 case OPC_CMP_EQ_PS
:
11633 case OPC_CMP_UEQ_PS
:
11634 case OPC_CMP_OLT_PS
:
11635 case OPC_CMP_ULT_PS
:
11636 case OPC_CMP_OLE_PS
:
11637 case OPC_CMP_ULE_PS
:
11638 case OPC_CMP_SF_PS
:
11639 case OPC_CMP_NGLE_PS
:
11640 case OPC_CMP_SEQ_PS
:
11641 case OPC_CMP_NGL_PS
:
11642 case OPC_CMP_LT_PS
:
11643 case OPC_CMP_NGE_PS
:
11644 case OPC_CMP_LE_PS
:
11645 case OPC_CMP_NGT_PS
:
11646 if (ctx
->opcode
& (1 << 6)) {
11647 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
11649 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
11653 MIPS_INVAL("farith");
11654 gen_reserved_instruction(ctx
);
11659 /* Coprocessor 3 (FPU) */
11660 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
11661 int fd
, int fs
, int base
, int index
)
11663 TCGv t0
= tcg_temp_new();
11666 gen_load_gpr(t0
, index
);
11667 } else if (index
== 0) {
11668 gen_load_gpr(t0
, base
);
11670 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
11673 * Don't do NOP if destination is zero: we must perform the actual
11680 TCGv_i32 fp0
= tcg_temp_new_i32();
11682 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
11683 tcg_gen_trunc_tl_i32(fp0
, t0
);
11684 gen_store_fpr32(ctx
, fp0
, fd
);
11685 tcg_temp_free_i32(fp0
);
11690 check_cp1_registers(ctx
, fd
);
11692 TCGv_i64 fp0
= tcg_temp_new_i64();
11693 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11694 gen_store_fpr64(ctx
, fp0
, fd
);
11695 tcg_temp_free_i64(fp0
);
11699 check_cp1_64bitmode(ctx
);
11700 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11702 TCGv_i64 fp0
= tcg_temp_new_i64();
11704 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11705 gen_store_fpr64(ctx
, fp0
, fd
);
11706 tcg_temp_free_i64(fp0
);
11712 TCGv_i32 fp0
= tcg_temp_new_i32();
11713 gen_load_fpr32(ctx
, fp0
, fs
);
11714 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
11715 tcg_temp_free_i32(fp0
);
11720 check_cp1_registers(ctx
, fs
);
11722 TCGv_i64 fp0
= tcg_temp_new_i64();
11723 gen_load_fpr64(ctx
, fp0
, fs
);
11724 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11725 tcg_temp_free_i64(fp0
);
11729 check_cp1_64bitmode(ctx
);
11730 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11732 TCGv_i64 fp0
= tcg_temp_new_i64();
11733 gen_load_fpr64(ctx
, fp0
, fs
);
11734 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11735 tcg_temp_free_i64(fp0
);
11742 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
11743 int fd
, int fr
, int fs
, int ft
)
11749 TCGv t0
= tcg_temp_local_new();
11750 TCGv_i32 fp
= tcg_temp_new_i32();
11751 TCGv_i32 fph
= tcg_temp_new_i32();
11752 TCGLabel
*l1
= gen_new_label();
11753 TCGLabel
*l2
= gen_new_label();
11755 gen_load_gpr(t0
, fr
);
11756 tcg_gen_andi_tl(t0
, t0
, 0x7);
11758 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
11759 gen_load_fpr32(ctx
, fp
, fs
);
11760 gen_load_fpr32h(ctx
, fph
, fs
);
11761 gen_store_fpr32(ctx
, fp
, fd
);
11762 gen_store_fpr32h(ctx
, fph
, fd
);
11765 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
11767 #ifdef TARGET_WORDS_BIGENDIAN
11768 gen_load_fpr32(ctx
, fp
, fs
);
11769 gen_load_fpr32h(ctx
, fph
, ft
);
11770 gen_store_fpr32h(ctx
, fp
, fd
);
11771 gen_store_fpr32(ctx
, fph
, fd
);
11773 gen_load_fpr32h(ctx
, fph
, fs
);
11774 gen_load_fpr32(ctx
, fp
, ft
);
11775 gen_store_fpr32(ctx
, fph
, fd
);
11776 gen_store_fpr32h(ctx
, fp
, fd
);
11779 tcg_temp_free_i32(fp
);
11780 tcg_temp_free_i32(fph
);
11786 TCGv_i32 fp0
= tcg_temp_new_i32();
11787 TCGv_i32 fp1
= tcg_temp_new_i32();
11788 TCGv_i32 fp2
= tcg_temp_new_i32();
11790 gen_load_fpr32(ctx
, fp0
, fs
);
11791 gen_load_fpr32(ctx
, fp1
, ft
);
11792 gen_load_fpr32(ctx
, fp2
, fr
);
11793 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11794 tcg_temp_free_i32(fp0
);
11795 tcg_temp_free_i32(fp1
);
11796 gen_store_fpr32(ctx
, fp2
, fd
);
11797 tcg_temp_free_i32(fp2
);
11802 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11804 TCGv_i64 fp0
= tcg_temp_new_i64();
11805 TCGv_i64 fp1
= tcg_temp_new_i64();
11806 TCGv_i64 fp2
= tcg_temp_new_i64();
11808 gen_load_fpr64(ctx
, fp0
, fs
);
11809 gen_load_fpr64(ctx
, fp1
, ft
);
11810 gen_load_fpr64(ctx
, fp2
, fr
);
11811 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11812 tcg_temp_free_i64(fp0
);
11813 tcg_temp_free_i64(fp1
);
11814 gen_store_fpr64(ctx
, fp2
, fd
);
11815 tcg_temp_free_i64(fp2
);
11821 TCGv_i64 fp0
= tcg_temp_new_i64();
11822 TCGv_i64 fp1
= tcg_temp_new_i64();
11823 TCGv_i64 fp2
= tcg_temp_new_i64();
11825 gen_load_fpr64(ctx
, fp0
, fs
);
11826 gen_load_fpr64(ctx
, fp1
, ft
);
11827 gen_load_fpr64(ctx
, fp2
, fr
);
11828 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11829 tcg_temp_free_i64(fp0
);
11830 tcg_temp_free_i64(fp1
);
11831 gen_store_fpr64(ctx
, fp2
, fd
);
11832 tcg_temp_free_i64(fp2
);
11838 TCGv_i32 fp0
= tcg_temp_new_i32();
11839 TCGv_i32 fp1
= tcg_temp_new_i32();
11840 TCGv_i32 fp2
= tcg_temp_new_i32();
11842 gen_load_fpr32(ctx
, fp0
, fs
);
11843 gen_load_fpr32(ctx
, fp1
, ft
);
11844 gen_load_fpr32(ctx
, fp2
, fr
);
11845 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11846 tcg_temp_free_i32(fp0
);
11847 tcg_temp_free_i32(fp1
);
11848 gen_store_fpr32(ctx
, fp2
, fd
);
11849 tcg_temp_free_i32(fp2
);
11854 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11856 TCGv_i64 fp0
= tcg_temp_new_i64();
11857 TCGv_i64 fp1
= tcg_temp_new_i64();
11858 TCGv_i64 fp2
= tcg_temp_new_i64();
11860 gen_load_fpr64(ctx
, fp0
, fs
);
11861 gen_load_fpr64(ctx
, fp1
, ft
);
11862 gen_load_fpr64(ctx
, fp2
, fr
);
11863 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11864 tcg_temp_free_i64(fp0
);
11865 tcg_temp_free_i64(fp1
);
11866 gen_store_fpr64(ctx
, fp2
, fd
);
11867 tcg_temp_free_i64(fp2
);
11873 TCGv_i64 fp0
= tcg_temp_new_i64();
11874 TCGv_i64 fp1
= tcg_temp_new_i64();
11875 TCGv_i64 fp2
= tcg_temp_new_i64();
11877 gen_load_fpr64(ctx
, fp0
, fs
);
11878 gen_load_fpr64(ctx
, fp1
, ft
);
11879 gen_load_fpr64(ctx
, fp2
, fr
);
11880 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11881 tcg_temp_free_i64(fp0
);
11882 tcg_temp_free_i64(fp1
);
11883 gen_store_fpr64(ctx
, fp2
, fd
);
11884 tcg_temp_free_i64(fp2
);
11890 TCGv_i32 fp0
= tcg_temp_new_i32();
11891 TCGv_i32 fp1
= tcg_temp_new_i32();
11892 TCGv_i32 fp2
= tcg_temp_new_i32();
11894 gen_load_fpr32(ctx
, fp0
, fs
);
11895 gen_load_fpr32(ctx
, fp1
, ft
);
11896 gen_load_fpr32(ctx
, fp2
, fr
);
11897 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11898 tcg_temp_free_i32(fp0
);
11899 tcg_temp_free_i32(fp1
);
11900 gen_store_fpr32(ctx
, fp2
, fd
);
11901 tcg_temp_free_i32(fp2
);
11906 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11908 TCGv_i64 fp0
= tcg_temp_new_i64();
11909 TCGv_i64 fp1
= tcg_temp_new_i64();
11910 TCGv_i64 fp2
= tcg_temp_new_i64();
11912 gen_load_fpr64(ctx
, fp0
, fs
);
11913 gen_load_fpr64(ctx
, fp1
, ft
);
11914 gen_load_fpr64(ctx
, fp2
, fr
);
11915 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11916 tcg_temp_free_i64(fp0
);
11917 tcg_temp_free_i64(fp1
);
11918 gen_store_fpr64(ctx
, fp2
, fd
);
11919 tcg_temp_free_i64(fp2
);
11925 TCGv_i64 fp0
= tcg_temp_new_i64();
11926 TCGv_i64 fp1
= tcg_temp_new_i64();
11927 TCGv_i64 fp2
= tcg_temp_new_i64();
11929 gen_load_fpr64(ctx
, fp0
, fs
);
11930 gen_load_fpr64(ctx
, fp1
, ft
);
11931 gen_load_fpr64(ctx
, fp2
, fr
);
11932 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11933 tcg_temp_free_i64(fp0
);
11934 tcg_temp_free_i64(fp1
);
11935 gen_store_fpr64(ctx
, fp2
, fd
);
11936 tcg_temp_free_i64(fp2
);
11942 TCGv_i32 fp0
= tcg_temp_new_i32();
11943 TCGv_i32 fp1
= tcg_temp_new_i32();
11944 TCGv_i32 fp2
= tcg_temp_new_i32();
11946 gen_load_fpr32(ctx
, fp0
, fs
);
11947 gen_load_fpr32(ctx
, fp1
, ft
);
11948 gen_load_fpr32(ctx
, fp2
, fr
);
11949 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11950 tcg_temp_free_i32(fp0
);
11951 tcg_temp_free_i32(fp1
);
11952 gen_store_fpr32(ctx
, fp2
, fd
);
11953 tcg_temp_free_i32(fp2
);
11958 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11960 TCGv_i64 fp0
= tcg_temp_new_i64();
11961 TCGv_i64 fp1
= tcg_temp_new_i64();
11962 TCGv_i64 fp2
= tcg_temp_new_i64();
11964 gen_load_fpr64(ctx
, fp0
, fs
);
11965 gen_load_fpr64(ctx
, fp1
, ft
);
11966 gen_load_fpr64(ctx
, fp2
, fr
);
11967 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11968 tcg_temp_free_i64(fp0
);
11969 tcg_temp_free_i64(fp1
);
11970 gen_store_fpr64(ctx
, fp2
, fd
);
11971 tcg_temp_free_i64(fp2
);
11977 TCGv_i64 fp0
= tcg_temp_new_i64();
11978 TCGv_i64 fp1
= tcg_temp_new_i64();
11979 TCGv_i64 fp2
= tcg_temp_new_i64();
11981 gen_load_fpr64(ctx
, fp0
, fs
);
11982 gen_load_fpr64(ctx
, fp1
, ft
);
11983 gen_load_fpr64(ctx
, fp2
, fr
);
11984 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11985 tcg_temp_free_i64(fp0
);
11986 tcg_temp_free_i64(fp1
);
11987 gen_store_fpr64(ctx
, fp2
, fd
);
11988 tcg_temp_free_i64(fp2
);
11992 MIPS_INVAL("flt3_arith");
11993 gen_reserved_instruction(ctx
);
11998 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12002 #if !defined(CONFIG_USER_ONLY)
12004 * The Linux kernel will emulate rdhwr if it's not supported natively.
12005 * Therefore only check the ISA in system mode.
12007 check_insn(ctx
, ISA_MIPS_R2
);
12009 t0
= tcg_temp_new();
12013 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12014 gen_store_gpr(t0
, rt
);
12017 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12018 gen_store_gpr(t0
, rt
);
12021 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12024 gen_helper_rdhwr_cc(t0
, cpu_env
);
12025 gen_store_gpr(t0
, rt
);
12027 * Break the TB to be able to take timer interrupts immediately
12028 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12029 * we break completely out of translated code.
12031 gen_save_pc(ctx
->base
.pc_next
+ 4);
12032 ctx
->base
.is_jmp
= DISAS_EXIT
;
12035 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12036 gen_store_gpr(t0
, rt
);
12039 check_insn(ctx
, ISA_MIPS_R6
);
12042 * Performance counter registers are not implemented other than
12043 * control register 0.
12045 generate_exception(ctx
, EXCP_RI
);
12047 gen_helper_rdhwr_performance(t0
, cpu_env
);
12048 gen_store_gpr(t0
, rt
);
12051 check_insn(ctx
, ISA_MIPS_R6
);
12052 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12053 gen_store_gpr(t0
, rt
);
12056 #if defined(CONFIG_USER_ONLY)
12057 tcg_gen_ld_tl(t0
, cpu_env
,
12058 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12059 gen_store_gpr(t0
, rt
);
12062 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12063 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12064 tcg_gen_ld_tl(t0
, cpu_env
,
12065 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12066 gen_store_gpr(t0
, rt
);
12068 gen_reserved_instruction(ctx
);
12072 default: /* Invalid */
12073 MIPS_INVAL("rdhwr");
12074 gen_reserved_instruction(ctx
);
12080 static inline void clear_branch_hflags(DisasContext
*ctx
)
12082 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12083 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12084 save_cpu_state(ctx
, 0);
12087 * It is not safe to save ctx->hflags as hflags may be changed
12088 * in execution time by the instruction in delay / forbidden slot.
12090 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12094 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12096 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12097 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12098 /* Branches completion */
12099 clear_branch_hflags(ctx
);
12100 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12101 /* FIXME: Need to clear can_do_io. */
12102 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12103 case MIPS_HFLAG_FBNSLOT
:
12104 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12107 /* unconditional branch */
12108 if (proc_hflags
& MIPS_HFLAG_BX
) {
12109 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12111 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12113 case MIPS_HFLAG_BL
:
12114 /* blikely taken case */
12115 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12117 case MIPS_HFLAG_BC
:
12118 /* Conditional branch */
12120 TCGLabel
*l1
= gen_new_label();
12122 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12123 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12125 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12128 case MIPS_HFLAG_BR
:
12129 /* unconditional branch to register */
12130 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12131 TCGv t0
= tcg_temp_new();
12132 TCGv_i32 t1
= tcg_temp_new_i32();
12134 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12135 tcg_gen_trunc_tl_i32(t1
, t0
);
12137 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12138 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12139 tcg_gen_or_i32(hflags
, hflags
, t1
);
12140 tcg_temp_free_i32(t1
);
12142 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12144 tcg_gen_mov_tl(cpu_PC
, btarget
);
12146 if (ctx
->base
.singlestep_enabled
) {
12147 save_cpu_state(ctx
, 0);
12148 gen_helper_raise_exception_debug(cpu_env
);
12150 tcg_gen_lookup_and_goto_ptr();
12153 LOG_DISAS("unknown branch 0x%x\n", proc_hflags
);
12154 gen_reserved_instruction(ctx
);
12159 /* Compact Branches */
12160 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12161 int rs
, int rt
, int32_t offset
)
12163 int bcond_compute
= 0;
12164 TCGv t0
= tcg_temp_new();
12165 TCGv t1
= tcg_temp_new();
12166 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12168 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12169 #ifdef MIPS_DEBUG_DISAS
12170 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12171 "\n", ctx
->base
.pc_next
);
12173 gen_reserved_instruction(ctx
);
12177 /* Load needed operands and calculate btarget */
12179 /* compact branch */
12180 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12181 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12182 gen_load_gpr(t0
, rs
);
12183 gen_load_gpr(t1
, rt
);
12185 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12186 if (rs
<= rt
&& rs
== 0) {
12187 /* OPC_BEQZALC, OPC_BNEZALC */
12188 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12191 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12192 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12193 gen_load_gpr(t0
, rs
);
12194 gen_load_gpr(t1
, rt
);
12196 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12198 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12199 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12200 if (rs
== 0 || rs
== rt
) {
12201 /* OPC_BLEZALC, OPC_BGEZALC */
12202 /* OPC_BGTZALC, OPC_BLTZALC */
12203 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12205 gen_load_gpr(t0
, rs
);
12206 gen_load_gpr(t1
, rt
);
12208 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12212 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12217 /* OPC_BEQZC, OPC_BNEZC */
12218 gen_load_gpr(t0
, rs
);
12220 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12222 /* OPC_JIC, OPC_JIALC */
12223 TCGv tbase
= tcg_temp_new();
12224 TCGv toffset
= tcg_temp_new();
12226 gen_load_gpr(tbase
, rt
);
12227 tcg_gen_movi_tl(toffset
, offset
);
12228 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12229 tcg_temp_free(tbase
);
12230 tcg_temp_free(toffset
);
12234 MIPS_INVAL("Compact branch/jump");
12235 gen_reserved_instruction(ctx
);
12239 if (bcond_compute
== 0) {
12240 /* Unconditional compact branch */
12243 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12246 ctx
->hflags
|= MIPS_HFLAG_BR
;
12249 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12252 ctx
->hflags
|= MIPS_HFLAG_B
;
12255 MIPS_INVAL("Compact branch/jump");
12256 gen_reserved_instruction(ctx
);
12260 /* Generating branch here as compact branches don't have delay slot */
12261 gen_branch(ctx
, 4);
12263 /* Conditional compact branch */
12264 TCGLabel
*fs
= gen_new_label();
12265 save_cpu_state(ctx
, 0);
12268 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12269 if (rs
== 0 && rt
!= 0) {
12271 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12272 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12274 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12277 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12280 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12281 if (rs
== 0 && rt
!= 0) {
12283 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12284 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12286 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12289 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12292 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12293 if (rs
== 0 && rt
!= 0) {
12295 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12296 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12298 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12301 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12304 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12305 if (rs
== 0 && rt
!= 0) {
12307 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12308 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12310 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12313 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12316 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12317 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12319 /* OPC_BOVC, OPC_BNVC */
12320 TCGv t2
= tcg_temp_new();
12321 TCGv t3
= tcg_temp_new();
12322 TCGv t4
= tcg_temp_new();
12323 TCGv input_overflow
= tcg_temp_new();
12325 gen_load_gpr(t0
, rs
);
12326 gen_load_gpr(t1
, rt
);
12327 tcg_gen_ext32s_tl(t2
, t0
);
12328 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12329 tcg_gen_ext32s_tl(t3
, t1
);
12330 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12331 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12333 tcg_gen_add_tl(t4
, t2
, t3
);
12334 tcg_gen_ext32s_tl(t4
, t4
);
12335 tcg_gen_xor_tl(t2
, t2
, t3
);
12336 tcg_gen_xor_tl(t3
, t4
, t3
);
12337 tcg_gen_andc_tl(t2
, t3
, t2
);
12338 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12339 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12340 if (opc
== OPC_BOVC
) {
12342 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12345 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12347 tcg_temp_free(input_overflow
);
12351 } else if (rs
< rt
&& rs
== 0) {
12352 /* OPC_BEQZALC, OPC_BNEZALC */
12353 if (opc
== OPC_BEQZALC
) {
12355 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12358 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12361 /* OPC_BEQC, OPC_BNEC */
12362 if (opc
== OPC_BEQC
) {
12364 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12367 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12372 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12375 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12378 MIPS_INVAL("Compact conditional branch/jump");
12379 gen_reserved_instruction(ctx
);
12383 /* Generating branch here as compact branches don't have delay slot */
12384 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12387 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12395 /* ISA extensions (ASEs) */
12396 /* MIPS16 extension to MIPS32 */
12398 /* MIPS16 major opcodes */
12400 M16_OPC_ADDIUSP
= 0x00,
12401 M16_OPC_ADDIUPC
= 0x01,
12403 M16_OPC_JAL
= 0x03,
12404 M16_OPC_BEQZ
= 0x04,
12405 M16_OPC_BNEQZ
= 0x05,
12406 M16_OPC_SHIFT
= 0x06,
12408 M16_OPC_RRIA
= 0x08,
12409 M16_OPC_ADDIU8
= 0x09,
12410 M16_OPC_SLTI
= 0x0a,
12411 M16_OPC_SLTIU
= 0x0b,
12414 M16_OPC_CMPI
= 0x0e,
12418 M16_OPC_LWSP
= 0x12,
12420 M16_OPC_LBU
= 0x14,
12421 M16_OPC_LHU
= 0x15,
12422 M16_OPC_LWPC
= 0x16,
12423 M16_OPC_LWU
= 0x17,
12426 M16_OPC_SWSP
= 0x1a,
12428 M16_OPC_RRR
= 0x1c,
12430 M16_OPC_EXTEND
= 0x1e,
12434 /* I8 funct field */
12453 /* RR funct field */
12487 /* I64 funct field */
12495 I64_DADDIUPC
= 0x6,
12499 /* RR ry field for CNVT */
12501 RR_RY_CNVT_ZEB
= 0x0,
12502 RR_RY_CNVT_ZEH
= 0x1,
12503 RR_RY_CNVT_ZEW
= 0x2,
12504 RR_RY_CNVT_SEB
= 0x4,
12505 RR_RY_CNVT_SEH
= 0x5,
12506 RR_RY_CNVT_SEW
= 0x6,
12509 static int xlat(int r
)
12511 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12516 static void gen_mips16_save(DisasContext
*ctx
,
12517 int xsregs
, int aregs
,
12518 int do_ra
, int do_s0
, int do_s1
,
12521 TCGv t0
= tcg_temp_new();
12522 TCGv t1
= tcg_temp_new();
12523 TCGv t2
= tcg_temp_new();
12553 gen_reserved_instruction(ctx
);
12559 gen_base_offset_addr(ctx
, t0
, 29, 12);
12560 gen_load_gpr(t1
, 7);
12561 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12564 gen_base_offset_addr(ctx
, t0
, 29, 8);
12565 gen_load_gpr(t1
, 6);
12566 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12569 gen_base_offset_addr(ctx
, t0
, 29, 4);
12570 gen_load_gpr(t1
, 5);
12571 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12574 gen_base_offset_addr(ctx
, t0
, 29, 0);
12575 gen_load_gpr(t1
, 4);
12576 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12579 gen_load_gpr(t0
, 29);
12581 #define DECR_AND_STORE(reg) do { \
12582 tcg_gen_movi_tl(t2, -4); \
12583 gen_op_addr_add(ctx, t0, t0, t2); \
12584 gen_load_gpr(t1, reg); \
12585 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12589 DECR_AND_STORE(31);
12594 DECR_AND_STORE(30);
12597 DECR_AND_STORE(23);
12600 DECR_AND_STORE(22);
12603 DECR_AND_STORE(21);
12606 DECR_AND_STORE(20);
12609 DECR_AND_STORE(19);
12612 DECR_AND_STORE(18);
12616 DECR_AND_STORE(17);
12619 DECR_AND_STORE(16);
12649 gen_reserved_instruction(ctx
);
12665 #undef DECR_AND_STORE
12667 tcg_gen_movi_tl(t2
, -framesize
);
12668 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12674 static void gen_mips16_restore(DisasContext
*ctx
,
12675 int xsregs
, int aregs
,
12676 int do_ra
, int do_s0
, int do_s1
,
12680 TCGv t0
= tcg_temp_new();
12681 TCGv t1
= tcg_temp_new();
12682 TCGv t2
= tcg_temp_new();
12684 tcg_gen_movi_tl(t2
, framesize
);
12685 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
12687 #define DECR_AND_LOAD(reg) do { \
12688 tcg_gen_movi_tl(t2, -4); \
12689 gen_op_addr_add(ctx, t0, t0, t2); \
12690 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12691 gen_store_gpr(t1, reg); \
12755 gen_reserved_instruction(ctx
);
12771 #undef DECR_AND_LOAD
12773 tcg_gen_movi_tl(t2
, framesize
);
12774 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12780 void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
12781 int is_64_bit
, int extended
)
12785 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12786 gen_reserved_instruction(ctx
);
12790 t0
= tcg_temp_new();
12792 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
12793 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
12795 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12801 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
12804 TCGv_i32 t0
= tcg_const_i32(op
);
12805 TCGv t1
= tcg_temp_new();
12806 gen_base_offset_addr(ctx
, t1
, base
, offset
);
12807 gen_helper_cache(cpu_env
, t1
, t0
);
12809 tcg_temp_free_i32(t0
);
12812 #if defined(TARGET_MIPS64)
12813 static void decode_i64_mips16(DisasContext
*ctx
,
12814 int ry
, int funct
, int16_t offset
,
12819 check_insn(ctx
, ISA_MIPS3
);
12820 check_mips_64(ctx
);
12821 offset
= extended
? offset
: offset
<< 3;
12822 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
12825 check_insn(ctx
, ISA_MIPS3
);
12826 check_mips_64(ctx
);
12827 offset
= extended
? offset
: offset
<< 3;
12828 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
12831 check_insn(ctx
, ISA_MIPS3
);
12832 check_mips_64(ctx
);
12833 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
12834 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
12837 check_insn(ctx
, ISA_MIPS3
);
12838 check_mips_64(ctx
);
12839 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
12840 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
12843 check_insn(ctx
, ISA_MIPS3
);
12844 check_mips_64(ctx
);
12845 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12846 gen_reserved_instruction(ctx
);
12848 offset
= extended
? offset
: offset
<< 3;
12849 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
12853 check_insn(ctx
, ISA_MIPS3
);
12854 check_mips_64(ctx
);
12855 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
12856 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
12859 check_insn(ctx
, ISA_MIPS3
);
12860 check_mips_64(ctx
);
12861 offset
= extended
? offset
: offset
<< 2;
12862 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
12865 check_insn(ctx
, ISA_MIPS3
);
12866 check_mips_64(ctx
);
12867 offset
= extended
? offset
: offset
<< 2;
12868 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
12874 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
12876 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
12877 int op
, rx
, ry
, funct
, sa
;
12878 int16_t imm
, offset
;
12880 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
12881 op
= (ctx
->opcode
>> 11) & 0x1f;
12882 sa
= (ctx
->opcode
>> 22) & 0x1f;
12883 funct
= (ctx
->opcode
>> 8) & 0x7;
12884 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
12885 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
12886 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
12887 | ((ctx
->opcode
>> 21) & 0x3f) << 5
12888 | (ctx
->opcode
& 0x1f));
12891 * The extended opcodes cleverly reuse the opcodes from their 16-bit
12895 case M16_OPC_ADDIUSP
:
12896 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
12898 case M16_OPC_ADDIUPC
:
12899 gen_addiupc(ctx
, rx
, imm
, 0, 1);
12902 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
12903 /* No delay slot, so just process as a normal instruction */
12906 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
12907 /* No delay slot, so just process as a normal instruction */
12909 case M16_OPC_BNEQZ
:
12910 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
12911 /* No delay slot, so just process as a normal instruction */
12913 case M16_OPC_SHIFT
:
12914 switch (ctx
->opcode
& 0x3) {
12916 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
12919 #if defined(TARGET_MIPS64)
12920 check_mips_64(ctx
);
12921 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
12923 gen_reserved_instruction(ctx
);
12927 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
12930 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
12934 #if defined(TARGET_MIPS64)
12936 check_insn(ctx
, ISA_MIPS3
);
12937 check_mips_64(ctx
);
12938 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
12942 imm
= ctx
->opcode
& 0xf;
12943 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
12944 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
12945 imm
= (int16_t) (imm
<< 1) >> 1;
12946 if ((ctx
->opcode
>> 4) & 0x1) {
12947 #if defined(TARGET_MIPS64)
12948 check_mips_64(ctx
);
12949 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12951 gen_reserved_instruction(ctx
);
12954 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12957 case M16_OPC_ADDIU8
:
12958 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12961 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12963 case M16_OPC_SLTIU
:
12964 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12969 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
12972 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
12975 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
12978 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
12981 check_insn(ctx
, ISA_MIPS_R1
);
12983 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
12984 int aregs
= (ctx
->opcode
>> 16) & 0xf;
12985 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
12986 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
12987 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
12988 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
12989 | (ctx
->opcode
& 0xf)) << 3;
12991 if (ctx
->opcode
& (1 << 7)) {
12992 gen_mips16_save(ctx
, xsregs
, aregs
,
12993 do_ra
, do_s0
, do_s1
,
12996 gen_mips16_restore(ctx
, xsregs
, aregs
,
12997 do_ra
, do_s0
, do_s1
,
13003 gen_reserved_instruction(ctx
);
13008 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13011 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13013 #if defined(TARGET_MIPS64)
13015 check_insn(ctx
, ISA_MIPS3
);
13016 check_mips_64(ctx
);
13017 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13021 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13024 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13027 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13030 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13033 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13036 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13039 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13041 #if defined(TARGET_MIPS64)
13043 check_insn(ctx
, ISA_MIPS3
);
13044 check_mips_64(ctx
);
13045 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13049 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13052 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13055 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13058 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13060 #if defined(TARGET_MIPS64)
13062 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13066 gen_reserved_instruction(ctx
);
13073 static inline bool is_uhi(int sdbbp_code
)
13075 #ifdef CONFIG_USER_ONLY
13078 return semihosting_enabled() && sdbbp_code
== 1;
13082 #ifdef CONFIG_USER_ONLY
13083 /* The above should dead-code away any calls to this..*/
13084 static inline void gen_helper_do_semihosting(void *env
)
13086 g_assert_not_reached();
13090 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13094 int op
, cnvt_op
, op1
, offset
;
13098 op
= (ctx
->opcode
>> 11) & 0x1f;
13099 sa
= (ctx
->opcode
>> 2) & 0x7;
13100 sa
= sa
== 0 ? 8 : sa
;
13101 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13102 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13103 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13104 op1
= offset
= ctx
->opcode
& 0x1f;
13109 case M16_OPC_ADDIUSP
:
13111 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13113 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13116 case M16_OPC_ADDIUPC
:
13117 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13120 offset
= (ctx
->opcode
& 0x7ff) << 1;
13121 offset
= (int16_t)(offset
<< 4) >> 4;
13122 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13123 /* No delay slot, so just process as a normal instruction */
13126 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13127 offset
= (((ctx
->opcode
& 0x1f) << 21)
13128 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13130 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13131 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13135 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13136 ((int8_t)ctx
->opcode
) << 1, 0);
13137 /* No delay slot, so just process as a normal instruction */
13139 case M16_OPC_BNEQZ
:
13140 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13141 ((int8_t)ctx
->opcode
) << 1, 0);
13142 /* No delay slot, so just process as a normal instruction */
13144 case M16_OPC_SHIFT
:
13145 switch (ctx
->opcode
& 0x3) {
13147 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13150 #if defined(TARGET_MIPS64)
13151 check_insn(ctx
, ISA_MIPS3
);
13152 check_mips_64(ctx
);
13153 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13155 gen_reserved_instruction(ctx
);
13159 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13162 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13166 #if defined(TARGET_MIPS64)
13168 check_insn(ctx
, ISA_MIPS3
);
13169 check_mips_64(ctx
);
13170 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13175 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13177 if ((ctx
->opcode
>> 4) & 1) {
13178 #if defined(TARGET_MIPS64)
13179 check_insn(ctx
, ISA_MIPS3
);
13180 check_mips_64(ctx
);
13181 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13183 gen_reserved_instruction(ctx
);
13186 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13190 case M16_OPC_ADDIU8
:
13192 int16_t imm
= (int8_t) ctx
->opcode
;
13194 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13199 int16_t imm
= (uint8_t) ctx
->opcode
;
13200 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13203 case M16_OPC_SLTIU
:
13205 int16_t imm
= (uint8_t) ctx
->opcode
;
13206 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13213 funct
= (ctx
->opcode
>> 8) & 0x7;
13216 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13217 ((int8_t)ctx
->opcode
) << 1, 0);
13220 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13221 ((int8_t)ctx
->opcode
) << 1, 0);
13224 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13227 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13228 ((int8_t)ctx
->opcode
) << 3);
13231 check_insn(ctx
, ISA_MIPS_R1
);
13233 int do_ra
= ctx
->opcode
& (1 << 6);
13234 int do_s0
= ctx
->opcode
& (1 << 5);
13235 int do_s1
= ctx
->opcode
& (1 << 4);
13236 int framesize
= ctx
->opcode
& 0xf;
13238 if (framesize
== 0) {
13241 framesize
= framesize
<< 3;
13244 if (ctx
->opcode
& (1 << 7)) {
13245 gen_mips16_save(ctx
, 0, 0,
13246 do_ra
, do_s0
, do_s1
, framesize
);
13248 gen_mips16_restore(ctx
, 0, 0,
13249 do_ra
, do_s0
, do_s1
, framesize
);
13255 int rz
= xlat(ctx
->opcode
& 0x7);
13257 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13258 ((ctx
->opcode
>> 5) & 0x7);
13259 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13263 reg32
= ctx
->opcode
& 0x1f;
13264 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13267 gen_reserved_instruction(ctx
);
13274 int16_t imm
= (uint8_t) ctx
->opcode
;
13276 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13281 int16_t imm
= (uint8_t) ctx
->opcode
;
13282 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13285 #if defined(TARGET_MIPS64)
13287 check_insn(ctx
, ISA_MIPS3
);
13288 check_mips_64(ctx
);
13289 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13293 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13296 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13299 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13302 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13305 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13308 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13311 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13313 #if defined(TARGET_MIPS64)
13315 check_insn(ctx
, ISA_MIPS3
);
13316 check_mips_64(ctx
);
13317 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13321 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13324 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13327 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13330 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13334 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13337 switch (ctx
->opcode
& 0x3) {
13339 mips32_op
= OPC_ADDU
;
13342 mips32_op
= OPC_SUBU
;
13344 #if defined(TARGET_MIPS64)
13346 mips32_op
= OPC_DADDU
;
13347 check_insn(ctx
, ISA_MIPS3
);
13348 check_mips_64(ctx
);
13351 mips32_op
= OPC_DSUBU
;
13352 check_insn(ctx
, ISA_MIPS3
);
13353 check_mips_64(ctx
);
13357 gen_reserved_instruction(ctx
);
13361 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13370 int nd
= (ctx
->opcode
>> 7) & 0x1;
13371 int link
= (ctx
->opcode
>> 6) & 0x1;
13372 int ra
= (ctx
->opcode
>> 5) & 0x1;
13375 check_insn(ctx
, ISA_MIPS_R1
);
13384 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13389 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13390 gen_helper_do_semihosting(cpu_env
);
13393 * XXX: not clear which exception should be raised
13394 * when in debug mode...
13396 check_insn(ctx
, ISA_MIPS_R1
);
13397 generate_exception_end(ctx
, EXCP_DBp
);
13401 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13404 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13407 generate_exception_end(ctx
, EXCP_BREAK
);
13410 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13413 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13416 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13418 #if defined(TARGET_MIPS64)
13420 check_insn(ctx
, ISA_MIPS3
);
13421 check_mips_64(ctx
);
13422 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13426 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13429 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13432 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13435 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13438 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13441 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13444 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13447 check_insn(ctx
, ISA_MIPS_R1
);
13449 case RR_RY_CNVT_ZEB
:
13450 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13452 case RR_RY_CNVT_ZEH
:
13453 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13455 case RR_RY_CNVT_SEB
:
13456 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13458 case RR_RY_CNVT_SEH
:
13459 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13461 #if defined(TARGET_MIPS64)
13462 case RR_RY_CNVT_ZEW
:
13463 check_insn(ctx
, ISA_MIPS_R1
);
13464 check_mips_64(ctx
);
13465 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13467 case RR_RY_CNVT_SEW
:
13468 check_insn(ctx
, ISA_MIPS_R1
);
13469 check_mips_64(ctx
);
13470 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13474 gen_reserved_instruction(ctx
);
13479 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13481 #if defined(TARGET_MIPS64)
13483 check_insn(ctx
, ISA_MIPS3
);
13484 check_mips_64(ctx
);
13485 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13488 check_insn(ctx
, ISA_MIPS3
);
13489 check_mips_64(ctx
);
13490 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13493 check_insn(ctx
, ISA_MIPS3
);
13494 check_mips_64(ctx
);
13495 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13498 check_insn(ctx
, ISA_MIPS3
);
13499 check_mips_64(ctx
);
13500 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13504 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13507 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13510 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13513 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13515 #if defined(TARGET_MIPS64)
13517 check_insn(ctx
, ISA_MIPS3
);
13518 check_mips_64(ctx
);
13519 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13522 check_insn(ctx
, ISA_MIPS3
);
13523 check_mips_64(ctx
);
13524 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13527 check_insn(ctx
, ISA_MIPS3
);
13528 check_mips_64(ctx
);
13529 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13532 check_insn(ctx
, ISA_MIPS3
);
13533 check_mips_64(ctx
);
13534 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13538 gen_reserved_instruction(ctx
);
13542 case M16_OPC_EXTEND
:
13543 decode_extended_mips16_opc(env
, ctx
);
13546 #if defined(TARGET_MIPS64)
13548 funct
= (ctx
->opcode
>> 8) & 0x7;
13549 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13553 gen_reserved_instruction(ctx
);
13560 /* microMIPS extension to MIPS32/MIPS64 */
13563 * microMIPS32/microMIPS64 major opcodes
13565 * 1. MIPS Architecture for Programmers Volume II-B:
13566 * The microMIPS32 Instruction Set (Revision 3.05)
13568 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13570 * 2. MIPS Architecture For Programmers Volume II-A:
13571 * The MIPS64 Instruction Set (Revision 3.51)
13601 POOL32S
= 0x16, /* MIPS64 */
13602 DADDIU32
= 0x17, /* MIPS64 */
13631 /* 0x29 is reserved */
13644 /* 0x31 is reserved */
13657 SD32
= 0x36, /* MIPS64 */
13658 LD32
= 0x37, /* MIPS64 */
13660 /* 0x39 is reserved */
13676 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13698 /* POOL32A encoding of minor opcode field */
13702 * These opcodes are distinguished only by bits 9..6; those bits are
13703 * what are recorded below.
13741 /* The following can be distinguished by their lower 6 bits. */
13751 /* POOL32AXF encoding of minor opcode field extension */
13754 * 1. MIPS Architecture for Programmers Volume II-B:
13755 * The microMIPS32 Instruction Set (Revision 3.05)
13757 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13759 * 2. MIPS Architecture for Programmers VolumeIV-e:
13760 * The MIPS DSP Application-Specific Extension
13761 * to the microMIPS32 Architecture (Revision 2.34)
13763 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13778 /* begin of microMIPS32 DSP */
13780 /* bits 13..12 for 0x01 */
13786 /* bits 13..12 for 0x2a */
13792 /* bits 13..12 for 0x32 */
13796 /* end of microMIPS32 DSP */
13798 /* bits 15..12 for 0x2c */
13815 /* bits 15..12 for 0x34 */
13823 /* bits 15..12 for 0x3c */
13825 JR
= 0x0, /* alias */
13833 /* bits 15..12 for 0x05 */
13837 /* bits 15..12 for 0x0d */
13849 /* bits 15..12 for 0x15 */
13855 /* bits 15..12 for 0x1d */
13859 /* bits 15..12 for 0x2d */
13864 /* bits 15..12 for 0x35 */
13871 /* POOL32B encoding of minor opcode field (bits 15..12) */
13887 /* POOL32C encoding of minor opcode field (bits 15..12) */
13908 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13921 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13934 /* POOL32F encoding of minor opcode field (bits 5..0) */
13937 /* These are the bit 7..6 values */
13946 /* These are the bit 8..6 values */
13971 MOVZ_FMT_05
= 0x05,
14005 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14012 /* POOL32Fxf encoding of minor opcode extension field */
14050 /* POOL32I encoding of minor opcode field (bits 25..21) */
14078 /* These overlap and are distinguished by bit16 of the instruction */
14087 /* POOL16A encoding of minor opcode field */
14094 /* POOL16B encoding of minor opcode field */
14101 /* POOL16C encoding of minor opcode field */
14121 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14145 /* POOL16D encoding of minor opcode field */
14152 /* POOL16E encoding of minor opcode field */
14159 static int mmreg(int r
)
14161 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14166 /* Used for 16-bit store instructions. */
14167 static int mmreg2(int r
)
14169 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14174 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14175 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14176 #define uMIPS_RS2(op) uMIPS_RS(op)
14177 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14178 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14179 #define uMIPS_RS5(op) (op & 0x1f)
14181 /* Signed immediate */
14182 #define SIMM(op, start, width) \
14183 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14186 /* Zero-extended immediate */
14187 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14189 static void gen_addiur1sp(DisasContext
*ctx
)
14191 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14193 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14196 static void gen_addiur2(DisasContext
*ctx
)
14198 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14199 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14200 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14202 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14205 static void gen_addiusp(DisasContext
*ctx
)
14207 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14210 if (encoded
<= 1) {
14211 decoded
= 256 + encoded
;
14212 } else if (encoded
<= 255) {
14214 } else if (encoded
<= 509) {
14215 decoded
= encoded
- 512;
14217 decoded
= encoded
- 768;
14220 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14223 static void gen_addius5(DisasContext
*ctx
)
14225 int imm
= SIMM(ctx
->opcode
, 1, 4);
14226 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14228 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14231 static void gen_andi16(DisasContext
*ctx
)
14233 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14234 31, 32, 63, 64, 255, 32768, 65535 };
14235 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14236 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14237 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14239 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14242 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14243 int base
, int16_t offset
)
14248 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14249 gen_reserved_instruction(ctx
);
14253 t0
= tcg_temp_new();
14255 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14257 t1
= tcg_const_tl(reglist
);
14258 t2
= tcg_const_i32(ctx
->mem_idx
);
14260 save_cpu_state(ctx
, 1);
14263 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14266 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14268 #ifdef TARGET_MIPS64
14270 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14273 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14279 tcg_temp_free_i32(t2
);
14283 static void gen_pool16c_insn(DisasContext
*ctx
)
14285 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14286 int rs
= mmreg(ctx
->opcode
& 0x7);
14288 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14293 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14299 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14305 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14311 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14318 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14319 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14321 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14330 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14331 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14333 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14340 int reg
= ctx
->opcode
& 0x1f;
14342 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14348 int reg
= ctx
->opcode
& 0x1f;
14349 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14351 * Let normal delay slot handling in our caller take us
14352 * to the branch target.
14358 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14359 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14363 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14364 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14368 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14372 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14375 generate_exception_end(ctx
, EXCP_BREAK
);
14378 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14379 gen_helper_do_semihosting(cpu_env
);
14382 * XXX: not clear which exception should be raised
14383 * when in debug mode...
14385 check_insn(ctx
, ISA_MIPS_R1
);
14386 generate_exception_end(ctx
, EXCP_DBp
);
14389 case JRADDIUSP
+ 0:
14390 case JRADDIUSP
+ 1:
14392 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14393 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14394 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14396 * Let normal delay slot handling in our caller take us
14397 * to the branch target.
14402 gen_reserved_instruction(ctx
);
14407 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14411 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14412 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14413 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14415 rd
= rd_enc
[enc_dest
];
14416 re
= re_enc
[enc_dest
];
14417 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14418 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14421 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14423 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14424 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14426 switch (ctx
->opcode
& 0xf) {
14428 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14431 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14435 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14436 int offset
= extract32(ctx
->opcode
, 4, 4);
14437 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14440 case R6_JRC16
: /* JRCADDIUSP */
14441 if ((ctx
->opcode
>> 4) & 1) {
14443 int imm
= extract32(ctx
->opcode
, 5, 5);
14444 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14445 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14448 rs
= extract32(ctx
->opcode
, 5, 5);
14449 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14461 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14462 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14463 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14464 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14468 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14471 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14475 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14476 int offset
= extract32(ctx
->opcode
, 4, 4);
14477 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14480 case JALRC16
: /* BREAK16, SDBBP16 */
14481 switch (ctx
->opcode
& 0x3f) {
14483 case JALRC16
+ 0x20:
14485 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14490 generate_exception(ctx
, EXCP_BREAK
);
14494 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14495 gen_helper_do_semihosting(cpu_env
);
14497 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14498 generate_exception(ctx
, EXCP_RI
);
14500 generate_exception(ctx
, EXCP_DBp
);
14507 generate_exception(ctx
, EXCP_RI
);
14512 void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14514 TCGv t0
= tcg_temp_new();
14515 TCGv t1
= tcg_temp_new();
14517 gen_load_gpr(t0
, base
);
14520 gen_load_gpr(t1
, index
);
14521 tcg_gen_shli_tl(t1
, t1
, 2);
14522 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14525 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14526 gen_store_gpr(t1
, rd
);
14532 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14533 int base
, int16_t offset
)
14537 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14538 gen_reserved_instruction(ctx
);
14542 t0
= tcg_temp_new();
14543 t1
= tcg_temp_new();
14545 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14550 gen_reserved_instruction(ctx
);
14553 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14554 gen_store_gpr(t1
, rd
);
14555 tcg_gen_movi_tl(t1
, 4);
14556 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14557 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14558 gen_store_gpr(t1
, rd
+ 1);
14561 gen_load_gpr(t1
, rd
);
14562 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14563 tcg_gen_movi_tl(t1
, 4);
14564 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14565 gen_load_gpr(t1
, rd
+ 1);
14566 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14568 #ifdef TARGET_MIPS64
14571 gen_reserved_instruction(ctx
);
14574 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14575 gen_store_gpr(t1
, rd
);
14576 tcg_gen_movi_tl(t1
, 8);
14577 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14578 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14579 gen_store_gpr(t1
, rd
+ 1);
14582 gen_load_gpr(t1
, rd
);
14583 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14584 tcg_gen_movi_tl(t1
, 8);
14585 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14586 gen_load_gpr(t1
, rd
+ 1);
14587 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14595 static void gen_sync(int stype
)
14597 TCGBar tcg_mo
= TCG_BAR_SC
;
14600 case 0x4: /* SYNC_WMB */
14601 tcg_mo
|= TCG_MO_ST_ST
;
14603 case 0x10: /* SYNC_MB */
14604 tcg_mo
|= TCG_MO_ALL
;
14606 case 0x11: /* SYNC_ACQUIRE */
14607 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14609 case 0x12: /* SYNC_RELEASE */
14610 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14612 case 0x13: /* SYNC_RMB */
14613 tcg_mo
|= TCG_MO_LD_LD
;
14616 tcg_mo
|= TCG_MO_ALL
;
14620 tcg_gen_mb(tcg_mo
);
14623 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14625 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14626 int minor
= (ctx
->opcode
>> 12) & 0xf;
14627 uint32_t mips32_op
;
14629 switch (extension
) {
14631 mips32_op
= OPC_TEQ
;
14634 mips32_op
= OPC_TGE
;
14637 mips32_op
= OPC_TGEU
;
14640 mips32_op
= OPC_TLT
;
14643 mips32_op
= OPC_TLTU
;
14646 mips32_op
= OPC_TNE
;
14648 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
14650 #ifndef CONFIG_USER_ONLY
14653 check_cp0_enabled(ctx
);
14655 /* Treat as NOP. */
14658 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
14662 check_cp0_enabled(ctx
);
14664 TCGv t0
= tcg_temp_new();
14666 gen_load_gpr(t0
, rt
);
14667 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
14673 switch (minor
& 3) {
14675 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14678 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14681 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14684 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14687 goto pool32axf_invalid
;
14691 switch (minor
& 3) {
14693 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14696 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14699 goto pool32axf_invalid
;
14705 check_insn(ctx
, ISA_MIPS_R6
);
14706 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
14709 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
14712 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
14715 mips32_op
= OPC_CLO
;
14718 mips32_op
= OPC_CLZ
;
14720 check_insn(ctx
, ISA_MIPS_R1
);
14721 gen_cl(ctx
, mips32_op
, rt
, rs
);
14724 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14725 gen_rdhwr(ctx
, rt
, rs
, 0);
14728 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
14731 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14732 mips32_op
= OPC_MULT
;
14735 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14736 mips32_op
= OPC_MULTU
;
14739 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14740 mips32_op
= OPC_DIV
;
14743 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14744 mips32_op
= OPC_DIVU
;
14747 check_insn(ctx
, ISA_MIPS_R1
);
14748 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14751 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14752 mips32_op
= OPC_MADD
;
14755 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14756 mips32_op
= OPC_MADDU
;
14759 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14760 mips32_op
= OPC_MSUB
;
14763 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14764 mips32_op
= OPC_MSUBU
;
14766 check_insn(ctx
, ISA_MIPS_R1
);
14767 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14770 goto pool32axf_invalid
;
14781 generate_exception_err(ctx
, EXCP_CpU
, 2);
14784 goto pool32axf_invalid
;
14789 case JALR
: /* JALRC */
14790 case JALR_HB
: /* JALRC_HB */
14791 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
14792 /* JALRC, JALRC_HB */
14793 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
14795 /* JALR, JALR_HB */
14796 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
14797 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14802 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14803 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
14804 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14807 goto pool32axf_invalid
;
14813 check_cp0_enabled(ctx
);
14814 check_insn(ctx
, ISA_MIPS_R2
);
14815 gen_load_srsgpr(rs
, rt
);
14818 check_cp0_enabled(ctx
);
14819 check_insn(ctx
, ISA_MIPS_R2
);
14820 gen_store_srsgpr(rs
, rt
);
14823 goto pool32axf_invalid
;
14826 #ifndef CONFIG_USER_ONLY
14830 mips32_op
= OPC_TLBP
;
14833 mips32_op
= OPC_TLBR
;
14836 mips32_op
= OPC_TLBWI
;
14839 mips32_op
= OPC_TLBWR
;
14842 mips32_op
= OPC_TLBINV
;
14845 mips32_op
= OPC_TLBINVF
;
14848 mips32_op
= OPC_WAIT
;
14851 mips32_op
= OPC_DERET
;
14854 mips32_op
= OPC_ERET
;
14856 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
14859 goto pool32axf_invalid
;
14865 check_cp0_enabled(ctx
);
14867 TCGv t0
= tcg_temp_new();
14869 save_cpu_state(ctx
, 1);
14870 gen_helper_di(t0
, cpu_env
);
14871 gen_store_gpr(t0
, rs
);
14873 * Stop translation as we may have switched the execution
14876 ctx
->base
.is_jmp
= DISAS_STOP
;
14881 check_cp0_enabled(ctx
);
14883 TCGv t0
= tcg_temp_new();
14885 save_cpu_state(ctx
, 1);
14886 gen_helper_ei(t0
, cpu_env
);
14887 gen_store_gpr(t0
, rs
);
14889 * DISAS_STOP isn't sufficient, we need to ensure we break out
14890 * of translated code to check for pending interrupts.
14892 gen_save_pc(ctx
->base
.pc_next
+ 4);
14893 ctx
->base
.is_jmp
= DISAS_EXIT
;
14898 goto pool32axf_invalid
;
14905 gen_sync(extract32(ctx
->opcode
, 16, 5));
14908 generate_exception_end(ctx
, EXCP_SYSCALL
);
14911 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
14912 gen_helper_do_semihosting(cpu_env
);
14914 check_insn(ctx
, ISA_MIPS_R1
);
14915 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14916 gen_reserved_instruction(ctx
);
14918 generate_exception_end(ctx
, EXCP_DBp
);
14923 goto pool32axf_invalid
;
14927 switch (minor
& 3) {
14929 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
14932 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
14935 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
14938 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
14941 goto pool32axf_invalid
;
14945 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14948 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
14951 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
14954 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
14957 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
14960 goto pool32axf_invalid
;
14965 MIPS_INVAL("pool32axf");
14966 gen_reserved_instruction(ctx
);
14972 * Values for microMIPS fmt field. Variable-width, depending on which
14973 * formats the instruction supports.
14992 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
14994 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
14995 uint32_t mips32_op
;
14997 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
14998 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
14999 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15001 switch (extension
) {
15002 case FLOAT_1BIT_FMT(CFC1
, 0):
15003 mips32_op
= OPC_CFC1
;
15005 case FLOAT_1BIT_FMT(CTC1
, 0):
15006 mips32_op
= OPC_CTC1
;
15008 case FLOAT_1BIT_FMT(MFC1
, 0):
15009 mips32_op
= OPC_MFC1
;
15011 case FLOAT_1BIT_FMT(MTC1
, 0):
15012 mips32_op
= OPC_MTC1
;
15014 case FLOAT_1BIT_FMT(MFHC1
, 0):
15015 mips32_op
= OPC_MFHC1
;
15017 case FLOAT_1BIT_FMT(MTHC1
, 0):
15018 mips32_op
= OPC_MTHC1
;
15020 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15023 /* Reciprocal square root */
15024 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15025 mips32_op
= OPC_RSQRT_S
;
15027 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15028 mips32_op
= OPC_RSQRT_D
;
15032 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15033 mips32_op
= OPC_SQRT_S
;
15035 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15036 mips32_op
= OPC_SQRT_D
;
15040 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15041 mips32_op
= OPC_RECIP_S
;
15043 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15044 mips32_op
= OPC_RECIP_D
;
15048 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15049 mips32_op
= OPC_FLOOR_L_S
;
15051 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15052 mips32_op
= OPC_FLOOR_L_D
;
15054 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15055 mips32_op
= OPC_FLOOR_W_S
;
15057 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15058 mips32_op
= OPC_FLOOR_W_D
;
15062 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15063 mips32_op
= OPC_CEIL_L_S
;
15065 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15066 mips32_op
= OPC_CEIL_L_D
;
15068 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15069 mips32_op
= OPC_CEIL_W_S
;
15071 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15072 mips32_op
= OPC_CEIL_W_D
;
15076 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15077 mips32_op
= OPC_TRUNC_L_S
;
15079 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15080 mips32_op
= OPC_TRUNC_L_D
;
15082 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15083 mips32_op
= OPC_TRUNC_W_S
;
15085 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15086 mips32_op
= OPC_TRUNC_W_D
;
15090 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15091 mips32_op
= OPC_ROUND_L_S
;
15093 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15094 mips32_op
= OPC_ROUND_L_D
;
15096 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15097 mips32_op
= OPC_ROUND_W_S
;
15099 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15100 mips32_op
= OPC_ROUND_W_D
;
15103 /* Integer to floating-point conversion */
15104 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15105 mips32_op
= OPC_CVT_L_S
;
15107 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15108 mips32_op
= OPC_CVT_L_D
;
15110 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15111 mips32_op
= OPC_CVT_W_S
;
15113 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15114 mips32_op
= OPC_CVT_W_D
;
15117 /* Paired-foo conversions */
15118 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15119 mips32_op
= OPC_CVT_S_PL
;
15121 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15122 mips32_op
= OPC_CVT_S_PU
;
15124 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15125 mips32_op
= OPC_CVT_PW_PS
;
15127 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15128 mips32_op
= OPC_CVT_PS_PW
;
15131 /* Floating-point moves */
15132 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15133 mips32_op
= OPC_MOV_S
;
15135 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15136 mips32_op
= OPC_MOV_D
;
15138 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15139 mips32_op
= OPC_MOV_PS
;
15142 /* Absolute value */
15143 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15144 mips32_op
= OPC_ABS_S
;
15146 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15147 mips32_op
= OPC_ABS_D
;
15149 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15150 mips32_op
= OPC_ABS_PS
;
15154 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15155 mips32_op
= OPC_NEG_S
;
15157 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15158 mips32_op
= OPC_NEG_D
;
15160 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15161 mips32_op
= OPC_NEG_PS
;
15164 /* Reciprocal square root step */
15165 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15166 mips32_op
= OPC_RSQRT1_S
;
15168 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15169 mips32_op
= OPC_RSQRT1_D
;
15171 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15172 mips32_op
= OPC_RSQRT1_PS
;
15175 /* Reciprocal step */
15176 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15177 mips32_op
= OPC_RECIP1_S
;
15179 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15180 mips32_op
= OPC_RECIP1_S
;
15182 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15183 mips32_op
= OPC_RECIP1_PS
;
15186 /* Conversions from double */
15187 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15188 mips32_op
= OPC_CVT_D_S
;
15190 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15191 mips32_op
= OPC_CVT_D_W
;
15193 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15194 mips32_op
= OPC_CVT_D_L
;
15197 /* Conversions from single */
15198 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15199 mips32_op
= OPC_CVT_S_D
;
15201 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15202 mips32_op
= OPC_CVT_S_W
;
15204 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15205 mips32_op
= OPC_CVT_S_L
;
15207 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15210 /* Conditional moves on floating-point codes */
15211 case COND_FLOAT_MOV(MOVT
, 0):
15212 case COND_FLOAT_MOV(MOVT
, 1):
15213 case COND_FLOAT_MOV(MOVT
, 2):
15214 case COND_FLOAT_MOV(MOVT
, 3):
15215 case COND_FLOAT_MOV(MOVT
, 4):
15216 case COND_FLOAT_MOV(MOVT
, 5):
15217 case COND_FLOAT_MOV(MOVT
, 6):
15218 case COND_FLOAT_MOV(MOVT
, 7):
15219 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15220 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15222 case COND_FLOAT_MOV(MOVF
, 0):
15223 case COND_FLOAT_MOV(MOVF
, 1):
15224 case COND_FLOAT_MOV(MOVF
, 2):
15225 case COND_FLOAT_MOV(MOVF
, 3):
15226 case COND_FLOAT_MOV(MOVF
, 4):
15227 case COND_FLOAT_MOV(MOVF
, 5):
15228 case COND_FLOAT_MOV(MOVF
, 6):
15229 case COND_FLOAT_MOV(MOVF
, 7):
15230 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15231 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15234 MIPS_INVAL("pool32fxf");
15235 gen_reserved_instruction(ctx
);
15240 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15244 int rt
, rs
, rd
, rr
;
15246 uint32_t op
, minor
, minor2
, mips32_op
;
15247 uint32_t cond
, fmt
, cc
;
15249 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15250 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15252 rt
= (ctx
->opcode
>> 21) & 0x1f;
15253 rs
= (ctx
->opcode
>> 16) & 0x1f;
15254 rd
= (ctx
->opcode
>> 11) & 0x1f;
15255 rr
= (ctx
->opcode
>> 6) & 0x1f;
15256 imm
= (int16_t) ctx
->opcode
;
15258 op
= (ctx
->opcode
>> 26) & 0x3f;
15261 minor
= ctx
->opcode
& 0x3f;
15264 minor
= (ctx
->opcode
>> 6) & 0xf;
15267 mips32_op
= OPC_SLL
;
15270 mips32_op
= OPC_SRA
;
15273 mips32_op
= OPC_SRL
;
15276 mips32_op
= OPC_ROTR
;
15278 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15281 check_insn(ctx
, ISA_MIPS_R6
);
15282 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15285 check_insn(ctx
, ISA_MIPS_R6
);
15286 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15289 check_insn(ctx
, ISA_MIPS_R6
);
15290 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15293 goto pool32a_invalid
;
15297 minor
= (ctx
->opcode
>> 6) & 0xf;
15301 mips32_op
= OPC_ADD
;
15304 mips32_op
= OPC_ADDU
;
15307 mips32_op
= OPC_SUB
;
15310 mips32_op
= OPC_SUBU
;
15313 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15314 mips32_op
= OPC_MUL
;
15316 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15320 mips32_op
= OPC_SLLV
;
15323 mips32_op
= OPC_SRLV
;
15326 mips32_op
= OPC_SRAV
;
15329 mips32_op
= OPC_ROTRV
;
15331 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15333 /* Logical operations */
15335 mips32_op
= OPC_AND
;
15338 mips32_op
= OPC_OR
;
15341 mips32_op
= OPC_NOR
;
15344 mips32_op
= OPC_XOR
;
15346 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15348 /* Set less than */
15350 mips32_op
= OPC_SLT
;
15353 mips32_op
= OPC_SLTU
;
15355 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15358 goto pool32a_invalid
;
15362 minor
= (ctx
->opcode
>> 6) & 0xf;
15364 /* Conditional moves */
15365 case MOVN
: /* MUL */
15366 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15368 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15371 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15374 case MOVZ
: /* MUH */
15375 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15377 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15380 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15384 check_insn(ctx
, ISA_MIPS_R6
);
15385 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15388 check_insn(ctx
, ISA_MIPS_R6
);
15389 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15391 case LWXS
: /* DIV */
15392 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15394 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15397 gen_ldxs(ctx
, rs
, rt
, rd
);
15401 check_insn(ctx
, ISA_MIPS_R6
);
15402 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15405 check_insn(ctx
, ISA_MIPS_R6
);
15406 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15409 check_insn(ctx
, ISA_MIPS_R6
);
15410 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15413 goto pool32a_invalid
;
15417 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15420 check_insn(ctx
, ISA_MIPS_R6
);
15421 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15424 check_insn(ctx
, ISA_MIPS_R6
);
15425 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15428 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15431 gen_pool32axf(env
, ctx
, rt
, rs
);
15434 generate_exception_end(ctx
, EXCP_BREAK
);
15437 check_insn(ctx
, ISA_MIPS_R6
);
15438 gen_reserved_instruction(ctx
);
15442 MIPS_INVAL("pool32a");
15443 gen_reserved_instruction(ctx
);
15448 minor
= (ctx
->opcode
>> 12) & 0xf;
15451 check_cp0_enabled(ctx
);
15452 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15453 gen_cache_operation(ctx
, rt
, rs
, imm
);
15458 /* COP2: Not implemented. */
15459 generate_exception_err(ctx
, EXCP_CpU
, 2);
15461 #ifdef TARGET_MIPS64
15464 check_insn(ctx
, ISA_MIPS3
);
15465 check_mips_64(ctx
);
15470 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15472 #ifdef TARGET_MIPS64
15475 check_insn(ctx
, ISA_MIPS3
);
15476 check_mips_64(ctx
);
15481 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15484 MIPS_INVAL("pool32b");
15485 gen_reserved_instruction(ctx
);
15490 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15491 minor
= ctx
->opcode
& 0x3f;
15492 check_cp1_enabled(ctx
);
15495 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15496 mips32_op
= OPC_ALNV_PS
;
15499 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15500 mips32_op
= OPC_MADD_S
;
15503 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15504 mips32_op
= OPC_MADD_D
;
15507 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15508 mips32_op
= OPC_MADD_PS
;
15511 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15512 mips32_op
= OPC_MSUB_S
;
15515 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15516 mips32_op
= OPC_MSUB_D
;
15519 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15520 mips32_op
= OPC_MSUB_PS
;
15523 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15524 mips32_op
= OPC_NMADD_S
;
15527 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15528 mips32_op
= OPC_NMADD_D
;
15531 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15532 mips32_op
= OPC_NMADD_PS
;
15535 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15536 mips32_op
= OPC_NMSUB_S
;
15539 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15540 mips32_op
= OPC_NMSUB_D
;
15543 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15544 mips32_op
= OPC_NMSUB_PS
;
15546 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15548 case CABS_COND_FMT
:
15549 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15550 cond
= (ctx
->opcode
>> 6) & 0xf;
15551 cc
= (ctx
->opcode
>> 13) & 0x7;
15552 fmt
= (ctx
->opcode
>> 10) & 0x3;
15555 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15558 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15561 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15564 goto pool32f_invalid
;
15568 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15569 cond
= (ctx
->opcode
>> 6) & 0xf;
15570 cc
= (ctx
->opcode
>> 13) & 0x7;
15571 fmt
= (ctx
->opcode
>> 10) & 0x3;
15574 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15577 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15580 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15583 goto pool32f_invalid
;
15587 check_insn(ctx
, ISA_MIPS_R6
);
15588 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15591 check_insn(ctx
, ISA_MIPS_R6
);
15592 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15595 gen_pool32fxf(ctx
, rt
, rs
);
15599 switch ((ctx
->opcode
>> 6) & 0x7) {
15601 mips32_op
= OPC_PLL_PS
;
15604 mips32_op
= OPC_PLU_PS
;
15607 mips32_op
= OPC_PUL_PS
;
15610 mips32_op
= OPC_PUU_PS
;
15613 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15614 mips32_op
= OPC_CVT_PS_S
;
15616 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15619 goto pool32f_invalid
;
15623 check_insn(ctx
, ISA_MIPS_R6
);
15624 switch ((ctx
->opcode
>> 9) & 0x3) {
15626 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15629 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15632 goto pool32f_invalid
;
15637 switch ((ctx
->opcode
>> 6) & 0x7) {
15639 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15640 mips32_op
= OPC_LWXC1
;
15643 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15644 mips32_op
= OPC_SWXC1
;
15647 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15648 mips32_op
= OPC_LDXC1
;
15651 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15652 mips32_op
= OPC_SDXC1
;
15655 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15656 mips32_op
= OPC_LUXC1
;
15659 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15660 mips32_op
= OPC_SUXC1
;
15662 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
15665 goto pool32f_invalid
;
15669 check_insn(ctx
, ISA_MIPS_R6
);
15670 switch ((ctx
->opcode
>> 9) & 0x3) {
15672 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
15675 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
15678 goto pool32f_invalid
;
15683 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15684 fmt
= (ctx
->opcode
>> 9) & 0x3;
15685 switch ((ctx
->opcode
>> 6) & 0x7) {
15689 mips32_op
= OPC_RSQRT2_S
;
15692 mips32_op
= OPC_RSQRT2_D
;
15695 mips32_op
= OPC_RSQRT2_PS
;
15698 goto pool32f_invalid
;
15704 mips32_op
= OPC_RECIP2_S
;
15707 mips32_op
= OPC_RECIP2_D
;
15710 mips32_op
= OPC_RECIP2_PS
;
15713 goto pool32f_invalid
;
15717 mips32_op
= OPC_ADDR_PS
;
15720 mips32_op
= OPC_MULR_PS
;
15722 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15725 goto pool32f_invalid
;
15729 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15730 cc
= (ctx
->opcode
>> 13) & 0x7;
15731 fmt
= (ctx
->opcode
>> 9) & 0x3;
15732 switch ((ctx
->opcode
>> 6) & 0x7) {
15733 case MOVF_FMT
: /* RINT_FMT */
15734 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15738 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
15741 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
15744 goto pool32f_invalid
;
15750 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
15753 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
15757 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
15760 goto pool32f_invalid
;
15764 case MOVT_FMT
: /* CLASS_FMT */
15765 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15769 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
15772 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
15775 goto pool32f_invalid
;
15781 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
15784 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
15788 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
15791 goto pool32f_invalid
;
15796 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15799 goto pool32f_invalid
;
15802 #define FINSN_3ARG_SDPS(prfx) \
15803 switch ((ctx->opcode >> 8) & 0x3) { \
15805 mips32_op = OPC_##prfx##_S; \
15808 mips32_op = OPC_##prfx##_D; \
15810 case FMT_SDPS_PS: \
15812 mips32_op = OPC_##prfx##_PS; \
15815 goto pool32f_invalid; \
15818 check_insn(ctx
, ISA_MIPS_R6
);
15819 switch ((ctx
->opcode
>> 9) & 0x3) {
15821 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
15824 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
15827 goto pool32f_invalid
;
15831 check_insn(ctx
, ISA_MIPS_R6
);
15832 switch ((ctx
->opcode
>> 9) & 0x3) {
15834 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
15837 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
15840 goto pool32f_invalid
;
15844 /* regular FP ops */
15845 switch ((ctx
->opcode
>> 6) & 0x3) {
15847 FINSN_3ARG_SDPS(ADD
);
15850 FINSN_3ARG_SDPS(SUB
);
15853 FINSN_3ARG_SDPS(MUL
);
15856 fmt
= (ctx
->opcode
>> 8) & 0x3;
15858 mips32_op
= OPC_DIV_D
;
15859 } else if (fmt
== 0) {
15860 mips32_op
= OPC_DIV_S
;
15862 goto pool32f_invalid
;
15866 goto pool32f_invalid
;
15871 switch ((ctx
->opcode
>> 6) & 0x7) {
15872 case MOVN_FMT
: /* SELEQZ_FMT */
15873 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15875 switch ((ctx
->opcode
>> 9) & 0x3) {
15877 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
15880 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
15883 goto pool32f_invalid
;
15887 FINSN_3ARG_SDPS(MOVN
);
15891 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15892 FINSN_3ARG_SDPS(MOVN
);
15894 case MOVZ_FMT
: /* SELNEZ_FMT */
15895 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15897 switch ((ctx
->opcode
>> 9) & 0x3) {
15899 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
15902 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
15905 goto pool32f_invalid
;
15909 FINSN_3ARG_SDPS(MOVZ
);
15913 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15914 FINSN_3ARG_SDPS(MOVZ
);
15917 check_insn(ctx
, ISA_MIPS_R6
);
15918 switch ((ctx
->opcode
>> 9) & 0x3) {
15920 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
15923 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
15926 goto pool32f_invalid
;
15930 check_insn(ctx
, ISA_MIPS_R6
);
15931 switch ((ctx
->opcode
>> 9) & 0x3) {
15933 mips32_op
= OPC_MADDF_S
;
15936 mips32_op
= OPC_MADDF_D
;
15939 goto pool32f_invalid
;
15943 check_insn(ctx
, ISA_MIPS_R6
);
15944 switch ((ctx
->opcode
>> 9) & 0x3) {
15946 mips32_op
= OPC_MSUBF_S
;
15949 mips32_op
= OPC_MSUBF_D
;
15952 goto pool32f_invalid
;
15956 goto pool32f_invalid
;
15960 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15964 MIPS_INVAL("pool32f");
15965 gen_reserved_instruction(ctx
);
15969 generate_exception_err(ctx
, EXCP_CpU
, 1);
15973 minor
= (ctx
->opcode
>> 21) & 0x1f;
15976 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15977 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
15980 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15981 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
15982 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15985 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15986 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
15987 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15990 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15991 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
15994 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15995 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
15996 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15999 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16000 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16001 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16004 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16005 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16008 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16009 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16013 case TLTI
: /* BC1EQZC */
16014 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16016 check_cp1_enabled(ctx
);
16017 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16020 mips32_op
= OPC_TLTI
;
16024 case TGEI
: /* BC1NEZC */
16025 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16027 check_cp1_enabled(ctx
);
16028 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16031 mips32_op
= OPC_TGEI
;
16036 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16037 mips32_op
= OPC_TLTIU
;
16040 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16041 mips32_op
= OPC_TGEIU
;
16043 case TNEI
: /* SYNCI */
16044 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16047 * Break the TB to be able to sync copied instructions
16050 ctx
->base
.is_jmp
= DISAS_STOP
;
16053 mips32_op
= OPC_TNEI
;
16058 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16059 mips32_op
= OPC_TEQI
;
16061 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16066 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16067 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16068 4, rs
, 0, imm
<< 1, 0);
16070 * Compact branches don't have a delay slot, so just let
16071 * the normal delay slot handling take us to the branch
16076 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16077 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16080 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16082 * Break the TB to be able to sync copied instructions
16085 ctx
->base
.is_jmp
= DISAS_STOP
;
16089 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16090 /* COP2: Not implemented. */
16091 generate_exception_err(ctx
, EXCP_CpU
, 2);
16094 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16095 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16098 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16099 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16102 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16103 mips32_op
= OPC_BC1FANY4
;
16106 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16107 mips32_op
= OPC_BC1TANY4
;
16110 check_insn(ctx
, ASE_MIPS3D
);
16113 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16114 check_cp1_enabled(ctx
);
16115 gen_compute_branch1(ctx
, mips32_op
,
16116 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16118 generate_exception_err(ctx
, EXCP_CpU
, 1);
16122 MIPS_INVAL("pool32i");
16123 gen_reserved_instruction(ctx
);
16128 minor
= (ctx
->opcode
>> 12) & 0xf;
16129 offset
= sextract32(ctx
->opcode
, 0,
16130 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16133 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16134 mips32_op
= OPC_LWL
;
16137 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16138 mips32_op
= OPC_SWL
;
16141 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16142 mips32_op
= OPC_LWR
;
16145 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16146 mips32_op
= OPC_SWR
;
16148 #if defined(TARGET_MIPS64)
16150 check_insn(ctx
, ISA_MIPS3
);
16151 check_mips_64(ctx
);
16152 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16153 mips32_op
= OPC_LDL
;
16156 check_insn(ctx
, ISA_MIPS3
);
16157 check_mips_64(ctx
);
16158 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16159 mips32_op
= OPC_SDL
;
16162 check_insn(ctx
, ISA_MIPS3
);
16163 check_mips_64(ctx
);
16164 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16165 mips32_op
= OPC_LDR
;
16168 check_insn(ctx
, ISA_MIPS3
);
16169 check_mips_64(ctx
);
16170 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16171 mips32_op
= OPC_SDR
;
16174 check_insn(ctx
, ISA_MIPS3
);
16175 check_mips_64(ctx
);
16176 mips32_op
= OPC_LWU
;
16179 check_insn(ctx
, ISA_MIPS3
);
16180 check_mips_64(ctx
);
16181 mips32_op
= OPC_LLD
;
16185 mips32_op
= OPC_LL
;
16188 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16191 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16194 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16196 #if defined(TARGET_MIPS64)
16198 check_insn(ctx
, ISA_MIPS3
);
16199 check_mips_64(ctx
);
16200 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16205 MIPS_INVAL("pool32c ld-eva");
16206 gen_reserved_instruction(ctx
);
16209 check_cp0_enabled(ctx
);
16211 minor2
= (ctx
->opcode
>> 9) & 0x7;
16212 offset
= sextract32(ctx
->opcode
, 0, 9);
16215 mips32_op
= OPC_LBUE
;
16218 mips32_op
= OPC_LHUE
;
16221 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16222 mips32_op
= OPC_LWLE
;
16225 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16226 mips32_op
= OPC_LWRE
;
16229 mips32_op
= OPC_LBE
;
16232 mips32_op
= OPC_LHE
;
16235 mips32_op
= OPC_LLE
;
16238 mips32_op
= OPC_LWE
;
16244 MIPS_INVAL("pool32c st-eva");
16245 gen_reserved_instruction(ctx
);
16248 check_cp0_enabled(ctx
);
16250 minor2
= (ctx
->opcode
>> 9) & 0x7;
16251 offset
= sextract32(ctx
->opcode
, 0, 9);
16254 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16255 mips32_op
= OPC_SWLE
;
16258 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16259 mips32_op
= OPC_SWRE
;
16262 /* Treat as no-op */
16263 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16264 /* hint codes 24-31 are reserved and signal RI */
16265 generate_exception(ctx
, EXCP_RI
);
16269 /* Treat as no-op */
16270 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16271 gen_cache_operation(ctx
, rt
, rs
, offset
);
16275 mips32_op
= OPC_SBE
;
16278 mips32_op
= OPC_SHE
;
16281 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16284 mips32_op
= OPC_SWE
;
16289 /* Treat as no-op */
16290 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16291 /* hint codes 24-31 are reserved and signal RI */
16292 generate_exception(ctx
, EXCP_RI
);
16296 MIPS_INVAL("pool32c");
16297 gen_reserved_instruction(ctx
);
16301 case ADDI32
: /* AUI, LUI */
16302 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16304 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16307 mips32_op
= OPC_ADDI
;
16312 mips32_op
= OPC_ADDIU
;
16314 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16317 /* Logical operations */
16319 mips32_op
= OPC_ORI
;
16322 mips32_op
= OPC_XORI
;
16325 mips32_op
= OPC_ANDI
;
16327 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16330 /* Set less than immediate */
16332 mips32_op
= OPC_SLTI
;
16335 mips32_op
= OPC_SLTIU
;
16337 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16340 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16341 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16342 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16343 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16345 case JALS32
: /* BOVC, BEQC, BEQZALC */
16346 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16349 mips32_op
= OPC_BOVC
;
16350 } else if (rs
< rt
&& rs
== 0) {
16352 mips32_op
= OPC_BEQZALC
;
16355 mips32_op
= OPC_BEQC
;
16357 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16360 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16361 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16362 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16365 case BEQ32
: /* BC */
16366 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16368 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16369 sextract32(ctx
->opcode
<< 1, 0, 27));
16372 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16375 case BNE32
: /* BALC */
16376 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16378 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16379 sextract32(ctx
->opcode
<< 1, 0, 27));
16382 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16385 case J32
: /* BGTZC, BLTZC, BLTC */
16386 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16387 if (rs
== 0 && rt
!= 0) {
16389 mips32_op
= OPC_BGTZC
;
16390 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16392 mips32_op
= OPC_BLTZC
;
16395 mips32_op
= OPC_BLTC
;
16397 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16400 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16401 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16404 case JAL32
: /* BLEZC, BGEZC, BGEC */
16405 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16406 if (rs
== 0 && rt
!= 0) {
16408 mips32_op
= OPC_BLEZC
;
16409 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16411 mips32_op
= OPC_BGEZC
;
16414 mips32_op
= OPC_BGEC
;
16416 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16419 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16420 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16421 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16424 /* Floating point (COP1) */
16426 mips32_op
= OPC_LWC1
;
16429 mips32_op
= OPC_LDC1
;
16432 mips32_op
= OPC_SWC1
;
16435 mips32_op
= OPC_SDC1
;
16437 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16439 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16440 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16441 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16442 switch ((ctx
->opcode
>> 16) & 0x1f) {
16451 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16454 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16457 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16467 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16470 generate_exception(ctx
, EXCP_RI
);
16475 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16476 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16478 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16481 case BNVC
: /* BNEC, BNEZALC */
16482 check_insn(ctx
, ISA_MIPS_R6
);
16485 mips32_op
= OPC_BNVC
;
16486 } else if (rs
< rt
&& rs
== 0) {
16488 mips32_op
= OPC_BNEZALC
;
16491 mips32_op
= OPC_BNEC
;
16493 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16495 case R6_BNEZC
: /* JIALC */
16496 check_insn(ctx
, ISA_MIPS_R6
);
16499 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16500 sextract32(ctx
->opcode
<< 1, 0, 22));
16503 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16506 case R6_BEQZC
: /* JIC */
16507 check_insn(ctx
, ISA_MIPS_R6
);
16510 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16511 sextract32(ctx
->opcode
<< 1, 0, 22));
16514 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16517 case BLEZALC
: /* BGEZALC, BGEUC */
16518 check_insn(ctx
, ISA_MIPS_R6
);
16519 if (rs
== 0 && rt
!= 0) {
16521 mips32_op
= OPC_BLEZALC
;
16522 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16524 mips32_op
= OPC_BGEZALC
;
16527 mips32_op
= OPC_BGEUC
;
16529 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16531 case BGTZALC
: /* BLTZALC, BLTUC */
16532 check_insn(ctx
, ISA_MIPS_R6
);
16533 if (rs
== 0 && rt
!= 0) {
16535 mips32_op
= OPC_BGTZALC
;
16536 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16538 mips32_op
= OPC_BLTZALC
;
16541 mips32_op
= OPC_BLTUC
;
16543 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16545 /* Loads and stores */
16547 mips32_op
= OPC_LB
;
16550 mips32_op
= OPC_LBU
;
16553 mips32_op
= OPC_LH
;
16556 mips32_op
= OPC_LHU
;
16559 mips32_op
= OPC_LW
;
16561 #ifdef TARGET_MIPS64
16563 check_insn(ctx
, ISA_MIPS3
);
16564 check_mips_64(ctx
);
16565 mips32_op
= OPC_LD
;
16568 check_insn(ctx
, ISA_MIPS3
);
16569 check_mips_64(ctx
);
16570 mips32_op
= OPC_SD
;
16574 mips32_op
= OPC_SB
;
16577 mips32_op
= OPC_SH
;
16580 mips32_op
= OPC_SW
;
16583 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16586 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16589 gen_reserved_instruction(ctx
);
16594 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16598 /* make sure instructions are on a halfword boundary */
16599 if (ctx
->base
.pc_next
& 0x1) {
16600 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16601 generate_exception_end(ctx
, EXCP_AdEL
);
16605 op
= (ctx
->opcode
>> 10) & 0x3f;
16606 /* Enforce properly-sized instructions in a delay slot */
16607 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16608 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16610 /* POOL32A, POOL32B, POOL32I, POOL32C */
16612 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16614 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16616 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16618 /* LB32, LH32, LWC132, LDC132, LW32 */
16619 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16620 gen_reserved_instruction(ctx
);
16625 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16627 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16629 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16630 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16631 gen_reserved_instruction(ctx
);
16641 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16642 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
16643 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
16646 switch (ctx
->opcode
& 0x1) {
16654 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16656 * In the Release 6, the register number location in
16657 * the instruction encoding has changed.
16659 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
16661 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
16667 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16668 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
16669 int amount
= (ctx
->opcode
>> 1) & 0x7;
16671 amount
= amount
== 0 ? 8 : amount
;
16673 switch (ctx
->opcode
& 0x1) {
16682 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
16686 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16687 gen_pool16c_r6_insn(ctx
);
16689 gen_pool16c_insn(ctx
);
16694 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16695 int rb
= 28; /* GP */
16696 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
16698 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16702 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16703 if (ctx
->opcode
& 1) {
16704 gen_reserved_instruction(ctx
);
16707 int enc_dest
= uMIPS_RD(ctx
->opcode
);
16708 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
16709 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
16710 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
16715 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16716 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16717 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16718 offset
= (offset
== 0xf ? -1 : offset
);
16720 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
16725 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16726 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16727 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16729 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
16734 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16735 int rb
= 29; /* SP */
16736 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16738 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16743 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16744 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16745 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16747 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16752 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16753 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16754 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16756 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
16761 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16762 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16763 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16765 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
16770 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16771 int rb
= 29; /* SP */
16772 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16774 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16779 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16780 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16781 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16783 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16788 int rd
= uMIPS_RD5(ctx
->opcode
);
16789 int rs
= uMIPS_RS5(ctx
->opcode
);
16791 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
16798 switch (ctx
->opcode
& 0x1) {
16808 switch (ctx
->opcode
& 0x1) {
16813 gen_addiur1sp(ctx
);
16817 case B16
: /* BC16 */
16818 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
16819 sextract32(ctx
->opcode
, 0, 10) << 1,
16820 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16822 case BNEZ16
: /* BNEZC16 */
16823 case BEQZ16
: /* BEQZC16 */
16824 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
16825 mmreg(uMIPS_RD(ctx
->opcode
)),
16826 0, sextract32(ctx
->opcode
, 0, 7) << 1,
16827 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16832 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
16833 int imm
= ZIMM(ctx
->opcode
, 0, 7);
16835 imm
= (imm
== 0x7f ? -1 : imm
);
16836 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
16842 gen_reserved_instruction(ctx
);
16845 decode_micromips32_opc(env
, ctx
);
16858 /* MAJOR, P16, and P32 pools opcodes */
16862 NM_MOVE_BALC
= 0x02,
16870 NM_P16_SHIFT
= 0x0c,
16888 NM_P_LS_U12
= 0x21,
16898 NM_P16_ADDU
= 0x2c,
16912 NM_MOVEPREV
= 0x3f,
16915 /* POOL32A instruction pool */
16917 NM_POOL32A0
= 0x00,
16918 NM_SPECIAL2
= 0x01,
16921 NM_POOL32A5
= 0x05,
16922 NM_POOL32A7
= 0x07,
16925 /* P.GP.W instruction pool */
16927 NM_ADDIUGP_W
= 0x00,
16932 /* P48I instruction pool */
16936 NM_ADDIUGP48
= 0x02,
16937 NM_ADDIUPC48
= 0x03,
16942 /* P.U12 instruction pool */
16951 NM_ADDIUNEG
= 0x08,
16958 /* POOL32F instruction pool */
16960 NM_POOL32F_0
= 0x00,
16961 NM_POOL32F_3
= 0x03,
16962 NM_POOL32F_5
= 0x05,
16965 /* POOL32S instruction pool */
16967 NM_POOL32S_0
= 0x00,
16968 NM_POOL32S_4
= 0x04,
16971 /* P.LUI instruction pool */
16977 /* P.GP.BH instruction pool */
16982 NM_ADDIUGP_B
= 0x03,
16985 NM_P_GP_CP1
= 0x06,
16988 /* P.LS.U12 instruction pool */
16993 NM_P_PREFU12
= 0x03,
17006 /* P.LS.S9 instruction pool */
17012 NM_P_LS_UAWM
= 0x05,
17015 /* P.BAL instruction pool */
17021 /* P.J instruction pool */
17024 NM_JALRC_HB
= 0x01,
17025 NM_P_BALRSC
= 0x08,
17028 /* P.BR1 instruction pool */
17036 /* P.BR2 instruction pool */
17043 /* P.BRI instruction pool */
17055 /* P16.SHIFT instruction pool */
17061 /* POOL16C instruction pool */
17063 NM_POOL16C_0
= 0x00,
17067 /* P16.A1 instruction pool */
17069 NM_ADDIUR1SP
= 0x01,
17072 /* P16.A2 instruction pool */
17075 NM_P_ADDIURS5
= 0x01,
17078 /* P16.ADDU instruction pool */
17084 /* P16.SR instruction pool */
17087 NM_RESTORE_JRC16
= 0x01,
17090 /* P16.4X4 instruction pool */
17096 /* P16.LB instruction pool */
17103 /* P16.LH instruction pool */
17110 /* P.RI instruction pool */
17113 NM_P_SYSCALL
= 0x01,
17118 /* POOL32A0 instruction pool */
17153 NM_D_E_MT_VPE
= 0x56,
17161 /* CRC32 instruction pool */
17171 /* POOL32A5 instruction pool */
17173 NM_CMP_EQ_PH
= 0x00,
17174 NM_CMP_LT_PH
= 0x08,
17175 NM_CMP_LE_PH
= 0x10,
17176 NM_CMPGU_EQ_QB
= 0x18,
17177 NM_CMPGU_LT_QB
= 0x20,
17178 NM_CMPGU_LE_QB
= 0x28,
17179 NM_CMPGDU_EQ_QB
= 0x30,
17180 NM_CMPGDU_LT_QB
= 0x38,
17181 NM_CMPGDU_LE_QB
= 0x40,
17182 NM_CMPU_EQ_QB
= 0x48,
17183 NM_CMPU_LT_QB
= 0x50,
17184 NM_CMPU_LE_QB
= 0x58,
17185 NM_ADDQ_S_W
= 0x60,
17186 NM_SUBQ_S_W
= 0x68,
17190 NM_ADDQ_S_PH
= 0x01,
17191 NM_ADDQH_R_PH
= 0x09,
17192 NM_ADDQH_R_W
= 0x11,
17193 NM_ADDU_S_QB
= 0x19,
17194 NM_ADDU_S_PH
= 0x21,
17195 NM_ADDUH_R_QB
= 0x29,
17196 NM_SHRAV_R_PH
= 0x31,
17197 NM_SHRAV_R_QB
= 0x39,
17198 NM_SUBQ_S_PH
= 0x41,
17199 NM_SUBQH_R_PH
= 0x49,
17200 NM_SUBQH_R_W
= 0x51,
17201 NM_SUBU_S_QB
= 0x59,
17202 NM_SUBU_S_PH
= 0x61,
17203 NM_SUBUH_R_QB
= 0x69,
17204 NM_SHLLV_S_PH
= 0x71,
17205 NM_PRECR_SRA_R_PH_W
= 0x79,
17207 NM_MULEU_S_PH_QBL
= 0x12,
17208 NM_MULEU_S_PH_QBR
= 0x1a,
17209 NM_MULQ_RS_PH
= 0x22,
17210 NM_MULQ_S_PH
= 0x2a,
17211 NM_MULQ_RS_W
= 0x32,
17212 NM_MULQ_S_W
= 0x3a,
17215 NM_SHRAV_R_W
= 0x5a,
17216 NM_SHRLV_PH
= 0x62,
17217 NM_SHRLV_QB
= 0x6a,
17218 NM_SHLLV_QB
= 0x72,
17219 NM_SHLLV_S_W
= 0x7a,
17223 NM_MULEQ_S_W_PHL
= 0x04,
17224 NM_MULEQ_S_W_PHR
= 0x0c,
17226 NM_MUL_S_PH
= 0x05,
17227 NM_PRECR_QB_PH
= 0x0d,
17228 NM_PRECRQ_QB_PH
= 0x15,
17229 NM_PRECRQ_PH_W
= 0x1d,
17230 NM_PRECRQ_RS_PH_W
= 0x25,
17231 NM_PRECRQU_S_QB_PH
= 0x2d,
17232 NM_PACKRL_PH
= 0x35,
17236 NM_SHRA_R_W
= 0x5e,
17237 NM_SHRA_R_PH
= 0x66,
17238 NM_SHLL_S_PH
= 0x76,
17239 NM_SHLL_S_W
= 0x7e,
17244 /* POOL32A7 instruction pool */
17249 NM_POOL32AXF
= 0x07,
17252 /* P.SR instruction pool */
17258 /* P.SHIFT instruction pool */
17266 /* P.ROTX instruction pool */
17271 /* P.INS instruction pool */
17276 /* P.EXT instruction pool */
17281 /* POOL32F_0 (fmt) instruction pool */
17286 NM_SELEQZ_S
= 0x07,
17287 NM_SELEQZ_D
= 0x47,
17291 NM_SELNEZ_S
= 0x0f,
17292 NM_SELNEZ_D
= 0x4f,
17307 /* POOL32F_3 instruction pool */
17311 NM_MINA_FMT
= 0x04,
17312 NM_MAXA_FMT
= 0x05,
17313 NM_POOL32FXF
= 0x07,
17316 /* POOL32F_5 instruction pool */
17318 NM_CMP_CONDN_S
= 0x00,
17319 NM_CMP_CONDN_D
= 0x02,
17322 /* P.GP.LH instruction pool */
17328 /* P.GP.SH instruction pool */
17333 /* P.GP.CP1 instruction pool */
17341 /* P.LS.S0 instruction pool */
17358 NM_P_PREFS9
= 0x03,
17364 /* P.LS.S1 instruction pool */
17366 NM_ASET_ACLR
= 0x02,
17374 /* P.LS.E0 instruction pool */
17390 /* P.PREFE instruction pool */
17396 /* P.LLE instruction pool */
17402 /* P.SCE instruction pool */
17408 /* P.LS.WM instruction pool */
17414 /* P.LS.UAWM instruction pool */
17420 /* P.BR3A instruction pool */
17426 NM_BPOSGE32C
= 0x04,
17429 /* P16.RI instruction pool */
17431 NM_P16_SYSCALL
= 0x01,
17436 /* POOL16C_0 instruction pool */
17438 NM_POOL16C_00
= 0x00,
17441 /* P16.JRC instruction pool */
17447 /* P.SYSCALL instruction pool */
17453 /* P.TRAP instruction pool */
17459 /* P.CMOVE instruction pool */
17465 /* POOL32Axf instruction pool */
17467 NM_POOL32AXF_1
= 0x01,
17468 NM_POOL32AXF_2
= 0x02,
17469 NM_POOL32AXF_4
= 0x04,
17470 NM_POOL32AXF_5
= 0x05,
17471 NM_POOL32AXF_7
= 0x07,
17474 /* POOL32Axf_1 instruction pool */
17476 NM_POOL32AXF_1_0
= 0x00,
17477 NM_POOL32AXF_1_1
= 0x01,
17478 NM_POOL32AXF_1_3
= 0x03,
17479 NM_POOL32AXF_1_4
= 0x04,
17480 NM_POOL32AXF_1_5
= 0x05,
17481 NM_POOL32AXF_1_7
= 0x07,
17484 /* POOL32Axf_2 instruction pool */
17486 NM_POOL32AXF_2_0_7
= 0x00,
17487 NM_POOL32AXF_2_8_15
= 0x01,
17488 NM_POOL32AXF_2_16_23
= 0x02,
17489 NM_POOL32AXF_2_24_31
= 0x03,
17492 /* POOL32Axf_7 instruction pool */
17494 NM_SHRA_R_QB
= 0x0,
17499 /* POOL32Axf_1_0 instruction pool */
17507 /* POOL32Axf_1_1 instruction pool */
17513 /* POOL32Axf_1_3 instruction pool */
17521 /* POOL32Axf_1_4 instruction pool */
17527 /* POOL32Axf_1_5 instruction pool */
17529 NM_MAQ_S_W_PHR
= 0x0,
17530 NM_MAQ_S_W_PHL
= 0x1,
17531 NM_MAQ_SA_W_PHR
= 0x2,
17532 NM_MAQ_SA_W_PHL
= 0x3,
17535 /* POOL32Axf_1_7 instruction pool */
17539 NM_EXTR_RS_W
= 0x2,
17543 /* POOL32Axf_2_0_7 instruction pool */
17546 NM_DPAQ_S_W_PH
= 0x1,
17548 NM_DPSQ_S_W_PH
= 0x3,
17555 /* POOL32Axf_2_8_15 instruction pool */
17557 NM_DPAX_W_PH
= 0x0,
17558 NM_DPAQ_SA_L_W
= 0x1,
17559 NM_DPSX_W_PH
= 0x2,
17560 NM_DPSQ_SA_L_W
= 0x3,
17563 NM_EXTRV_R_W
= 0x7,
17566 /* POOL32Axf_2_16_23 instruction pool */
17568 NM_DPAU_H_QBL
= 0x0,
17569 NM_DPAQX_S_W_PH
= 0x1,
17570 NM_DPSU_H_QBL
= 0x2,
17571 NM_DPSQX_S_W_PH
= 0x3,
17574 NM_MULSA_W_PH
= 0x6,
17575 NM_EXTRV_RS_W
= 0x7,
17578 /* POOL32Axf_2_24_31 instruction pool */
17580 NM_DPAU_H_QBR
= 0x0,
17581 NM_DPAQX_SA_W_PH
= 0x1,
17582 NM_DPSU_H_QBR
= 0x2,
17583 NM_DPSQX_SA_W_PH
= 0x3,
17586 NM_MULSAQ_S_W_PH
= 0x6,
17587 NM_EXTRV_S_H
= 0x7,
17590 /* POOL32Axf_{4, 5} instruction pool */
17609 /* nanoMIPS DSP instructions */
17610 NM_ABSQ_S_QB
= 0x00,
17611 NM_ABSQ_S_PH
= 0x08,
17612 NM_ABSQ_S_W
= 0x10,
17613 NM_PRECEQ_W_PHL
= 0x28,
17614 NM_PRECEQ_W_PHR
= 0x30,
17615 NM_PRECEQU_PH_QBL
= 0x38,
17616 NM_PRECEQU_PH_QBR
= 0x48,
17617 NM_PRECEU_PH_QBL
= 0x58,
17618 NM_PRECEU_PH_QBR
= 0x68,
17619 NM_PRECEQU_PH_QBLA
= 0x39,
17620 NM_PRECEQU_PH_QBRA
= 0x49,
17621 NM_PRECEU_PH_QBLA
= 0x59,
17622 NM_PRECEU_PH_QBRA
= 0x69,
17623 NM_REPLV_PH
= 0x01,
17624 NM_REPLV_QB
= 0x09,
17627 NM_RADDU_W_QB
= 0x78,
17633 /* PP.SR instruction pool */
17637 NM_RESTORE_JRC
= 0x03,
17640 /* P.SR.F instruction pool */
17643 NM_RESTOREF
= 0x01,
17646 /* P16.SYSCALL instruction pool */
17648 NM_SYSCALL16
= 0x00,
17649 NM_HYPCALL16
= 0x01,
17652 /* POOL16C_00 instruction pool */
17660 /* PP.LSX and PP.LSXS instruction pool */
17698 /* ERETx instruction pool */
17704 /* POOL32FxF_{0, 1} insturction pool */
17713 NM_CVT_S_PL
= 0x84,
17714 NM_CVT_S_PU
= 0xa4,
17716 NM_CVT_L_S
= 0x004,
17717 NM_CVT_L_D
= 0x104,
17718 NM_CVT_W_S
= 0x024,
17719 NM_CVT_W_D
= 0x124,
17721 NM_RSQRT_S
= 0x008,
17722 NM_RSQRT_D
= 0x108,
17727 NM_RECIP_S
= 0x048,
17728 NM_RECIP_D
= 0x148,
17730 NM_FLOOR_L_S
= 0x00c,
17731 NM_FLOOR_L_D
= 0x10c,
17733 NM_FLOOR_W_S
= 0x02c,
17734 NM_FLOOR_W_D
= 0x12c,
17736 NM_CEIL_L_S
= 0x04c,
17737 NM_CEIL_L_D
= 0x14c,
17738 NM_CEIL_W_S
= 0x06c,
17739 NM_CEIL_W_D
= 0x16c,
17740 NM_TRUNC_L_S
= 0x08c,
17741 NM_TRUNC_L_D
= 0x18c,
17742 NM_TRUNC_W_S
= 0x0ac,
17743 NM_TRUNC_W_D
= 0x1ac,
17744 NM_ROUND_L_S
= 0x0cc,
17745 NM_ROUND_L_D
= 0x1cc,
17746 NM_ROUND_W_S
= 0x0ec,
17747 NM_ROUND_W_D
= 0x1ec,
17755 NM_CVT_D_S
= 0x04d,
17756 NM_CVT_D_W
= 0x0cd,
17757 NM_CVT_D_L
= 0x14d,
17758 NM_CVT_S_D
= 0x06d,
17759 NM_CVT_S_W
= 0x0ed,
17760 NM_CVT_S_L
= 0x16d,
17763 /* P.LL instruction pool */
17769 /* P.SC instruction pool */
17775 /* P.DVP instruction pool */
17784 * nanoMIPS decoding engine
17789 /* extraction utilities */
17791 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17792 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17793 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17794 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17795 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17797 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17798 static inline int decode_gpr_gpr3(int r
)
17800 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17802 return map
[r
& 0x7];
17805 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17806 static inline int decode_gpr_gpr3_src_store(int r
)
17808 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17810 return map
[r
& 0x7];
17813 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17814 static inline int decode_gpr_gpr4(int r
)
17816 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17817 16, 17, 18, 19, 20, 21, 22, 23 };
17819 return map
[r
& 0xf];
17822 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17823 static inline int decode_gpr_gpr4_zero(int r
)
17825 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17826 16, 17, 18, 19, 20, 21, 22, 23 };
17828 return map
[r
& 0xf];
17832 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
17834 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
17837 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17838 uint8_t gp
, uint16_t u
)
17841 TCGv va
= tcg_temp_new();
17842 TCGv t0
= tcg_temp_new();
17844 while (counter
!= count
) {
17845 bool use_gp
= gp
&& (counter
== count
- 1);
17846 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17847 int this_offset
= -((counter
+ 1) << 2);
17848 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17849 gen_load_gpr(t0
, this_rt
);
17850 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
17851 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
17855 /* adjust stack pointer */
17856 gen_adjust_sp(ctx
, -u
);
17862 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17863 uint8_t gp
, uint16_t u
)
17866 TCGv va
= tcg_temp_new();
17867 TCGv t0
= tcg_temp_new();
17869 while (counter
!= count
) {
17870 bool use_gp
= gp
&& (counter
== count
- 1);
17871 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17872 int this_offset
= u
- ((counter
+ 1) << 2);
17873 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17874 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
17875 ctx
->default_tcg_memop_mask
);
17876 tcg_gen_ext32s_tl(t0
, t0
);
17877 gen_store_gpr(t0
, this_rt
);
17881 /* adjust stack pointer */
17882 gen_adjust_sp(ctx
, u
);
17888 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
17890 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
17891 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
17893 switch (extract32(ctx
->opcode
, 2, 2)) {
17895 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
17898 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
17901 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
17904 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
17909 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
17911 int rt
= extract32(ctx
->opcode
, 21, 5);
17912 int rs
= extract32(ctx
->opcode
, 16, 5);
17913 int rd
= extract32(ctx
->opcode
, 11, 5);
17915 switch (extract32(ctx
->opcode
, 3, 7)) {
17917 switch (extract32(ctx
->opcode
, 10, 1)) {
17920 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
17924 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
17930 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
17934 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
17937 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
17940 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
17943 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
17946 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
17949 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
17952 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
17955 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
17959 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
17962 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
17965 switch (extract32(ctx
->opcode
, 10, 1)) {
17967 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
17970 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
17975 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
17978 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
17981 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
17984 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
17987 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
17992 #ifndef CONFIG_USER_ONLY
17993 TCGv t0
= tcg_temp_new();
17994 switch (extract32(ctx
->opcode
, 10, 1)) {
17997 check_cp0_enabled(ctx
);
17998 gen_helper_dvp(t0
, cpu_env
);
17999 gen_store_gpr(t0
, rt
);
18004 check_cp0_enabled(ctx
);
18005 gen_helper_evp(t0
, cpu_env
);
18006 gen_store_gpr(t0
, rt
);
18013 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18018 TCGv t0
= tcg_temp_new();
18019 TCGv t1
= tcg_temp_new();
18020 TCGv t2
= tcg_temp_new();
18022 gen_load_gpr(t1
, rs
);
18023 gen_load_gpr(t2
, rt
);
18024 tcg_gen_add_tl(t0
, t1
, t2
);
18025 tcg_gen_ext32s_tl(t0
, t0
);
18026 tcg_gen_xor_tl(t1
, t1
, t2
);
18027 tcg_gen_xor_tl(t2
, t0
, t2
);
18028 tcg_gen_andc_tl(t1
, t2
, t1
);
18030 /* operands of same sign, result different sign */
18031 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18032 gen_store_gpr(t0
, rd
);
18040 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18043 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18046 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18049 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18052 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18055 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18058 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18061 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18063 #ifndef CONFIG_USER_ONLY
18065 check_cp0_enabled(ctx
);
18067 /* Treat as NOP. */
18070 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18073 check_cp0_enabled(ctx
);
18075 TCGv t0
= tcg_temp_new();
18077 gen_load_gpr(t0
, rt
);
18078 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18082 case NM_D_E_MT_VPE
:
18084 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18085 TCGv t0
= tcg_temp_new();
18092 gen_helper_dmt(t0
);
18093 gen_store_gpr(t0
, rt
);
18094 } else if (rs
== 0) {
18097 gen_helper_dvpe(t0
, cpu_env
);
18098 gen_store_gpr(t0
, rt
);
18100 gen_reserved_instruction(ctx
);
18107 gen_helper_emt(t0
);
18108 gen_store_gpr(t0
, rt
);
18109 } else if (rs
== 0) {
18112 gen_helper_evpe(t0
, cpu_env
);
18113 gen_store_gpr(t0
, rt
);
18115 gen_reserved_instruction(ctx
);
18126 TCGv t0
= tcg_temp_new();
18127 TCGv t1
= tcg_temp_new();
18129 gen_load_gpr(t0
, rt
);
18130 gen_load_gpr(t1
, rs
);
18131 gen_helper_fork(t0
, t1
);
18138 check_cp0_enabled(ctx
);
18140 /* Treat as NOP. */
18143 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18144 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18148 check_cp0_enabled(ctx
);
18149 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18150 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18155 TCGv t0
= tcg_temp_new();
18157 gen_load_gpr(t0
, rs
);
18158 gen_helper_yield(t0
, cpu_env
, t0
);
18159 gen_store_gpr(t0
, rt
);
18165 gen_reserved_instruction(ctx
);
18171 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18172 int ret
, int v1
, int v2
)
18178 t0
= tcg_temp_new_i32();
18180 v0_t
= tcg_temp_new();
18181 v1_t
= tcg_temp_new();
18183 tcg_gen_movi_i32(t0
, v2
>> 3);
18185 gen_load_gpr(v0_t
, ret
);
18186 gen_load_gpr(v1_t
, v1
);
18189 case NM_MAQ_S_W_PHR
:
18191 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18193 case NM_MAQ_S_W_PHL
:
18195 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18197 case NM_MAQ_SA_W_PHR
:
18199 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18201 case NM_MAQ_SA_W_PHL
:
18203 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18206 gen_reserved_instruction(ctx
);
18210 tcg_temp_free_i32(t0
);
18212 tcg_temp_free(v0_t
);
18213 tcg_temp_free(v1_t
);
18217 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18218 int ret
, int v1
, int v2
)
18221 TCGv t0
= tcg_temp_new();
18222 TCGv t1
= tcg_temp_new();
18223 TCGv v0_t
= tcg_temp_new();
18225 gen_load_gpr(v0_t
, v1
);
18228 case NM_POOL32AXF_1_0
:
18230 switch (extract32(ctx
->opcode
, 12, 2)) {
18232 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18235 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18238 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18241 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18245 case NM_POOL32AXF_1_1
:
18247 switch (extract32(ctx
->opcode
, 12, 2)) {
18249 tcg_gen_movi_tl(t0
, v2
);
18250 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18253 tcg_gen_movi_tl(t0
, v2
>> 3);
18254 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18257 gen_reserved_instruction(ctx
);
18261 case NM_POOL32AXF_1_3
:
18263 imm
= extract32(ctx
->opcode
, 14, 7);
18264 switch (extract32(ctx
->opcode
, 12, 2)) {
18266 tcg_gen_movi_tl(t0
, imm
);
18267 gen_helper_rddsp(t0
, t0
, cpu_env
);
18268 gen_store_gpr(t0
, ret
);
18271 gen_load_gpr(t0
, ret
);
18272 tcg_gen_movi_tl(t1
, imm
);
18273 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18276 tcg_gen_movi_tl(t0
, v2
>> 3);
18277 tcg_gen_movi_tl(t1
, v1
);
18278 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18279 gen_store_gpr(t0
, ret
);
18282 tcg_gen_movi_tl(t0
, v2
>> 3);
18283 tcg_gen_movi_tl(t1
, v1
);
18284 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18285 gen_store_gpr(t0
, ret
);
18289 case NM_POOL32AXF_1_4
:
18291 tcg_gen_movi_tl(t0
, v2
>> 2);
18292 switch (extract32(ctx
->opcode
, 12, 1)) {
18294 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18295 gen_store_gpr(t0
, ret
);
18298 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18299 gen_store_gpr(t0
, ret
);
18303 case NM_POOL32AXF_1_5
:
18304 opc
= extract32(ctx
->opcode
, 12, 2);
18305 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18307 case NM_POOL32AXF_1_7
:
18309 tcg_gen_movi_tl(t0
, v2
>> 3);
18310 tcg_gen_movi_tl(t1
, v1
);
18311 switch (extract32(ctx
->opcode
, 12, 2)) {
18313 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18314 gen_store_gpr(t0
, ret
);
18317 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18318 gen_store_gpr(t0
, ret
);
18321 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18322 gen_store_gpr(t0
, ret
);
18325 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18326 gen_store_gpr(t0
, ret
);
18331 gen_reserved_instruction(ctx
);
18337 tcg_temp_free(v0_t
);
18340 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18341 TCGv v0
, TCGv v1
, int rd
)
18345 t0
= tcg_temp_new_i32();
18347 tcg_gen_movi_i32(t0
, rd
>> 3);
18350 case NM_POOL32AXF_2_0_7
:
18351 switch (extract32(ctx
->opcode
, 9, 3)) {
18354 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18356 case NM_DPAQ_S_W_PH
:
18358 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18362 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18364 case NM_DPSQ_S_W_PH
:
18366 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18369 gen_reserved_instruction(ctx
);
18373 case NM_POOL32AXF_2_8_15
:
18374 switch (extract32(ctx
->opcode
, 9, 3)) {
18377 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18379 case NM_DPAQ_SA_L_W
:
18381 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18385 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18387 case NM_DPSQ_SA_L_W
:
18389 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18392 gen_reserved_instruction(ctx
);
18396 case NM_POOL32AXF_2_16_23
:
18397 switch (extract32(ctx
->opcode
, 9, 3)) {
18398 case NM_DPAU_H_QBL
:
18400 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18402 case NM_DPAQX_S_W_PH
:
18404 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18406 case NM_DPSU_H_QBL
:
18408 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18410 case NM_DPSQX_S_W_PH
:
18412 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18414 case NM_MULSA_W_PH
:
18416 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18419 gen_reserved_instruction(ctx
);
18423 case NM_POOL32AXF_2_24_31
:
18424 switch (extract32(ctx
->opcode
, 9, 3)) {
18425 case NM_DPAU_H_QBR
:
18427 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18429 case NM_DPAQX_SA_W_PH
:
18431 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18433 case NM_DPSU_H_QBR
:
18435 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18437 case NM_DPSQX_SA_W_PH
:
18439 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18441 case NM_MULSAQ_S_W_PH
:
18443 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18446 gen_reserved_instruction(ctx
);
18451 gen_reserved_instruction(ctx
);
18455 tcg_temp_free_i32(t0
);
18458 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18459 int rt
, int rs
, int rd
)
18462 TCGv t0
= tcg_temp_new();
18463 TCGv t1
= tcg_temp_new();
18464 TCGv v0_t
= tcg_temp_new();
18465 TCGv v1_t
= tcg_temp_new();
18467 gen_load_gpr(v0_t
, rt
);
18468 gen_load_gpr(v1_t
, rs
);
18471 case NM_POOL32AXF_2_0_7
:
18472 switch (extract32(ctx
->opcode
, 9, 3)) {
18474 case NM_DPAQ_S_W_PH
:
18476 case NM_DPSQ_S_W_PH
:
18477 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18482 gen_load_gpr(t0
, rs
);
18484 if (rd
!= 0 && rd
!= 2) {
18485 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18486 tcg_gen_ext32u_tl(t0
, t0
);
18487 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18488 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18490 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18496 int acc
= extract32(ctx
->opcode
, 14, 2);
18497 TCGv_i64 t2
= tcg_temp_new_i64();
18498 TCGv_i64 t3
= tcg_temp_new_i64();
18500 gen_load_gpr(t0
, rt
);
18501 gen_load_gpr(t1
, rs
);
18502 tcg_gen_ext_tl_i64(t2
, t0
);
18503 tcg_gen_ext_tl_i64(t3
, t1
);
18504 tcg_gen_mul_i64(t2
, t2
, t3
);
18505 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18506 tcg_gen_add_i64(t2
, t2
, t3
);
18507 tcg_temp_free_i64(t3
);
18508 gen_move_low32(cpu_LO
[acc
], t2
);
18509 gen_move_high32(cpu_HI
[acc
], t2
);
18510 tcg_temp_free_i64(t2
);
18516 int acc
= extract32(ctx
->opcode
, 14, 2);
18517 TCGv_i32 t2
= tcg_temp_new_i32();
18518 TCGv_i32 t3
= tcg_temp_new_i32();
18520 gen_load_gpr(t0
, rs
);
18521 gen_load_gpr(t1
, rt
);
18522 tcg_gen_trunc_tl_i32(t2
, t0
);
18523 tcg_gen_trunc_tl_i32(t3
, t1
);
18524 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18525 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18526 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18527 tcg_temp_free_i32(t2
);
18528 tcg_temp_free_i32(t3
);
18533 gen_load_gpr(v1_t
, rs
);
18534 tcg_gen_movi_tl(t0
, rd
>> 3);
18535 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18536 gen_store_gpr(t0
, ret
);
18540 case NM_POOL32AXF_2_8_15
:
18541 switch (extract32(ctx
->opcode
, 9, 3)) {
18543 case NM_DPAQ_SA_L_W
:
18545 case NM_DPSQ_SA_L_W
:
18546 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18551 int acc
= extract32(ctx
->opcode
, 14, 2);
18552 TCGv_i64 t2
= tcg_temp_new_i64();
18553 TCGv_i64 t3
= tcg_temp_new_i64();
18555 gen_load_gpr(t0
, rs
);
18556 gen_load_gpr(t1
, rt
);
18557 tcg_gen_ext32u_tl(t0
, t0
);
18558 tcg_gen_ext32u_tl(t1
, t1
);
18559 tcg_gen_extu_tl_i64(t2
, t0
);
18560 tcg_gen_extu_tl_i64(t3
, t1
);
18561 tcg_gen_mul_i64(t2
, t2
, t3
);
18562 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18563 tcg_gen_add_i64(t2
, t2
, t3
);
18564 tcg_temp_free_i64(t3
);
18565 gen_move_low32(cpu_LO
[acc
], t2
);
18566 gen_move_high32(cpu_HI
[acc
], t2
);
18567 tcg_temp_free_i64(t2
);
18573 int acc
= extract32(ctx
->opcode
, 14, 2);
18574 TCGv_i32 t2
= tcg_temp_new_i32();
18575 TCGv_i32 t3
= tcg_temp_new_i32();
18577 gen_load_gpr(t0
, rs
);
18578 gen_load_gpr(t1
, rt
);
18579 tcg_gen_trunc_tl_i32(t2
, t0
);
18580 tcg_gen_trunc_tl_i32(t3
, t1
);
18581 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18582 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18583 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18584 tcg_temp_free_i32(t2
);
18585 tcg_temp_free_i32(t3
);
18590 tcg_gen_movi_tl(t0
, rd
>> 3);
18591 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18592 gen_store_gpr(t0
, ret
);
18595 gen_reserved_instruction(ctx
);
18599 case NM_POOL32AXF_2_16_23
:
18600 switch (extract32(ctx
->opcode
, 9, 3)) {
18601 case NM_DPAU_H_QBL
:
18602 case NM_DPAQX_S_W_PH
:
18603 case NM_DPSU_H_QBL
:
18604 case NM_DPSQX_S_W_PH
:
18605 case NM_MULSA_W_PH
:
18606 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18610 tcg_gen_movi_tl(t0
, rd
>> 3);
18611 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18612 gen_store_gpr(t0
, ret
);
18617 int acc
= extract32(ctx
->opcode
, 14, 2);
18618 TCGv_i64 t2
= tcg_temp_new_i64();
18619 TCGv_i64 t3
= tcg_temp_new_i64();
18621 gen_load_gpr(t0
, rs
);
18622 gen_load_gpr(t1
, rt
);
18623 tcg_gen_ext_tl_i64(t2
, t0
);
18624 tcg_gen_ext_tl_i64(t3
, t1
);
18625 tcg_gen_mul_i64(t2
, t2
, t3
);
18626 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18627 tcg_gen_sub_i64(t2
, t3
, t2
);
18628 tcg_temp_free_i64(t3
);
18629 gen_move_low32(cpu_LO
[acc
], t2
);
18630 gen_move_high32(cpu_HI
[acc
], t2
);
18631 tcg_temp_free_i64(t2
);
18634 case NM_EXTRV_RS_W
:
18636 tcg_gen_movi_tl(t0
, rd
>> 3);
18637 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18638 gen_store_gpr(t0
, ret
);
18642 case NM_POOL32AXF_2_24_31
:
18643 switch (extract32(ctx
->opcode
, 9, 3)) {
18644 case NM_DPAU_H_QBR
:
18645 case NM_DPAQX_SA_W_PH
:
18646 case NM_DPSU_H_QBR
:
18647 case NM_DPSQX_SA_W_PH
:
18648 case NM_MULSAQ_S_W_PH
:
18649 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18653 tcg_gen_movi_tl(t0
, rd
>> 3);
18654 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
18655 gen_store_gpr(t0
, ret
);
18660 int acc
= extract32(ctx
->opcode
, 14, 2);
18661 TCGv_i64 t2
= tcg_temp_new_i64();
18662 TCGv_i64 t3
= tcg_temp_new_i64();
18664 gen_load_gpr(t0
, rs
);
18665 gen_load_gpr(t1
, rt
);
18666 tcg_gen_ext32u_tl(t0
, t0
);
18667 tcg_gen_ext32u_tl(t1
, t1
);
18668 tcg_gen_extu_tl_i64(t2
, t0
);
18669 tcg_gen_extu_tl_i64(t3
, t1
);
18670 tcg_gen_mul_i64(t2
, t2
, t3
);
18671 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18672 tcg_gen_sub_i64(t2
, t3
, t2
);
18673 tcg_temp_free_i64(t3
);
18674 gen_move_low32(cpu_LO
[acc
], t2
);
18675 gen_move_high32(cpu_HI
[acc
], t2
);
18676 tcg_temp_free_i64(t2
);
18681 tcg_gen_movi_tl(t0
, rd
>> 3);
18682 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
18683 gen_store_gpr(t0
, ret
);
18688 gen_reserved_instruction(ctx
);
18695 tcg_temp_free(v0_t
);
18696 tcg_temp_free(v1_t
);
18699 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18703 TCGv t0
= tcg_temp_new();
18704 TCGv v0_t
= tcg_temp_new();
18706 gen_load_gpr(v0_t
, rs
);
18711 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
18712 gen_store_gpr(v0_t
, ret
);
18716 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
18717 gen_store_gpr(v0_t
, ret
);
18721 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
18722 gen_store_gpr(v0_t
, ret
);
18724 case NM_PRECEQ_W_PHL
:
18726 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
18727 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18728 gen_store_gpr(v0_t
, ret
);
18730 case NM_PRECEQ_W_PHR
:
18732 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
18733 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
18734 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18735 gen_store_gpr(v0_t
, ret
);
18737 case NM_PRECEQU_PH_QBL
:
18739 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
18740 gen_store_gpr(v0_t
, ret
);
18742 case NM_PRECEQU_PH_QBR
:
18744 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
18745 gen_store_gpr(v0_t
, ret
);
18747 case NM_PRECEQU_PH_QBLA
:
18749 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
18750 gen_store_gpr(v0_t
, ret
);
18752 case NM_PRECEQU_PH_QBRA
:
18754 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
18755 gen_store_gpr(v0_t
, ret
);
18757 case NM_PRECEU_PH_QBL
:
18759 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
18760 gen_store_gpr(v0_t
, ret
);
18762 case NM_PRECEU_PH_QBR
:
18764 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
18765 gen_store_gpr(v0_t
, ret
);
18767 case NM_PRECEU_PH_QBLA
:
18769 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
18770 gen_store_gpr(v0_t
, ret
);
18772 case NM_PRECEU_PH_QBRA
:
18774 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
18775 gen_store_gpr(v0_t
, ret
);
18779 tcg_gen_ext16u_tl(v0_t
, v0_t
);
18780 tcg_gen_shli_tl(t0
, v0_t
, 16);
18781 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18782 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18783 gen_store_gpr(v0_t
, ret
);
18787 tcg_gen_ext8u_tl(v0_t
, v0_t
);
18788 tcg_gen_shli_tl(t0
, v0_t
, 8);
18789 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18790 tcg_gen_shli_tl(t0
, v0_t
, 16);
18791 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18792 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18793 gen_store_gpr(v0_t
, ret
);
18797 gen_helper_bitrev(v0_t
, v0_t
);
18798 gen_store_gpr(v0_t
, ret
);
18803 TCGv tv0
= tcg_temp_new();
18805 gen_load_gpr(tv0
, rt
);
18806 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
18807 gen_store_gpr(v0_t
, ret
);
18808 tcg_temp_free(tv0
);
18811 case NM_RADDU_W_QB
:
18813 gen_helper_raddu_w_qb(v0_t
, v0_t
);
18814 gen_store_gpr(v0_t
, ret
);
18817 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
18821 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
18825 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
18828 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
18831 gen_reserved_instruction(ctx
);
18835 tcg_temp_free(v0_t
);
18839 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18840 int rt
, int rs
, int rd
)
18842 TCGv t0
= tcg_temp_new();
18843 TCGv rs_t
= tcg_temp_new();
18845 gen_load_gpr(rs_t
, rs
);
18850 tcg_gen_movi_tl(t0
, rd
>> 2);
18851 switch (extract32(ctx
->opcode
, 12, 1)) {
18854 gen_helper_shra_qb(t0
, t0
, rs_t
);
18855 gen_store_gpr(t0
, rt
);
18859 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
18860 gen_store_gpr(t0
, rt
);
18866 tcg_gen_movi_tl(t0
, rd
>> 1);
18867 gen_helper_shrl_ph(t0
, t0
, rs_t
);
18868 gen_store_gpr(t0
, rt
);
18874 target_long result
;
18875 imm
= extract32(ctx
->opcode
, 13, 8);
18876 result
= (uint32_t)imm
<< 24 |
18877 (uint32_t)imm
<< 16 |
18878 (uint32_t)imm
<< 8 |
18880 result
= (int32_t)result
;
18881 tcg_gen_movi_tl(t0
, result
);
18882 gen_store_gpr(t0
, rt
);
18886 gen_reserved_instruction(ctx
);
18890 tcg_temp_free(rs_t
);
18894 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18896 int rt
= extract32(ctx
->opcode
, 21, 5);
18897 int rs
= extract32(ctx
->opcode
, 16, 5);
18898 int rd
= extract32(ctx
->opcode
, 11, 5);
18900 switch (extract32(ctx
->opcode
, 6, 3)) {
18901 case NM_POOL32AXF_1
:
18903 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18904 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18907 case NM_POOL32AXF_2
:
18909 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
18910 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18913 case NM_POOL32AXF_4
:
18915 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
18916 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
18919 case NM_POOL32AXF_5
:
18920 switch (extract32(ctx
->opcode
, 9, 7)) {
18921 #ifndef CONFIG_USER_ONLY
18923 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
18926 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
18929 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
18932 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
18935 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
18938 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
18941 check_cp0_enabled(ctx
);
18943 TCGv t0
= tcg_temp_new();
18945 save_cpu_state(ctx
, 1);
18946 gen_helper_di(t0
, cpu_env
);
18947 gen_store_gpr(t0
, rt
);
18948 /* Stop translation as we may have switched the execution mode */
18949 ctx
->base
.is_jmp
= DISAS_STOP
;
18954 check_cp0_enabled(ctx
);
18956 TCGv t0
= tcg_temp_new();
18958 save_cpu_state(ctx
, 1);
18959 gen_helper_ei(t0
, cpu_env
);
18960 gen_store_gpr(t0
, rt
);
18961 /* Stop translation as we may have switched the execution mode */
18962 ctx
->base
.is_jmp
= DISAS_STOP
;
18967 check_cp0_enabled(ctx
);
18968 gen_load_srsgpr(rs
, rt
);
18971 check_cp0_enabled(ctx
);
18972 gen_store_srsgpr(rs
, rt
);
18975 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
18978 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
18981 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
18985 gen_reserved_instruction(ctx
);
18989 case NM_POOL32AXF_7
:
18991 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18992 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18996 gen_reserved_instruction(ctx
);
19001 /* Immediate Value Compact Branches */
19002 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19003 int rt
, int32_t imm
, int32_t offset
)
19005 TCGCond cond
= TCG_COND_ALWAYS
;
19006 TCGv t0
= tcg_temp_new();
19007 TCGv t1
= tcg_temp_new();
19009 gen_load_gpr(t0
, rt
);
19010 tcg_gen_movi_tl(t1
, imm
);
19011 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19013 /* Load needed operands and calculate btarget */
19016 if (rt
== 0 && imm
== 0) {
19017 /* Unconditional branch */
19018 } else if (rt
== 0 && imm
!= 0) {
19022 cond
= TCG_COND_EQ
;
19028 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19029 gen_reserved_instruction(ctx
);
19031 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19032 /* Unconditional branch */
19033 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19037 tcg_gen_shri_tl(t0
, t0
, imm
);
19038 tcg_gen_andi_tl(t0
, t0
, 1);
19039 tcg_gen_movi_tl(t1
, 0);
19040 if (opc
== NM_BBEQZC
) {
19041 cond
= TCG_COND_EQ
;
19043 cond
= TCG_COND_NE
;
19048 if (rt
== 0 && imm
== 0) {
19051 } else if (rt
== 0 && imm
!= 0) {
19052 /* Unconditional branch */
19054 cond
= TCG_COND_NE
;
19058 if (rt
== 0 && imm
== 0) {
19059 /* Unconditional branch */
19061 cond
= TCG_COND_GE
;
19065 cond
= TCG_COND_LT
;
19068 if (rt
== 0 && imm
== 0) {
19069 /* Unconditional branch */
19071 cond
= TCG_COND_GEU
;
19075 cond
= TCG_COND_LTU
;
19078 MIPS_INVAL("Immediate Value Compact branch");
19079 gen_reserved_instruction(ctx
);
19083 /* branch completion */
19084 clear_branch_hflags(ctx
);
19085 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19087 if (cond
== TCG_COND_ALWAYS
) {
19088 /* Unconditional compact branch */
19089 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19091 /* Conditional compact branch */
19092 TCGLabel
*fs
= gen_new_label();
19094 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19096 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19099 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19107 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19108 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19111 TCGv t0
= tcg_temp_new();
19112 TCGv t1
= tcg_temp_new();
19115 gen_load_gpr(t0
, rs
);
19119 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19122 /* calculate btarget */
19123 tcg_gen_shli_tl(t0
, t0
, 1);
19124 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19125 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19127 /* branch completion */
19128 clear_branch_hflags(ctx
);
19129 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19131 /* unconditional branch to register */
19132 tcg_gen_mov_tl(cpu_PC
, btarget
);
19133 tcg_gen_lookup_and_goto_ptr();
19139 /* nanoMIPS Branches */
19140 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19141 int rs
, int rt
, int32_t offset
)
19143 int bcond_compute
= 0;
19144 TCGv t0
= tcg_temp_new();
19145 TCGv t1
= tcg_temp_new();
19147 /* Load needed operands and calculate btarget */
19149 /* compact branch */
19152 gen_load_gpr(t0
, rs
);
19153 gen_load_gpr(t1
, rt
);
19155 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19159 if (rs
== 0 || rs
== rt
) {
19160 /* OPC_BLEZALC, OPC_BGEZALC */
19161 /* OPC_BGTZALC, OPC_BLTZALC */
19162 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19164 gen_load_gpr(t0
, rs
);
19165 gen_load_gpr(t1
, rt
);
19167 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19170 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19174 /* OPC_BEQZC, OPC_BNEZC */
19175 gen_load_gpr(t0
, rs
);
19177 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19179 /* OPC_JIC, OPC_JIALC */
19180 TCGv tbase
= tcg_temp_new();
19181 TCGv toffset
= tcg_temp_new();
19183 gen_load_gpr(tbase
, rt
);
19184 tcg_gen_movi_tl(toffset
, offset
);
19185 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19186 tcg_temp_free(tbase
);
19187 tcg_temp_free(toffset
);
19191 MIPS_INVAL("Compact branch/jump");
19192 gen_reserved_instruction(ctx
);
19196 if (bcond_compute
== 0) {
19197 /* Unconditional compact branch */
19200 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19203 MIPS_INVAL("Compact branch/jump");
19204 gen_reserved_instruction(ctx
);
19208 /* Conditional compact branch */
19209 TCGLabel
*fs
= gen_new_label();
19213 if (rs
== 0 && rt
!= 0) {
19215 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19216 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19218 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19221 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19225 if (rs
== 0 && rt
!= 0) {
19227 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19228 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19230 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19233 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19237 if (rs
== 0 && rt
!= 0) {
19239 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19240 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19242 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19245 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19249 if (rs
== 0 && rt
!= 0) {
19251 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19252 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19254 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19257 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19261 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19264 MIPS_INVAL("Compact conditional branch/jump");
19265 gen_reserved_instruction(ctx
);
19269 /* branch completion */
19270 clear_branch_hflags(ctx
);
19271 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19273 /* Generating branch here as compact branches don't have delay slot */
19274 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19277 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19286 /* nanoMIPS CP1 Branches */
19287 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19288 int32_t ft
, int32_t offset
)
19290 target_ulong btarget
;
19291 TCGv_i64 t0
= tcg_temp_new_i64();
19293 gen_load_fpr64(ctx
, t0
, ft
);
19294 tcg_gen_andi_i64(t0
, t0
, 1);
19296 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19300 tcg_gen_xori_i64(t0
, t0
, 1);
19301 ctx
->hflags
|= MIPS_HFLAG_BC
;
19304 /* t0 already set */
19305 ctx
->hflags
|= MIPS_HFLAG_BC
;
19308 MIPS_INVAL("cp1 cond branch");
19309 gen_reserved_instruction(ctx
);
19313 tcg_gen_trunc_i64_tl(bcond
, t0
);
19315 ctx
->btarget
= btarget
;
19318 tcg_temp_free_i64(t0
);
19322 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19325 t0
= tcg_temp_new();
19326 t1
= tcg_temp_new();
19328 gen_load_gpr(t0
, rs
);
19329 gen_load_gpr(t1
, rt
);
19331 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19332 /* PP.LSXS instructions require shifting */
19333 switch (extract32(ctx
->opcode
, 7, 4)) {
19339 tcg_gen_shli_tl(t0
, t0
, 1);
19347 tcg_gen_shli_tl(t0
, t0
, 2);
19351 tcg_gen_shli_tl(t0
, t0
, 3);
19355 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19357 switch (extract32(ctx
->opcode
, 7, 4)) {
19359 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19361 gen_store_gpr(t0
, rd
);
19365 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19367 gen_store_gpr(t0
, rd
);
19371 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19373 gen_store_gpr(t0
, rd
);
19376 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19378 gen_store_gpr(t0
, rd
);
19382 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19384 gen_store_gpr(t0
, rd
);
19388 gen_load_gpr(t1
, rd
);
19389 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19395 gen_load_gpr(t1
, rd
);
19396 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19402 gen_load_gpr(t1
, rd
);
19403 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19407 /*case NM_LWC1XS:*/
19409 /*case NM_LDC1XS:*/
19411 /*case NM_SWC1XS:*/
19413 /*case NM_SDC1XS:*/
19414 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19415 check_cp1_enabled(ctx
);
19416 switch (extract32(ctx
->opcode
, 7, 4)) {
19418 /*case NM_LWC1XS:*/
19419 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19422 /*case NM_LDC1XS:*/
19423 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19426 /*case NM_SWC1XS:*/
19427 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19430 /*case NM_SDC1XS:*/
19431 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19435 generate_exception_err(ctx
, EXCP_CpU
, 1);
19439 gen_reserved_instruction(ctx
);
19447 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19451 rt
= extract32(ctx
->opcode
, 21, 5);
19452 rs
= extract32(ctx
->opcode
, 16, 5);
19453 rd
= extract32(ctx
->opcode
, 11, 5);
19455 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19456 gen_reserved_instruction(ctx
);
19459 check_cp1_enabled(ctx
);
19460 switch (extract32(ctx
->opcode
, 0, 3)) {
19462 switch (extract32(ctx
->opcode
, 3, 7)) {
19464 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19467 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19470 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19473 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19476 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19479 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19482 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19485 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19488 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19491 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19494 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19497 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19500 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19503 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19506 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19509 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19512 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19515 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19518 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19521 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19524 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19527 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19530 gen_reserved_instruction(ctx
);
19535 switch (extract32(ctx
->opcode
, 3, 3)) {
19537 switch (extract32(ctx
->opcode
, 9, 1)) {
19539 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19542 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19547 switch (extract32(ctx
->opcode
, 9, 1)) {
19549 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19552 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19557 switch (extract32(ctx
->opcode
, 9, 1)) {
19559 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19562 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19567 switch (extract32(ctx
->opcode
, 9, 1)) {
19569 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19572 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19577 switch (extract32(ctx
->opcode
, 6, 8)) {
19579 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19582 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19585 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19588 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19591 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19594 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19597 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19600 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19603 switch (extract32(ctx
->opcode
, 6, 9)) {
19605 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19608 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19611 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19614 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19617 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19620 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19623 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19626 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19629 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19632 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19635 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19638 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19641 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
19644 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
19647 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
19650 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
19653 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
19656 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
19659 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
19662 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
19665 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
19668 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
19671 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
19674 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
19677 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
19680 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
19683 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
19686 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
19689 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
19692 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
19695 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
19698 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
19701 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
19704 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
19707 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
19710 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
19713 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
19716 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
19719 gen_reserved_instruction(ctx
);
19728 switch (extract32(ctx
->opcode
, 3, 3)) {
19729 case NM_CMP_CONDN_S
:
19730 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19732 case NM_CMP_CONDN_D
:
19733 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19736 gen_reserved_instruction(ctx
);
19741 gen_reserved_instruction(ctx
);
19746 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
19747 int rd
, int rs
, int rt
)
19750 TCGv t0
= tcg_temp_new();
19751 TCGv v1_t
= tcg_temp_new();
19752 TCGv v2_t
= tcg_temp_new();
19754 gen_load_gpr(v1_t
, rs
);
19755 gen_load_gpr(v2_t
, rt
);
19760 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
19764 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
19768 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
19770 case NM_CMPU_EQ_QB
:
19772 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
19774 case NM_CMPU_LT_QB
:
19776 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
19778 case NM_CMPU_LE_QB
:
19780 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
19782 case NM_CMPGU_EQ_QB
:
19784 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19785 gen_store_gpr(v1_t
, ret
);
19787 case NM_CMPGU_LT_QB
:
19789 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19790 gen_store_gpr(v1_t
, ret
);
19792 case NM_CMPGU_LE_QB
:
19794 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19795 gen_store_gpr(v1_t
, ret
);
19797 case NM_CMPGDU_EQ_QB
:
19799 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19800 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19801 gen_store_gpr(v1_t
, ret
);
19803 case NM_CMPGDU_LT_QB
:
19805 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19806 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19807 gen_store_gpr(v1_t
, ret
);
19809 case NM_CMPGDU_LE_QB
:
19811 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19812 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19813 gen_store_gpr(v1_t
, ret
);
19817 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
19818 gen_store_gpr(v1_t
, ret
);
19822 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19823 gen_store_gpr(v1_t
, ret
);
19827 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19828 gen_store_gpr(v1_t
, ret
);
19832 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19833 gen_store_gpr(v1_t
, ret
);
19837 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19838 gen_store_gpr(v1_t
, ret
);
19842 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
19843 gen_store_gpr(v1_t
, ret
);
19847 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
19848 gen_store_gpr(v1_t
, ret
);
19852 switch (extract32(ctx
->opcode
, 10, 1)) {
19855 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19856 gen_store_gpr(v1_t
, ret
);
19860 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19861 gen_store_gpr(v1_t
, ret
);
19865 case NM_ADDQH_R_PH
:
19867 switch (extract32(ctx
->opcode
, 10, 1)) {
19870 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
19871 gen_store_gpr(v1_t
, ret
);
19875 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
19876 gen_store_gpr(v1_t
, ret
);
19882 switch (extract32(ctx
->opcode
, 10, 1)) {
19885 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
19886 gen_store_gpr(v1_t
, ret
);
19890 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
19891 gen_store_gpr(v1_t
, ret
);
19897 switch (extract32(ctx
->opcode
, 10, 1)) {
19900 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19901 gen_store_gpr(v1_t
, ret
);
19905 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19906 gen_store_gpr(v1_t
, ret
);
19912 switch (extract32(ctx
->opcode
, 10, 1)) {
19915 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19916 gen_store_gpr(v1_t
, ret
);
19920 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19921 gen_store_gpr(v1_t
, ret
);
19925 case NM_ADDUH_R_QB
:
19927 switch (extract32(ctx
->opcode
, 10, 1)) {
19930 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
19931 gen_store_gpr(v1_t
, ret
);
19935 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
19936 gen_store_gpr(v1_t
, ret
);
19940 case NM_SHRAV_R_PH
:
19942 switch (extract32(ctx
->opcode
, 10, 1)) {
19945 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
19946 gen_store_gpr(v1_t
, ret
);
19950 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
19951 gen_store_gpr(v1_t
, ret
);
19955 case NM_SHRAV_R_QB
:
19957 switch (extract32(ctx
->opcode
, 10, 1)) {
19960 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
19961 gen_store_gpr(v1_t
, ret
);
19965 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
19966 gen_store_gpr(v1_t
, ret
);
19972 switch (extract32(ctx
->opcode
, 10, 1)) {
19975 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19976 gen_store_gpr(v1_t
, ret
);
19980 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19981 gen_store_gpr(v1_t
, ret
);
19985 case NM_SUBQH_R_PH
:
19987 switch (extract32(ctx
->opcode
, 10, 1)) {
19990 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
19991 gen_store_gpr(v1_t
, ret
);
19995 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
19996 gen_store_gpr(v1_t
, ret
);
20002 switch (extract32(ctx
->opcode
, 10, 1)) {
20005 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20006 gen_store_gpr(v1_t
, ret
);
20010 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20011 gen_store_gpr(v1_t
, ret
);
20017 switch (extract32(ctx
->opcode
, 10, 1)) {
20020 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20021 gen_store_gpr(v1_t
, ret
);
20025 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20026 gen_store_gpr(v1_t
, ret
);
20032 switch (extract32(ctx
->opcode
, 10, 1)) {
20035 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20036 gen_store_gpr(v1_t
, ret
);
20040 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20041 gen_store_gpr(v1_t
, ret
);
20045 case NM_SUBUH_R_QB
:
20047 switch (extract32(ctx
->opcode
, 10, 1)) {
20050 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20051 gen_store_gpr(v1_t
, ret
);
20055 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20056 gen_store_gpr(v1_t
, ret
);
20060 case NM_SHLLV_S_PH
:
20062 switch (extract32(ctx
->opcode
, 10, 1)) {
20065 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20066 gen_store_gpr(v1_t
, ret
);
20070 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20071 gen_store_gpr(v1_t
, ret
);
20075 case NM_PRECR_SRA_R_PH_W
:
20077 switch (extract32(ctx
->opcode
, 10, 1)) {
20079 /* PRECR_SRA_PH_W */
20081 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20082 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20084 gen_store_gpr(v1_t
, rt
);
20085 tcg_temp_free_i32(sa_t
);
20089 /* PRECR_SRA_R_PH_W */
20091 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20092 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20094 gen_store_gpr(v1_t
, rt
);
20095 tcg_temp_free_i32(sa_t
);
20100 case NM_MULEU_S_PH_QBL
:
20102 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20103 gen_store_gpr(v1_t
, ret
);
20105 case NM_MULEU_S_PH_QBR
:
20107 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20108 gen_store_gpr(v1_t
, ret
);
20110 case NM_MULQ_RS_PH
:
20112 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20113 gen_store_gpr(v1_t
, ret
);
20117 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20118 gen_store_gpr(v1_t
, ret
);
20122 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20123 gen_store_gpr(v1_t
, ret
);
20127 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20128 gen_store_gpr(v1_t
, ret
);
20132 gen_load_gpr(t0
, rs
);
20134 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20136 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20140 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20141 gen_store_gpr(v1_t
, ret
);
20145 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20146 gen_store_gpr(v1_t
, ret
);
20150 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20151 gen_store_gpr(v1_t
, ret
);
20155 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20156 gen_store_gpr(v1_t
, ret
);
20160 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20161 gen_store_gpr(v1_t
, ret
);
20165 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20166 gen_store_gpr(v1_t
, ret
);
20171 TCGv tv0
= tcg_temp_new();
20172 TCGv tv1
= tcg_temp_new();
20173 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20175 tcg_gen_movi_tl(tv0
, rd
>> 3);
20176 tcg_gen_movi_tl(tv1
, imm
);
20177 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20178 tcg_temp_free(tv1
);
20179 tcg_temp_free(tv0
);
20182 case NM_MULEQ_S_W_PHL
:
20184 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20185 gen_store_gpr(v1_t
, ret
);
20187 case NM_MULEQ_S_W_PHR
:
20189 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20190 gen_store_gpr(v1_t
, ret
);
20194 switch (extract32(ctx
->opcode
, 10, 1)) {
20197 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20198 gen_store_gpr(v1_t
, ret
);
20202 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20203 gen_store_gpr(v1_t
, ret
);
20207 case NM_PRECR_QB_PH
:
20209 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20210 gen_store_gpr(v1_t
, ret
);
20212 case NM_PRECRQ_QB_PH
:
20214 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20215 gen_store_gpr(v1_t
, ret
);
20217 case NM_PRECRQ_PH_W
:
20219 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20220 gen_store_gpr(v1_t
, ret
);
20222 case NM_PRECRQ_RS_PH_W
:
20224 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20225 gen_store_gpr(v1_t
, ret
);
20227 case NM_PRECRQU_S_QB_PH
:
20229 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20230 gen_store_gpr(v1_t
, ret
);
20234 tcg_gen_movi_tl(t0
, rd
);
20235 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20236 gen_store_gpr(v1_t
, rt
);
20240 tcg_gen_movi_tl(t0
, rd
>> 1);
20241 switch (extract32(ctx
->opcode
, 10, 1)) {
20244 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20245 gen_store_gpr(v1_t
, rt
);
20249 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20250 gen_store_gpr(v1_t
, rt
);
20256 tcg_gen_movi_tl(t0
, rd
>> 1);
20257 switch (extract32(ctx
->opcode
, 10, 2)) {
20260 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20261 gen_store_gpr(v1_t
, rt
);
20265 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20266 gen_store_gpr(v1_t
, rt
);
20269 gen_reserved_instruction(ctx
);
20275 tcg_gen_movi_tl(t0
, rd
);
20276 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20277 gen_store_gpr(v1_t
, rt
);
20283 imm
= sextract32(ctx
->opcode
, 11, 11);
20284 imm
= (int16_t)(imm
<< 6) >> 6;
20286 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20291 gen_reserved_instruction(ctx
);
20295 tcg_temp_free(v2_t
);
20296 tcg_temp_free(v1_t
);
20300 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20308 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20309 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20311 rt
= extract32(ctx
->opcode
, 21, 5);
20312 rs
= extract32(ctx
->opcode
, 16, 5);
20313 rd
= extract32(ctx
->opcode
, 11, 5);
20315 op
= extract32(ctx
->opcode
, 26, 6);
20320 switch (extract32(ctx
->opcode
, 19, 2)) {
20323 gen_reserved_instruction(ctx
);
20326 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20327 generate_exception_end(ctx
, EXCP_SYSCALL
);
20329 gen_reserved_instruction(ctx
);
20333 generate_exception_end(ctx
, EXCP_BREAK
);
20336 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20337 gen_helper_do_semihosting(cpu_env
);
20339 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20340 gen_reserved_instruction(ctx
);
20342 generate_exception_end(ctx
, EXCP_DBp
);
20349 imm
= extract32(ctx
->opcode
, 0, 16);
20351 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20353 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20355 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20360 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20361 extract32(ctx
->opcode
, 1, 20) << 1;
20362 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20363 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20367 switch (ctx
->opcode
& 0x07) {
20369 gen_pool32a0_nanomips_insn(env
, ctx
);
20373 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20374 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20378 switch (extract32(ctx
->opcode
, 3, 3)) {
20380 gen_p_lsx(ctx
, rd
, rs
, rt
);
20384 * In nanoMIPS, the shift field directly encodes the shift
20385 * amount, meaning that the supported shift values are in
20386 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20388 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20391 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20394 gen_pool32axf_nanomips_insn(env
, ctx
);
20397 gen_reserved_instruction(ctx
);
20402 gen_reserved_instruction(ctx
);
20407 switch (ctx
->opcode
& 0x03) {
20410 offset
= extract32(ctx
->opcode
, 0, 21);
20411 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20415 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20418 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20421 gen_reserved_instruction(ctx
);
20427 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20428 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20429 switch (extract32(ctx
->opcode
, 16, 5)) {
20433 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20439 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20440 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20446 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20452 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20455 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20462 t0
= tcg_temp_new();
20464 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20467 tcg_gen_movi_tl(t0
, addr
);
20468 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20476 t0
= tcg_temp_new();
20477 t1
= tcg_temp_new();
20479 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20482 tcg_gen_movi_tl(t0
, addr
);
20483 gen_load_gpr(t1
, rt
);
20485 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20492 gen_reserved_instruction(ctx
);
20498 switch (extract32(ctx
->opcode
, 12, 4)) {
20500 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20503 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20506 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20509 switch (extract32(ctx
->opcode
, 20, 1)) {
20511 switch (ctx
->opcode
& 3) {
20513 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20514 extract32(ctx
->opcode
, 2, 1),
20515 extract32(ctx
->opcode
, 3, 9) << 3);
20518 case NM_RESTORE_JRC
:
20519 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20520 extract32(ctx
->opcode
, 2, 1),
20521 extract32(ctx
->opcode
, 3, 9) << 3);
20522 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20523 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20527 gen_reserved_instruction(ctx
);
20532 gen_reserved_instruction(ctx
);
20537 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20540 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20544 TCGv t0
= tcg_temp_new();
20546 imm
= extract32(ctx
->opcode
, 0, 12);
20547 gen_load_gpr(t0
, rs
);
20548 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20549 gen_store_gpr(t0
, rt
);
20555 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20556 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20560 int shift
= extract32(ctx
->opcode
, 0, 5);
20561 switch (extract32(ctx
->opcode
, 5, 4)) {
20563 if (rt
== 0 && shift
== 0) {
20565 } else if (rt
== 0 && shift
== 3) {
20566 /* EHB - treat as NOP */
20567 } else if (rt
== 0 && shift
== 5) {
20568 /* PAUSE - treat as NOP */
20569 } else if (rt
== 0 && shift
== 6) {
20571 gen_sync(extract32(ctx
->opcode
, 16, 5));
20574 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20575 extract32(ctx
->opcode
, 0, 5));
20579 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20580 extract32(ctx
->opcode
, 0, 5));
20583 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20584 extract32(ctx
->opcode
, 0, 5));
20587 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20588 extract32(ctx
->opcode
, 0, 5));
20596 TCGv t0
= tcg_temp_new();
20597 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20598 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20600 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20602 gen_load_gpr(t0
, rs
);
20603 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20606 tcg_temp_free_i32(shift
);
20607 tcg_temp_free_i32(shiftx
);
20608 tcg_temp_free_i32(stripe
);
20612 switch (((ctx
->opcode
>> 10) & 2) |
20613 (extract32(ctx
->opcode
, 5, 1))) {
20616 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20617 extract32(ctx
->opcode
, 6, 5));
20620 gen_reserved_instruction(ctx
);
20625 switch (((ctx
->opcode
>> 10) & 2) |
20626 (extract32(ctx
->opcode
, 5, 1))) {
20629 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20630 extract32(ctx
->opcode
, 6, 5));
20633 gen_reserved_instruction(ctx
);
20638 gen_reserved_instruction(ctx
);
20643 gen_pool32f_nanomips_insn(ctx
);
20648 switch (extract32(ctx
->opcode
, 1, 1)) {
20651 tcg_gen_movi_tl(cpu_gpr
[rt
],
20652 sextract32(ctx
->opcode
, 0, 1) << 31 |
20653 extract32(ctx
->opcode
, 2, 10) << 21 |
20654 extract32(ctx
->opcode
, 12, 9) << 12);
20659 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
20660 extract32(ctx
->opcode
, 2, 10) << 21 |
20661 extract32(ctx
->opcode
, 12, 9) << 12;
20663 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20664 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20671 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
20673 switch (extract32(ctx
->opcode
, 18, 3)) {
20675 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
20678 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
20681 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
20685 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
20690 switch (ctx
->opcode
& 1) {
20692 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
20695 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
20701 switch (ctx
->opcode
& 1) {
20703 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
20706 gen_reserved_instruction(ctx
);
20712 switch (ctx
->opcode
& 0x3) {
20714 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
20717 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
20720 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
20723 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
20728 gen_reserved_instruction(ctx
);
20735 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
20737 switch (extract32(ctx
->opcode
, 12, 4)) {
20742 * Break the TB to be able to sync copied instructions
20745 ctx
->base
.is_jmp
= DISAS_STOP
;
20748 /* Treat as NOP. */
20752 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
20755 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
20758 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
20761 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
20764 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
20767 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
20770 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
20773 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
20776 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
20779 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
20782 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
20785 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
20788 gen_reserved_instruction(ctx
);
20795 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
20796 extract32(ctx
->opcode
, 0, 8);
20798 switch (extract32(ctx
->opcode
, 8, 3)) {
20800 switch (extract32(ctx
->opcode
, 11, 4)) {
20802 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
20805 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
20808 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
20811 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
20814 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
20817 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
20820 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
20823 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
20826 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
20829 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
20832 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
20835 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
20841 * Break the TB to be able to sync copied instructions
20844 ctx
->base
.is_jmp
= DISAS_STOP
;
20847 /* Treat as NOP. */
20851 gen_reserved_instruction(ctx
);
20856 switch (extract32(ctx
->opcode
, 11, 4)) {
20861 TCGv t0
= tcg_temp_new();
20862 TCGv t1
= tcg_temp_new();
20864 gen_base_offset_addr(ctx
, t0
, rs
, s
);
20866 switch (extract32(ctx
->opcode
, 11, 4)) {
20868 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
20870 gen_store_gpr(t0
, rt
);
20873 gen_load_gpr(t1
, rt
);
20874 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
20883 switch (ctx
->opcode
& 0x03) {
20885 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
20889 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20894 switch (ctx
->opcode
& 0x03) {
20896 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
20900 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
20906 check_cp0_enabled(ctx
);
20907 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
20908 gen_cache_operation(ctx
, rt
, rs
, s
);
20914 switch (extract32(ctx
->opcode
, 11, 4)) {
20917 check_cp0_enabled(ctx
);
20918 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
20922 check_cp0_enabled(ctx
);
20923 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
20927 check_cp0_enabled(ctx
);
20928 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
20932 /* case NM_SYNCIE */
20934 check_cp0_enabled(ctx
);
20936 * Break the TB to be able to sync copied instructions
20939 ctx
->base
.is_jmp
= DISAS_STOP
;
20941 /* case NM_PREFE */
20943 check_cp0_enabled(ctx
);
20944 /* Treat as NOP. */
20949 check_cp0_enabled(ctx
);
20950 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
20954 check_cp0_enabled(ctx
);
20955 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
20959 check_cp0_enabled(ctx
);
20960 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
20964 check_cp0_enabled(ctx
);
20965 check_nms_dl_il_sl_tl_l2c(ctx
);
20966 gen_cache_operation(ctx
, rt
, rs
, s
);
20970 check_cp0_enabled(ctx
);
20971 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
20975 check_cp0_enabled(ctx
);
20976 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
20979 switch (extract32(ctx
->opcode
, 2, 2)) {
20983 check_cp0_enabled(ctx
);
20984 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
20989 check_cp0_enabled(ctx
);
20990 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20993 gen_reserved_instruction(ctx
);
20998 switch (extract32(ctx
->opcode
, 2, 2)) {
21002 check_cp0_enabled(ctx
);
21003 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21008 check_cp0_enabled(ctx
);
21009 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21013 gen_reserved_instruction(ctx
);
21023 int count
= extract32(ctx
->opcode
, 12, 3);
21026 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21027 extract32(ctx
->opcode
, 0, 8);
21028 TCGv va
= tcg_temp_new();
21029 TCGv t1
= tcg_temp_new();
21030 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21031 NM_P_LS_UAWM
? MO_UNALN
: 0;
21033 count
= (count
== 0) ? 8 : count
;
21034 while (counter
!= count
) {
21035 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21036 int this_offset
= offset
+ (counter
<< 2);
21038 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21040 switch (extract32(ctx
->opcode
, 11, 1)) {
21042 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21044 gen_store_gpr(t1
, this_rt
);
21045 if ((this_rt
== rs
) &&
21046 (counter
!= (count
- 1))) {
21047 /* UNPREDICTABLE */
21051 this_rt
= (rt
== 0) ? 0 : this_rt
;
21052 gen_load_gpr(t1
, this_rt
);
21053 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21064 gen_reserved_instruction(ctx
);
21072 TCGv t0
= tcg_temp_new();
21073 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21074 extract32(ctx
->opcode
, 1, 20) << 1;
21075 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21076 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21077 extract32(ctx
->opcode
, 21, 3));
21078 gen_load_gpr(t0
, rt
);
21079 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21080 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21086 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21087 extract32(ctx
->opcode
, 1, 24) << 1;
21089 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21091 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21094 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21099 switch (extract32(ctx
->opcode
, 12, 4)) {
21102 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21105 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21108 gen_reserved_instruction(ctx
);
21114 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21115 extract32(ctx
->opcode
, 1, 13) << 1;
21116 switch (extract32(ctx
->opcode
, 14, 2)) {
21119 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21122 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21123 extract32(ctx
->opcode
, 1, 13) << 1;
21124 check_cp1_enabled(ctx
);
21125 switch (extract32(ctx
->opcode
, 16, 5)) {
21127 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21130 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21135 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21136 extract32(ctx
->opcode
, 0, 1) << 13;
21138 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21143 gen_reserved_instruction(ctx
);
21149 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21151 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21155 if (rs
== rt
|| rt
== 0) {
21156 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21157 } else if (rs
== 0) {
21158 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21160 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21168 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21169 extract32(ctx
->opcode
, 1, 13) << 1;
21170 switch (extract32(ctx
->opcode
, 14, 2)) {
21173 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21176 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21178 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21180 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21184 if (rs
== 0 || rs
== rt
) {
21186 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21188 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21192 gen_reserved_instruction(ctx
);
21199 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21200 extract32(ctx
->opcode
, 1, 10) << 1;
21201 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21203 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21208 gen_reserved_instruction(ctx
);
21214 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21217 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21218 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21219 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21223 /* make sure instructions are on a halfword boundary */
21224 if (ctx
->base
.pc_next
& 0x1) {
21225 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21226 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21227 tcg_temp_free(tmp
);
21228 generate_exception_end(ctx
, EXCP_AdEL
);
21232 op
= extract32(ctx
->opcode
, 10, 6);
21235 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21238 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21239 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21242 switch (extract32(ctx
->opcode
, 3, 2)) {
21243 case NM_P16_SYSCALL
:
21244 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21245 generate_exception_end(ctx
, EXCP_SYSCALL
);
21247 gen_reserved_instruction(ctx
);
21251 generate_exception_end(ctx
, EXCP_BREAK
);
21254 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21255 gen_helper_do_semihosting(cpu_env
);
21257 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21258 gen_reserved_instruction(ctx
);
21260 generate_exception_end(ctx
, EXCP_DBp
);
21265 gen_reserved_instruction(ctx
);
21272 int shift
= extract32(ctx
->opcode
, 0, 3);
21274 shift
= (shift
== 0) ? 8 : shift
;
21276 switch (extract32(ctx
->opcode
, 3, 1)) {
21284 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21288 switch (ctx
->opcode
& 1) {
21290 gen_pool16c_nanomips_insn(ctx
);
21293 gen_ldxs(ctx
, rt
, rs
, rd
);
21298 switch (extract32(ctx
->opcode
, 6, 1)) {
21300 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21301 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21304 gen_reserved_instruction(ctx
);
21309 switch (extract32(ctx
->opcode
, 3, 1)) {
21311 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21312 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21314 case NM_P_ADDIURS5
:
21315 rt
= extract32(ctx
->opcode
, 5, 5);
21317 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21318 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21319 (extract32(ctx
->opcode
, 0, 3));
21320 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21326 switch (ctx
->opcode
& 0x1) {
21328 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21331 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21336 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21337 extract32(ctx
->opcode
, 5, 3);
21338 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21339 extract32(ctx
->opcode
, 0, 3);
21340 rt
= decode_gpr_gpr4(rt
);
21341 rs
= decode_gpr_gpr4(rs
);
21342 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21343 (extract32(ctx
->opcode
, 3, 1))) {
21346 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21350 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21353 gen_reserved_instruction(ctx
);
21359 int imm
= extract32(ctx
->opcode
, 0, 7);
21360 imm
= (imm
== 0x7f ? -1 : imm
);
21362 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21368 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21369 u
= (u
== 12) ? 0xff :
21370 (u
== 13) ? 0xffff : u
;
21371 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21375 offset
= extract32(ctx
->opcode
, 0, 2);
21376 switch (extract32(ctx
->opcode
, 2, 2)) {
21378 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21381 rt
= decode_gpr_gpr3_src_store(
21382 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21383 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21386 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21389 gen_reserved_instruction(ctx
);
21394 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21395 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21397 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21400 rt
= decode_gpr_gpr3_src_store(
21401 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21402 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21405 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21408 gen_reserved_instruction(ctx
);
21413 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21414 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21417 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21418 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21419 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21423 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21424 extract32(ctx
->opcode
, 5, 3);
21425 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21426 extract32(ctx
->opcode
, 0, 3);
21427 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21428 (extract32(ctx
->opcode
, 8, 1) << 2);
21429 rt
= decode_gpr_gpr4(rt
);
21430 rs
= decode_gpr_gpr4(rs
);
21431 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21435 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21436 extract32(ctx
->opcode
, 5, 3);
21437 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21438 extract32(ctx
->opcode
, 0, 3);
21439 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21440 (extract32(ctx
->opcode
, 8, 1) << 2);
21441 rt
= decode_gpr_gpr4_zero(rt
);
21442 rs
= decode_gpr_gpr4(rs
);
21443 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21446 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21447 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21450 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21451 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21452 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21455 rt
= decode_gpr_gpr3_src_store(
21456 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21457 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21458 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21459 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21462 rt
= decode_gpr_gpr3_src_store(
21463 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21464 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21465 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21468 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21469 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21470 (extract32(ctx
->opcode
, 1, 9) << 1));
21473 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21474 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21475 (extract32(ctx
->opcode
, 1, 9) << 1));
21478 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21479 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21480 (extract32(ctx
->opcode
, 1, 6) << 1));
21483 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21484 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21485 (extract32(ctx
->opcode
, 1, 6) << 1));
21488 switch (ctx
->opcode
& 0xf) {
21491 switch (extract32(ctx
->opcode
, 4, 1)) {
21493 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21494 extract32(ctx
->opcode
, 5, 5), 0, 0);
21497 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21498 extract32(ctx
->opcode
, 5, 5), 31, 0);
21505 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21506 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21507 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21508 extract32(ctx
->opcode
, 0, 4) << 1);
21515 int count
= extract32(ctx
->opcode
, 0, 4);
21516 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21518 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21519 switch (extract32(ctx
->opcode
, 8, 1)) {
21521 gen_save(ctx
, rt
, count
, 0, u
);
21523 case NM_RESTORE_JRC16
:
21524 gen_restore(ctx
, rt
, count
, 0, u
);
21525 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21534 static const int gpr2reg1
[] = {4, 5, 6, 7};
21535 static const int gpr2reg2
[] = {5, 6, 7, 8};
21537 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21538 extract32(ctx
->opcode
, 8, 1);
21539 int r1
= gpr2reg1
[rd2
];
21540 int r2
= gpr2reg2
[rd2
];
21541 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21542 extract32(ctx
->opcode
, 0, 3);
21543 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21544 extract32(ctx
->opcode
, 5, 3);
21545 TCGv t0
= tcg_temp_new();
21546 TCGv t1
= tcg_temp_new();
21547 if (op
== NM_MOVEP
) {
21550 rs
= decode_gpr_gpr4_zero(r3
);
21551 rt
= decode_gpr_gpr4_zero(r4
);
21553 rd
= decode_gpr_gpr4(r3
);
21554 re
= decode_gpr_gpr4(r4
);
21558 gen_load_gpr(t0
, rs
);
21559 gen_load_gpr(t1
, rt
);
21560 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21561 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21567 return decode_nanomips_32_48_opc(env
, ctx
);
21574 /* MIPSDSP functions. */
21575 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21576 int rd
, int base
, int offset
)
21581 t0
= tcg_temp_new();
21584 gen_load_gpr(t0
, offset
);
21585 } else if (offset
== 0) {
21586 gen_load_gpr(t0
, base
);
21588 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21593 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21594 gen_store_gpr(t0
, rd
);
21597 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21598 gen_store_gpr(t0
, rd
);
21601 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21602 gen_store_gpr(t0
, rd
);
21604 #if defined(TARGET_MIPS64)
21606 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21607 gen_store_gpr(t0
, rd
);
21614 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21615 int ret
, int v1
, int v2
)
21621 /* Treat as NOP. */
21625 v1_t
= tcg_temp_new();
21626 v2_t
= tcg_temp_new();
21628 gen_load_gpr(v1_t
, v1
);
21629 gen_load_gpr(v2_t
, v2
);
21632 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21633 case OPC_MULT_G_2E
:
21637 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21639 case OPC_ADDUH_R_QB
:
21640 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21643 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21645 case OPC_ADDQH_R_PH
:
21646 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21649 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21651 case OPC_ADDQH_R_W
:
21652 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21655 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21657 case OPC_SUBUH_R_QB
:
21658 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21661 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21663 case OPC_SUBQH_R_PH
:
21664 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21667 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21669 case OPC_SUBQH_R_W
:
21670 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21674 case OPC_ABSQ_S_PH_DSP
:
21676 case OPC_ABSQ_S_QB
:
21678 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
21680 case OPC_ABSQ_S_PH
:
21682 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
21686 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
21688 case OPC_PRECEQ_W_PHL
:
21690 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
21691 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21693 case OPC_PRECEQ_W_PHR
:
21695 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
21696 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
21697 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21699 case OPC_PRECEQU_PH_QBL
:
21701 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
21703 case OPC_PRECEQU_PH_QBR
:
21705 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
21707 case OPC_PRECEQU_PH_QBLA
:
21709 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
21711 case OPC_PRECEQU_PH_QBRA
:
21713 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
21715 case OPC_PRECEU_PH_QBL
:
21717 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
21719 case OPC_PRECEU_PH_QBR
:
21721 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
21723 case OPC_PRECEU_PH_QBLA
:
21725 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
21727 case OPC_PRECEU_PH_QBRA
:
21729 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
21733 case OPC_ADDU_QB_DSP
:
21737 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21739 case OPC_ADDQ_S_PH
:
21741 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21745 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21749 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21751 case OPC_ADDU_S_QB
:
21753 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21757 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21759 case OPC_ADDU_S_PH
:
21761 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21765 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21767 case OPC_SUBQ_S_PH
:
21769 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21773 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21777 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21779 case OPC_SUBU_S_QB
:
21781 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21785 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21787 case OPC_SUBU_S_PH
:
21789 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21793 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21797 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21801 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
21803 case OPC_RADDU_W_QB
:
21805 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
21809 case OPC_CMPU_EQ_QB_DSP
:
21811 case OPC_PRECR_QB_PH
:
21813 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21815 case OPC_PRECRQ_QB_PH
:
21817 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21819 case OPC_PRECR_SRA_PH_W
:
21822 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21823 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21825 tcg_temp_free_i32(sa_t
);
21828 case OPC_PRECR_SRA_R_PH_W
:
21831 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21832 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21834 tcg_temp_free_i32(sa_t
);
21837 case OPC_PRECRQ_PH_W
:
21839 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21841 case OPC_PRECRQ_RS_PH_W
:
21843 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21845 case OPC_PRECRQU_S_QB_PH
:
21847 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21851 #ifdef TARGET_MIPS64
21852 case OPC_ABSQ_S_QH_DSP
:
21854 case OPC_PRECEQ_L_PWL
:
21856 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
21858 case OPC_PRECEQ_L_PWR
:
21860 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
21862 case OPC_PRECEQ_PW_QHL
:
21864 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
21866 case OPC_PRECEQ_PW_QHR
:
21868 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
21870 case OPC_PRECEQ_PW_QHLA
:
21872 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
21874 case OPC_PRECEQ_PW_QHRA
:
21876 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
21878 case OPC_PRECEQU_QH_OBL
:
21880 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
21882 case OPC_PRECEQU_QH_OBR
:
21884 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
21886 case OPC_PRECEQU_QH_OBLA
:
21888 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
21890 case OPC_PRECEQU_QH_OBRA
:
21892 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
21894 case OPC_PRECEU_QH_OBL
:
21896 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
21898 case OPC_PRECEU_QH_OBR
:
21900 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
21902 case OPC_PRECEU_QH_OBLA
:
21904 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
21906 case OPC_PRECEU_QH_OBRA
:
21908 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
21910 case OPC_ABSQ_S_OB
:
21912 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
21914 case OPC_ABSQ_S_PW
:
21916 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
21918 case OPC_ABSQ_S_QH
:
21920 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
21924 case OPC_ADDU_OB_DSP
:
21926 case OPC_RADDU_L_OB
:
21928 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
21932 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21934 case OPC_SUBQ_S_PW
:
21936 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21940 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21942 case OPC_SUBQ_S_QH
:
21944 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21948 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21950 case OPC_SUBU_S_OB
:
21952 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21956 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21958 case OPC_SUBU_S_QH
:
21960 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21964 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21966 case OPC_SUBUH_R_OB
:
21968 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21972 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21974 case OPC_ADDQ_S_PW
:
21976 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21980 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21982 case OPC_ADDQ_S_QH
:
21984 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21988 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21990 case OPC_ADDU_S_OB
:
21992 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21996 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21998 case OPC_ADDU_S_QH
:
22000 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22004 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22006 case OPC_ADDUH_R_OB
:
22008 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22012 case OPC_CMPU_EQ_OB_DSP
:
22014 case OPC_PRECR_OB_QH
:
22016 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22018 case OPC_PRECR_SRA_QH_PW
:
22021 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22022 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22023 tcg_temp_free_i32(ret_t
);
22026 case OPC_PRECR_SRA_R_QH_PW
:
22029 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22030 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22031 tcg_temp_free_i32(sa_v
);
22034 case OPC_PRECRQ_OB_QH
:
22036 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22038 case OPC_PRECRQ_PW_L
:
22040 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22042 case OPC_PRECRQ_QH_PW
:
22044 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22046 case OPC_PRECRQ_RS_QH_PW
:
22048 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22050 case OPC_PRECRQU_S_OB_QH
:
22052 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22059 tcg_temp_free(v1_t
);
22060 tcg_temp_free(v2_t
);
22063 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22064 int ret
, int v1
, int v2
)
22072 /* Treat as NOP. */
22076 t0
= tcg_temp_new();
22077 v1_t
= tcg_temp_new();
22078 v2_t
= tcg_temp_new();
22080 tcg_gen_movi_tl(t0
, v1
);
22081 gen_load_gpr(v1_t
, v1
);
22082 gen_load_gpr(v2_t
, v2
);
22085 case OPC_SHLL_QB_DSP
:
22087 op2
= MASK_SHLL_QB(ctx
->opcode
);
22091 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22095 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22099 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22103 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22105 case OPC_SHLL_S_PH
:
22107 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22109 case OPC_SHLLV_S_PH
:
22111 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22115 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22117 case OPC_SHLLV_S_W
:
22119 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22123 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22127 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22131 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22135 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22139 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22141 case OPC_SHRA_R_QB
:
22143 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22147 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22149 case OPC_SHRAV_R_QB
:
22151 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22155 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22157 case OPC_SHRA_R_PH
:
22159 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22163 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22165 case OPC_SHRAV_R_PH
:
22167 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22171 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22173 case OPC_SHRAV_R_W
:
22175 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22177 default: /* Invalid */
22178 MIPS_INVAL("MASK SHLL.QB");
22179 gen_reserved_instruction(ctx
);
22184 #ifdef TARGET_MIPS64
22185 case OPC_SHLL_OB_DSP
:
22186 op2
= MASK_SHLL_OB(ctx
->opcode
);
22190 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22194 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22196 case OPC_SHLL_S_PW
:
22198 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22200 case OPC_SHLLV_S_PW
:
22202 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22206 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22210 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22214 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22218 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22220 case OPC_SHLL_S_QH
:
22222 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22224 case OPC_SHLLV_S_QH
:
22226 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22230 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22234 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22236 case OPC_SHRA_R_OB
:
22238 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22240 case OPC_SHRAV_R_OB
:
22242 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22246 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22250 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22252 case OPC_SHRA_R_PW
:
22254 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22256 case OPC_SHRAV_R_PW
:
22258 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22262 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22266 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22268 case OPC_SHRA_R_QH
:
22270 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22272 case OPC_SHRAV_R_QH
:
22274 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22278 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22282 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22286 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22290 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22292 default: /* Invalid */
22293 MIPS_INVAL("MASK SHLL.OB");
22294 gen_reserved_instruction(ctx
);
22302 tcg_temp_free(v1_t
);
22303 tcg_temp_free(v2_t
);
22306 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22307 int ret
, int v1
, int v2
, int check_ret
)
22313 if ((ret
== 0) && (check_ret
== 1)) {
22314 /* Treat as NOP. */
22318 t0
= tcg_temp_new_i32();
22319 v1_t
= tcg_temp_new();
22320 v2_t
= tcg_temp_new();
22322 tcg_gen_movi_i32(t0
, ret
);
22323 gen_load_gpr(v1_t
, v1
);
22324 gen_load_gpr(v2_t
, v2
);
22328 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22329 * the same mask and op1.
22331 case OPC_MULT_G_2E
:
22335 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22338 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22341 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22343 case OPC_MULQ_RS_W
:
22344 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22348 case OPC_DPA_W_PH_DSP
:
22350 case OPC_DPAU_H_QBL
:
22352 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22354 case OPC_DPAU_H_QBR
:
22356 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22358 case OPC_DPSU_H_QBL
:
22360 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22362 case OPC_DPSU_H_QBR
:
22364 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22368 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22370 case OPC_DPAX_W_PH
:
22372 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22374 case OPC_DPAQ_S_W_PH
:
22376 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22378 case OPC_DPAQX_S_W_PH
:
22380 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22382 case OPC_DPAQX_SA_W_PH
:
22384 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22388 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22390 case OPC_DPSX_W_PH
:
22392 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22394 case OPC_DPSQ_S_W_PH
:
22396 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22398 case OPC_DPSQX_S_W_PH
:
22400 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22402 case OPC_DPSQX_SA_W_PH
:
22404 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22406 case OPC_MULSAQ_S_W_PH
:
22408 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22410 case OPC_DPAQ_SA_L_W
:
22412 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22414 case OPC_DPSQ_SA_L_W
:
22416 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22418 case OPC_MAQ_S_W_PHL
:
22420 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22422 case OPC_MAQ_S_W_PHR
:
22424 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22426 case OPC_MAQ_SA_W_PHL
:
22428 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22430 case OPC_MAQ_SA_W_PHR
:
22432 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22434 case OPC_MULSA_W_PH
:
22436 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22440 #ifdef TARGET_MIPS64
22441 case OPC_DPAQ_W_QH_DSP
:
22443 int ac
= ret
& 0x03;
22444 tcg_gen_movi_i32(t0
, ac
);
22449 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22453 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22457 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22461 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22465 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22467 case OPC_DPAQ_S_W_QH
:
22469 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22471 case OPC_DPAQ_SA_L_PW
:
22473 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22475 case OPC_DPAU_H_OBL
:
22477 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22479 case OPC_DPAU_H_OBR
:
22481 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22485 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22487 case OPC_DPSQ_S_W_QH
:
22489 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22491 case OPC_DPSQ_SA_L_PW
:
22493 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22495 case OPC_DPSU_H_OBL
:
22497 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22499 case OPC_DPSU_H_OBR
:
22501 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22503 case OPC_MAQ_S_L_PWL
:
22505 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22507 case OPC_MAQ_S_L_PWR
:
22509 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22511 case OPC_MAQ_S_W_QHLL
:
22513 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22515 case OPC_MAQ_SA_W_QHLL
:
22517 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22519 case OPC_MAQ_S_W_QHLR
:
22521 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22523 case OPC_MAQ_SA_W_QHLR
:
22525 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22527 case OPC_MAQ_S_W_QHRL
:
22529 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22531 case OPC_MAQ_SA_W_QHRL
:
22533 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22535 case OPC_MAQ_S_W_QHRR
:
22537 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22539 case OPC_MAQ_SA_W_QHRR
:
22541 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22543 case OPC_MULSAQ_S_L_PW
:
22545 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22547 case OPC_MULSAQ_S_W_QH
:
22549 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22555 case OPC_ADDU_QB_DSP
:
22557 case OPC_MULEU_S_PH_QBL
:
22559 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22561 case OPC_MULEU_S_PH_QBR
:
22563 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22565 case OPC_MULQ_RS_PH
:
22567 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22569 case OPC_MULEQ_S_W_PHL
:
22571 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22573 case OPC_MULEQ_S_W_PHR
:
22575 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22577 case OPC_MULQ_S_PH
:
22579 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22583 #ifdef TARGET_MIPS64
22584 case OPC_ADDU_OB_DSP
:
22586 case OPC_MULEQ_S_PW_QHL
:
22588 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22590 case OPC_MULEQ_S_PW_QHR
:
22592 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22594 case OPC_MULEU_S_QH_OBL
:
22596 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22598 case OPC_MULEU_S_QH_OBR
:
22600 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22602 case OPC_MULQ_RS_QH
:
22604 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22611 tcg_temp_free_i32(t0
);
22612 tcg_temp_free(v1_t
);
22613 tcg_temp_free(v2_t
);
22616 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22624 /* Treat as NOP. */
22628 t0
= tcg_temp_new();
22629 val_t
= tcg_temp_new();
22630 gen_load_gpr(val_t
, val
);
22633 case OPC_ABSQ_S_PH_DSP
:
22637 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22642 target_long result
;
22643 imm
= (ctx
->opcode
>> 16) & 0xFF;
22644 result
= (uint32_t)imm
<< 24 |
22645 (uint32_t)imm
<< 16 |
22646 (uint32_t)imm
<< 8 |
22648 result
= (int32_t)result
;
22649 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
22654 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22655 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22656 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22657 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22658 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22659 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22664 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22665 imm
= (int16_t)(imm
<< 6) >> 6;
22666 tcg_gen_movi_tl(cpu_gpr
[ret
], \
22667 (target_long
)((int32_t)imm
<< 16 | \
22673 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22674 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22675 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22676 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22680 #ifdef TARGET_MIPS64
22681 case OPC_ABSQ_S_QH_DSP
:
22688 imm
= (ctx
->opcode
>> 16) & 0xFF;
22689 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
22690 temp
= (temp
<< 16) | temp
;
22691 temp
= (temp
<< 32) | temp
;
22692 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22700 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22701 imm
= (int16_t)(imm
<< 6) >> 6;
22702 temp
= ((target_long
)imm
<< 32) \
22703 | ((target_long
)imm
& 0xFFFFFFFF);
22704 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22712 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22713 imm
= (int16_t)(imm
<< 6) >> 6;
22715 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
22716 ((uint64_t)(uint16_t)imm
<< 32) |
22717 ((uint64_t)(uint16_t)imm
<< 16) |
22718 (uint64_t)(uint16_t)imm
;
22719 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22724 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22725 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22726 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22727 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22728 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22729 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22730 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22734 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
22735 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22736 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22740 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22741 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22742 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22743 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22744 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22751 tcg_temp_free(val_t
);
22754 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
22755 uint32_t op1
, uint32_t op2
,
22756 int ret
, int v1
, int v2
, int check_ret
)
22762 if ((ret
== 0) && (check_ret
== 1)) {
22763 /* Treat as NOP. */
22767 t1
= tcg_temp_new();
22768 v1_t
= tcg_temp_new();
22769 v2_t
= tcg_temp_new();
22771 gen_load_gpr(v1_t
, v1
);
22772 gen_load_gpr(v2_t
, v2
);
22775 case OPC_CMPU_EQ_QB_DSP
:
22777 case OPC_CMPU_EQ_QB
:
22779 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
22781 case OPC_CMPU_LT_QB
:
22783 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
22785 case OPC_CMPU_LE_QB
:
22787 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
22789 case OPC_CMPGU_EQ_QB
:
22791 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22793 case OPC_CMPGU_LT_QB
:
22795 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22797 case OPC_CMPGU_LE_QB
:
22799 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22801 case OPC_CMPGDU_EQ_QB
:
22803 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
22804 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22805 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22806 tcg_gen_shli_tl(t1
, t1
, 24);
22807 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22809 case OPC_CMPGDU_LT_QB
:
22811 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
22812 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22813 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22814 tcg_gen_shli_tl(t1
, t1
, 24);
22815 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22817 case OPC_CMPGDU_LE_QB
:
22819 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
22820 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22821 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22822 tcg_gen_shli_tl(t1
, t1
, 24);
22823 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22825 case OPC_CMP_EQ_PH
:
22827 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
22829 case OPC_CMP_LT_PH
:
22831 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
22833 case OPC_CMP_LE_PH
:
22835 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
22839 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22843 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22845 case OPC_PACKRL_PH
:
22847 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22851 #ifdef TARGET_MIPS64
22852 case OPC_CMPU_EQ_OB_DSP
:
22854 case OPC_CMP_EQ_PW
:
22856 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
22858 case OPC_CMP_LT_PW
:
22860 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
22862 case OPC_CMP_LE_PW
:
22864 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
22866 case OPC_CMP_EQ_QH
:
22868 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
22870 case OPC_CMP_LT_QH
:
22872 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
22874 case OPC_CMP_LE_QH
:
22876 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
22878 case OPC_CMPGDU_EQ_OB
:
22880 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22882 case OPC_CMPGDU_LT_OB
:
22884 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22886 case OPC_CMPGDU_LE_OB
:
22888 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22890 case OPC_CMPGU_EQ_OB
:
22892 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22894 case OPC_CMPGU_LT_OB
:
22896 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22898 case OPC_CMPGU_LE_OB
:
22900 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22902 case OPC_CMPU_EQ_OB
:
22904 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
22906 case OPC_CMPU_LT_OB
:
22908 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
22910 case OPC_CMPU_LE_OB
:
22912 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
22914 case OPC_PACKRL_PW
:
22916 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22920 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22924 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22928 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22936 tcg_temp_free(v1_t
);
22937 tcg_temp_free(v2_t
);
22940 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
22941 uint32_t op1
, int rt
, int rs
, int sa
)
22948 /* Treat as NOP. */
22952 t0
= tcg_temp_new();
22953 gen_load_gpr(t0
, rs
);
22956 case OPC_APPEND_DSP
:
22957 switch (MASK_APPEND(ctx
->opcode
)) {
22960 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
22962 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22966 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22967 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
22968 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
22969 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22971 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22975 if (sa
!= 0 && sa
!= 2) {
22976 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
22977 tcg_gen_ext32u_tl(t0
, t0
);
22978 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
22979 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22981 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22983 default: /* Invalid */
22984 MIPS_INVAL("MASK APPEND");
22985 gen_reserved_instruction(ctx
);
22989 #ifdef TARGET_MIPS64
22990 case OPC_DAPPEND_DSP
:
22991 switch (MASK_DAPPEND(ctx
->opcode
)) {
22994 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
22998 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
22999 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23000 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23004 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23005 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23006 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23011 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23012 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23013 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23014 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23017 default: /* Invalid */
23018 MIPS_INVAL("MASK DAPPEND");
23019 gen_reserved_instruction(ctx
);
23028 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23029 int ret
, int v1
, int v2
, int check_ret
)
23038 if ((ret
== 0) && (check_ret
== 1)) {
23039 /* Treat as NOP. */
23043 t0
= tcg_temp_new();
23044 t1
= tcg_temp_new();
23045 v1_t
= tcg_temp_new();
23046 v2_t
= tcg_temp_new();
23048 gen_load_gpr(v1_t
, v1
);
23049 gen_load_gpr(v2_t
, v2
);
23052 case OPC_EXTR_W_DSP
:
23056 tcg_gen_movi_tl(t0
, v2
);
23057 tcg_gen_movi_tl(t1
, v1
);
23058 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23061 tcg_gen_movi_tl(t0
, v2
);
23062 tcg_gen_movi_tl(t1
, v1
);
23063 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23065 case OPC_EXTR_RS_W
:
23066 tcg_gen_movi_tl(t0
, v2
);
23067 tcg_gen_movi_tl(t1
, v1
);
23068 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23071 tcg_gen_movi_tl(t0
, v2
);
23072 tcg_gen_movi_tl(t1
, v1
);
23073 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23075 case OPC_EXTRV_S_H
:
23076 tcg_gen_movi_tl(t0
, v2
);
23077 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23080 tcg_gen_movi_tl(t0
, v2
);
23081 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23083 case OPC_EXTRV_R_W
:
23084 tcg_gen_movi_tl(t0
, v2
);
23085 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23087 case OPC_EXTRV_RS_W
:
23088 tcg_gen_movi_tl(t0
, v2
);
23089 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23092 tcg_gen_movi_tl(t0
, v2
);
23093 tcg_gen_movi_tl(t1
, v1
);
23094 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23097 tcg_gen_movi_tl(t0
, v2
);
23098 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23101 tcg_gen_movi_tl(t0
, v2
);
23102 tcg_gen_movi_tl(t1
, v1
);
23103 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23106 tcg_gen_movi_tl(t0
, v2
);
23107 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23110 imm
= (ctx
->opcode
>> 20) & 0x3F;
23111 tcg_gen_movi_tl(t0
, ret
);
23112 tcg_gen_movi_tl(t1
, imm
);
23113 gen_helper_shilo(t0
, t1
, cpu_env
);
23116 tcg_gen_movi_tl(t0
, ret
);
23117 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23120 tcg_gen_movi_tl(t0
, ret
);
23121 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23124 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23125 tcg_gen_movi_tl(t0
, imm
);
23126 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23129 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23130 tcg_gen_movi_tl(t0
, imm
);
23131 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23135 #ifdef TARGET_MIPS64
23136 case OPC_DEXTR_W_DSP
:
23140 tcg_gen_movi_tl(t0
, ret
);
23141 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23145 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23146 int ac
= (ctx
->opcode
>> 11) & 0x03;
23147 tcg_gen_movi_tl(t0
, shift
);
23148 tcg_gen_movi_tl(t1
, ac
);
23149 gen_helper_dshilo(t0
, t1
, cpu_env
);
23154 int ac
= (ctx
->opcode
>> 11) & 0x03;
23155 tcg_gen_movi_tl(t0
, ac
);
23156 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23160 tcg_gen_movi_tl(t0
, v2
);
23161 tcg_gen_movi_tl(t1
, v1
);
23163 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23166 tcg_gen_movi_tl(t0
, v2
);
23167 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23170 tcg_gen_movi_tl(t0
, v2
);
23171 tcg_gen_movi_tl(t1
, v1
);
23172 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23175 tcg_gen_movi_tl(t0
, v2
);
23176 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23179 tcg_gen_movi_tl(t0
, v2
);
23180 tcg_gen_movi_tl(t1
, v1
);
23181 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23183 case OPC_DEXTR_R_L
:
23184 tcg_gen_movi_tl(t0
, v2
);
23185 tcg_gen_movi_tl(t1
, v1
);
23186 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23188 case OPC_DEXTR_RS_L
:
23189 tcg_gen_movi_tl(t0
, v2
);
23190 tcg_gen_movi_tl(t1
, v1
);
23191 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23194 tcg_gen_movi_tl(t0
, v2
);
23195 tcg_gen_movi_tl(t1
, v1
);
23196 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23198 case OPC_DEXTR_R_W
:
23199 tcg_gen_movi_tl(t0
, v2
);
23200 tcg_gen_movi_tl(t1
, v1
);
23201 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23203 case OPC_DEXTR_RS_W
:
23204 tcg_gen_movi_tl(t0
, v2
);
23205 tcg_gen_movi_tl(t1
, v1
);
23206 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23208 case OPC_DEXTR_S_H
:
23209 tcg_gen_movi_tl(t0
, v2
);
23210 tcg_gen_movi_tl(t1
, v1
);
23211 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23213 case OPC_DEXTRV_S_H
:
23214 tcg_gen_movi_tl(t0
, v2
);
23215 tcg_gen_movi_tl(t1
, v1
);
23216 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23219 tcg_gen_movi_tl(t0
, v2
);
23220 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23222 case OPC_DEXTRV_R_L
:
23223 tcg_gen_movi_tl(t0
, v2
);
23224 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23226 case OPC_DEXTRV_RS_L
:
23227 tcg_gen_movi_tl(t0
, v2
);
23228 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23231 tcg_gen_movi_tl(t0
, v2
);
23232 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23234 case OPC_DEXTRV_R_W
:
23235 tcg_gen_movi_tl(t0
, v2
);
23236 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23238 case OPC_DEXTRV_RS_W
:
23239 tcg_gen_movi_tl(t0
, v2
);
23240 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23249 tcg_temp_free(v1_t
);
23250 tcg_temp_free(v2_t
);
23253 /* End MIPSDSP functions. */
23255 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23257 int rs
, rt
, rd
, sa
;
23260 rs
= (ctx
->opcode
>> 21) & 0x1f;
23261 rt
= (ctx
->opcode
>> 16) & 0x1f;
23262 rd
= (ctx
->opcode
>> 11) & 0x1f;
23263 sa
= (ctx
->opcode
>> 6) & 0x1f;
23265 op1
= MASK_SPECIAL(ctx
->opcode
);
23271 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23281 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23284 MIPS_INVAL("special_r6 muldiv");
23285 gen_reserved_instruction(ctx
);
23291 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23295 if (rt
== 0 && sa
== 1) {
23297 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23298 * We need additionally to check other fields.
23300 gen_cl(ctx
, op1
, rd
, rs
);
23302 gen_reserved_instruction(ctx
);
23306 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23307 gen_helper_do_semihosting(cpu_env
);
23309 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23310 gen_reserved_instruction(ctx
);
23312 generate_exception_end(ctx
, EXCP_DBp
);
23316 #if defined(TARGET_MIPS64)
23319 if (rt
== 0 && sa
== 1) {
23321 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23322 * We need additionally to check other fields.
23324 check_mips_64(ctx
);
23325 gen_cl(ctx
, op1
, rd
, rs
);
23327 gen_reserved_instruction(ctx
);
23335 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23345 check_mips_64(ctx
);
23346 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23349 MIPS_INVAL("special_r6 muldiv");
23350 gen_reserved_instruction(ctx
);
23355 default: /* Invalid */
23356 MIPS_INVAL("special_r6");
23357 gen_reserved_instruction(ctx
);
23362 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23364 int rs
= extract32(ctx
->opcode
, 21, 5);
23365 int rt
= extract32(ctx
->opcode
, 16, 5);
23366 int rd
= extract32(ctx
->opcode
, 11, 5);
23367 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23370 case OPC_MOVN
: /* Conditional move */
23372 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23374 case OPC_MFHI
: /* Move from HI/LO */
23376 gen_HILO(ctx
, op1
, 0, rd
);
23379 case OPC_MTLO
: /* Move to HI/LO */
23380 gen_HILO(ctx
, op1
, 0, rs
);
23384 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23388 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23390 #if defined(TARGET_MIPS64)
23395 check_insn_opc_user_only(ctx
, INSN_R5900
);
23396 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23400 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23402 default: /* Invalid */
23403 MIPS_INVAL("special_tx79");
23404 gen_reserved_instruction(ctx
);
23409 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23411 int rs
, rt
, rd
, sa
;
23414 rs
= (ctx
->opcode
>> 21) & 0x1f;
23415 rt
= (ctx
->opcode
>> 16) & 0x1f;
23416 rd
= (ctx
->opcode
>> 11) & 0x1f;
23417 sa
= (ctx
->opcode
>> 6) & 0x1f;
23419 op1
= MASK_SPECIAL(ctx
->opcode
);
23421 case OPC_MOVN
: /* Conditional move */
23423 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23424 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23425 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23427 case OPC_MFHI
: /* Move from HI/LO */
23429 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23432 case OPC_MTLO
: /* Move to HI/LO */
23433 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23436 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23437 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23438 check_cp1_enabled(ctx
);
23439 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23440 (ctx
->opcode
>> 16) & 1);
23442 generate_exception_err(ctx
, EXCP_CpU
, 1);
23448 check_insn(ctx
, INSN_VR54XX
);
23449 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23450 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23452 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23457 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23459 #if defined(TARGET_MIPS64)
23464 check_insn(ctx
, ISA_MIPS3
);
23465 check_mips_64(ctx
);
23466 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23470 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23473 #ifdef MIPS_STRICT_STANDARD
23474 MIPS_INVAL("SPIM");
23475 gen_reserved_instruction(ctx
);
23477 /* Implemented as RI exception for now. */
23478 MIPS_INVAL("spim (unofficial)");
23479 gen_reserved_instruction(ctx
);
23482 default: /* Invalid */
23483 MIPS_INVAL("special_legacy");
23484 gen_reserved_instruction(ctx
);
23489 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23491 int rs
, rt
, rd
, sa
;
23494 rs
= (ctx
->opcode
>> 21) & 0x1f;
23495 rt
= (ctx
->opcode
>> 16) & 0x1f;
23496 rd
= (ctx
->opcode
>> 11) & 0x1f;
23497 sa
= (ctx
->opcode
>> 6) & 0x1f;
23499 op1
= MASK_SPECIAL(ctx
->opcode
);
23501 case OPC_SLL
: /* Shift with immediate */
23502 if (sa
== 5 && rd
== 0 &&
23503 rs
== 0 && rt
== 0) { /* PAUSE */
23504 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23505 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23506 gen_reserved_instruction(ctx
);
23512 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23515 switch ((ctx
->opcode
>> 21) & 0x1f) {
23517 /* rotr is decoded as srl on non-R2 CPUs */
23518 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23523 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23526 gen_reserved_instruction(ctx
);
23534 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23536 case OPC_SLLV
: /* Shifts */
23538 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23541 switch ((ctx
->opcode
>> 6) & 0x1f) {
23543 /* rotrv is decoded as srlv on non-R2 CPUs */
23544 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23549 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23552 gen_reserved_instruction(ctx
);
23556 case OPC_SLT
: /* Set on less than */
23558 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23560 case OPC_AND
: /* Logic*/
23564 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23567 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23569 case OPC_TGE
: /* Traps */
23575 check_insn(ctx
, ISA_MIPS2
);
23576 gen_trap(ctx
, op1
, rs
, rt
, -1);
23579 /* Pmon entry point, also R4010 selsl */
23580 #ifdef MIPS_STRICT_STANDARD
23581 MIPS_INVAL("PMON / selsl");
23582 gen_reserved_instruction(ctx
);
23584 gen_helper_0e0i(pmon
, sa
);
23588 generate_exception_end(ctx
, EXCP_SYSCALL
);
23591 generate_exception_end(ctx
, EXCP_BREAK
);
23594 check_insn(ctx
, ISA_MIPS2
);
23595 gen_sync(extract32(ctx
->opcode
, 6, 5));
23598 #if defined(TARGET_MIPS64)
23599 /* MIPS64 specific opcodes */
23604 check_insn(ctx
, ISA_MIPS3
);
23605 check_mips_64(ctx
);
23606 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23609 switch ((ctx
->opcode
>> 21) & 0x1f) {
23611 /* drotr is decoded as dsrl on non-R2 CPUs */
23612 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23617 check_insn(ctx
, ISA_MIPS3
);
23618 check_mips_64(ctx
);
23619 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23622 gen_reserved_instruction(ctx
);
23627 switch ((ctx
->opcode
>> 21) & 0x1f) {
23629 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23630 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23635 check_insn(ctx
, ISA_MIPS3
);
23636 check_mips_64(ctx
);
23637 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23640 gen_reserved_instruction(ctx
);
23648 check_insn(ctx
, ISA_MIPS3
);
23649 check_mips_64(ctx
);
23650 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23654 check_insn(ctx
, ISA_MIPS3
);
23655 check_mips_64(ctx
);
23656 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23659 switch ((ctx
->opcode
>> 6) & 0x1f) {
23661 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23662 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23667 check_insn(ctx
, ISA_MIPS3
);
23668 check_mips_64(ctx
);
23669 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23672 gen_reserved_instruction(ctx
);
23678 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
23679 decode_opc_special_r6(env
, ctx
);
23680 } else if (ctx
->insn_flags
& INSN_R5900
) {
23681 decode_opc_special_tx79(env
, ctx
);
23683 decode_opc_special_legacy(env
, ctx
);
23689 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23694 rs
= (ctx
->opcode
>> 21) & 0x1f;
23695 rt
= (ctx
->opcode
>> 16) & 0x1f;
23696 rd
= (ctx
->opcode
>> 11) & 0x1f;
23698 op1
= MASK_SPECIAL2(ctx
->opcode
);
23700 case OPC_MADD
: /* Multiply and add/sub */
23704 check_insn(ctx
, ISA_MIPS_R1
);
23705 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23708 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23711 case OPC_DIVU_G_2F
:
23712 case OPC_MULT_G_2F
:
23713 case OPC_MULTU_G_2F
:
23715 case OPC_MODU_G_2F
:
23716 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23717 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23721 check_insn(ctx
, ISA_MIPS_R1
);
23722 gen_cl(ctx
, op1
, rd
, rs
);
23725 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23726 gen_helper_do_semihosting(cpu_env
);
23729 * XXX: not clear which exception should be raised
23730 * when in debug mode...
23732 check_insn(ctx
, ISA_MIPS_R1
);
23733 generate_exception_end(ctx
, EXCP_DBp
);
23736 #if defined(TARGET_MIPS64)
23739 check_insn(ctx
, ISA_MIPS_R1
);
23740 check_mips_64(ctx
);
23741 gen_cl(ctx
, op1
, rd
, rs
);
23743 case OPC_DMULT_G_2F
:
23744 case OPC_DMULTU_G_2F
:
23745 case OPC_DDIV_G_2F
:
23746 case OPC_DDIVU_G_2F
:
23747 case OPC_DMOD_G_2F
:
23748 case OPC_DMODU_G_2F
:
23749 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23750 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23753 default: /* Invalid */
23754 MIPS_INVAL("special2_legacy");
23755 gen_reserved_instruction(ctx
);
23760 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23762 int rs
, rt
, rd
, sa
;
23766 rs
= (ctx
->opcode
>> 21) & 0x1f;
23767 rt
= (ctx
->opcode
>> 16) & 0x1f;
23768 rd
= (ctx
->opcode
>> 11) & 0x1f;
23769 sa
= (ctx
->opcode
>> 6) & 0x1f;
23770 imm
= (int16_t)ctx
->opcode
>> 7;
23772 op1
= MASK_SPECIAL3(ctx
->opcode
);
23776 /* hint codes 24-31 are reserved and signal RI */
23777 gen_reserved_instruction(ctx
);
23779 /* Treat as NOP. */
23782 check_cp0_enabled(ctx
);
23783 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
23784 gen_cache_operation(ctx
, rt
, rs
, imm
);
23788 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
23791 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23796 /* Treat as NOP. */
23799 op2
= MASK_BSHFL(ctx
->opcode
);
23805 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
23808 gen_bitswap(ctx
, op2
, rd
, rt
);
23813 #ifndef CONFIG_USER_ONLY
23815 if (unlikely(ctx
->gi
<= 1)) {
23816 gen_reserved_instruction(ctx
);
23818 check_cp0_enabled(ctx
);
23819 switch ((ctx
->opcode
>> 6) & 3) {
23820 case 0: /* GINVI */
23821 /* Treat as NOP. */
23823 case 2: /* GINVT */
23824 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
23827 gen_reserved_instruction(ctx
);
23832 #if defined(TARGET_MIPS64)
23834 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
23837 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23840 check_mips_64(ctx
);
23843 /* Treat as NOP. */
23846 op2
= MASK_DBSHFL(ctx
->opcode
);
23856 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
23859 gen_bitswap(ctx
, op2
, rd
, rt
);
23866 default: /* Invalid */
23867 MIPS_INVAL("special3_r6");
23868 gen_reserved_instruction(ctx
);
23873 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23878 rs
= (ctx
->opcode
>> 21) & 0x1f;
23879 rt
= (ctx
->opcode
>> 16) & 0x1f;
23880 rd
= (ctx
->opcode
>> 11) & 0x1f;
23882 op1
= MASK_SPECIAL3(ctx
->opcode
);
23885 case OPC_DIVU_G_2E
:
23887 case OPC_MODU_G_2E
:
23888 case OPC_MULT_G_2E
:
23889 case OPC_MULTU_G_2E
:
23891 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23892 * the same mask and op1.
23894 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
23895 op2
= MASK_ADDUH_QB(ctx
->opcode
);
23898 case OPC_ADDUH_R_QB
:
23900 case OPC_ADDQH_R_PH
:
23902 case OPC_ADDQH_R_W
:
23904 case OPC_SUBUH_R_QB
:
23906 case OPC_SUBQH_R_PH
:
23908 case OPC_SUBQH_R_W
:
23909 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23914 case OPC_MULQ_RS_W
:
23915 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
23918 MIPS_INVAL("MASK ADDUH.QB");
23919 gen_reserved_instruction(ctx
);
23922 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
23923 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23925 gen_reserved_instruction(ctx
);
23929 op2
= MASK_LX(ctx
->opcode
);
23931 #if defined(TARGET_MIPS64)
23937 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
23939 default: /* Invalid */
23940 MIPS_INVAL("MASK LX");
23941 gen_reserved_instruction(ctx
);
23945 case OPC_ABSQ_S_PH_DSP
:
23946 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
23948 case OPC_ABSQ_S_QB
:
23949 case OPC_ABSQ_S_PH
:
23951 case OPC_PRECEQ_W_PHL
:
23952 case OPC_PRECEQ_W_PHR
:
23953 case OPC_PRECEQU_PH_QBL
:
23954 case OPC_PRECEQU_PH_QBR
:
23955 case OPC_PRECEQU_PH_QBLA
:
23956 case OPC_PRECEQU_PH_QBRA
:
23957 case OPC_PRECEU_PH_QBL
:
23958 case OPC_PRECEU_PH_QBR
:
23959 case OPC_PRECEU_PH_QBLA
:
23960 case OPC_PRECEU_PH_QBRA
:
23961 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23968 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
23971 MIPS_INVAL("MASK ABSQ_S.PH");
23972 gen_reserved_instruction(ctx
);
23976 case OPC_ADDU_QB_DSP
:
23977 op2
= MASK_ADDU_QB(ctx
->opcode
);
23980 case OPC_ADDQ_S_PH
:
23983 case OPC_ADDU_S_QB
:
23985 case OPC_ADDU_S_PH
:
23987 case OPC_SUBQ_S_PH
:
23990 case OPC_SUBU_S_QB
:
23992 case OPC_SUBU_S_PH
:
23996 case OPC_RADDU_W_QB
:
23997 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23999 case OPC_MULEU_S_PH_QBL
:
24000 case OPC_MULEU_S_PH_QBR
:
24001 case OPC_MULQ_RS_PH
:
24002 case OPC_MULEQ_S_W_PHL
:
24003 case OPC_MULEQ_S_W_PHR
:
24004 case OPC_MULQ_S_PH
:
24005 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24007 default: /* Invalid */
24008 MIPS_INVAL("MASK ADDU.QB");
24009 gen_reserved_instruction(ctx
);
24014 case OPC_CMPU_EQ_QB_DSP
:
24015 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24017 case OPC_PRECR_SRA_PH_W
:
24018 case OPC_PRECR_SRA_R_PH_W
:
24019 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24021 case OPC_PRECR_QB_PH
:
24022 case OPC_PRECRQ_QB_PH
:
24023 case OPC_PRECRQ_PH_W
:
24024 case OPC_PRECRQ_RS_PH_W
:
24025 case OPC_PRECRQU_S_QB_PH
:
24026 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24028 case OPC_CMPU_EQ_QB
:
24029 case OPC_CMPU_LT_QB
:
24030 case OPC_CMPU_LE_QB
:
24031 case OPC_CMP_EQ_PH
:
24032 case OPC_CMP_LT_PH
:
24033 case OPC_CMP_LE_PH
:
24034 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24036 case OPC_CMPGU_EQ_QB
:
24037 case OPC_CMPGU_LT_QB
:
24038 case OPC_CMPGU_LE_QB
:
24039 case OPC_CMPGDU_EQ_QB
:
24040 case OPC_CMPGDU_LT_QB
:
24041 case OPC_CMPGDU_LE_QB
:
24044 case OPC_PACKRL_PH
:
24045 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24047 default: /* Invalid */
24048 MIPS_INVAL("MASK CMPU.EQ.QB");
24049 gen_reserved_instruction(ctx
);
24053 case OPC_SHLL_QB_DSP
:
24054 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24056 case OPC_DPA_W_PH_DSP
:
24057 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24059 case OPC_DPAU_H_QBL
:
24060 case OPC_DPAU_H_QBR
:
24061 case OPC_DPSU_H_QBL
:
24062 case OPC_DPSU_H_QBR
:
24064 case OPC_DPAX_W_PH
:
24065 case OPC_DPAQ_S_W_PH
:
24066 case OPC_DPAQX_S_W_PH
:
24067 case OPC_DPAQX_SA_W_PH
:
24069 case OPC_DPSX_W_PH
:
24070 case OPC_DPSQ_S_W_PH
:
24071 case OPC_DPSQX_S_W_PH
:
24072 case OPC_DPSQX_SA_W_PH
:
24073 case OPC_MULSAQ_S_W_PH
:
24074 case OPC_DPAQ_SA_L_W
:
24075 case OPC_DPSQ_SA_L_W
:
24076 case OPC_MAQ_S_W_PHL
:
24077 case OPC_MAQ_S_W_PHR
:
24078 case OPC_MAQ_SA_W_PHL
:
24079 case OPC_MAQ_SA_W_PHR
:
24080 case OPC_MULSA_W_PH
:
24081 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24083 default: /* Invalid */
24084 MIPS_INVAL("MASK DPAW.PH");
24085 gen_reserved_instruction(ctx
);
24090 op2
= MASK_INSV(ctx
->opcode
);
24101 t0
= tcg_temp_new();
24102 t1
= tcg_temp_new();
24104 gen_load_gpr(t0
, rt
);
24105 gen_load_gpr(t1
, rs
);
24107 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24113 default: /* Invalid */
24114 MIPS_INVAL("MASK INSV");
24115 gen_reserved_instruction(ctx
);
24119 case OPC_APPEND_DSP
:
24120 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24122 case OPC_EXTR_W_DSP
:
24123 op2
= MASK_EXTR_W(ctx
->opcode
);
24127 case OPC_EXTR_RS_W
:
24129 case OPC_EXTRV_S_H
:
24131 case OPC_EXTRV_R_W
:
24132 case OPC_EXTRV_RS_W
:
24137 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24140 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24146 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24148 default: /* Invalid */
24149 MIPS_INVAL("MASK EXTR.W");
24150 gen_reserved_instruction(ctx
);
24154 #if defined(TARGET_MIPS64)
24155 case OPC_DDIV_G_2E
:
24156 case OPC_DDIVU_G_2E
:
24157 case OPC_DMULT_G_2E
:
24158 case OPC_DMULTU_G_2E
:
24159 case OPC_DMOD_G_2E
:
24160 case OPC_DMODU_G_2E
:
24161 check_insn(ctx
, INSN_LOONGSON2E
);
24162 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24164 case OPC_ABSQ_S_QH_DSP
:
24165 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24167 case OPC_PRECEQ_L_PWL
:
24168 case OPC_PRECEQ_L_PWR
:
24169 case OPC_PRECEQ_PW_QHL
:
24170 case OPC_PRECEQ_PW_QHR
:
24171 case OPC_PRECEQ_PW_QHLA
:
24172 case OPC_PRECEQ_PW_QHRA
:
24173 case OPC_PRECEQU_QH_OBL
:
24174 case OPC_PRECEQU_QH_OBR
:
24175 case OPC_PRECEQU_QH_OBLA
:
24176 case OPC_PRECEQU_QH_OBRA
:
24177 case OPC_PRECEU_QH_OBL
:
24178 case OPC_PRECEU_QH_OBR
:
24179 case OPC_PRECEU_QH_OBLA
:
24180 case OPC_PRECEU_QH_OBRA
:
24181 case OPC_ABSQ_S_OB
:
24182 case OPC_ABSQ_S_PW
:
24183 case OPC_ABSQ_S_QH
:
24184 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24192 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24194 default: /* Invalid */
24195 MIPS_INVAL("MASK ABSQ_S.QH");
24196 gen_reserved_instruction(ctx
);
24200 case OPC_ADDU_OB_DSP
:
24201 op2
= MASK_ADDU_OB(ctx
->opcode
);
24203 case OPC_RADDU_L_OB
:
24205 case OPC_SUBQ_S_PW
:
24207 case OPC_SUBQ_S_QH
:
24209 case OPC_SUBU_S_OB
:
24211 case OPC_SUBU_S_QH
:
24213 case OPC_SUBUH_R_OB
:
24215 case OPC_ADDQ_S_PW
:
24217 case OPC_ADDQ_S_QH
:
24219 case OPC_ADDU_S_OB
:
24221 case OPC_ADDU_S_QH
:
24223 case OPC_ADDUH_R_OB
:
24224 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24226 case OPC_MULEQ_S_PW_QHL
:
24227 case OPC_MULEQ_S_PW_QHR
:
24228 case OPC_MULEU_S_QH_OBL
:
24229 case OPC_MULEU_S_QH_OBR
:
24230 case OPC_MULQ_RS_QH
:
24231 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24233 default: /* Invalid */
24234 MIPS_INVAL("MASK ADDU.OB");
24235 gen_reserved_instruction(ctx
);
24239 case OPC_CMPU_EQ_OB_DSP
:
24240 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24242 case OPC_PRECR_SRA_QH_PW
:
24243 case OPC_PRECR_SRA_R_QH_PW
:
24244 /* Return value is rt. */
24245 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24247 case OPC_PRECR_OB_QH
:
24248 case OPC_PRECRQ_OB_QH
:
24249 case OPC_PRECRQ_PW_L
:
24250 case OPC_PRECRQ_QH_PW
:
24251 case OPC_PRECRQ_RS_QH_PW
:
24252 case OPC_PRECRQU_S_OB_QH
:
24253 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24255 case OPC_CMPU_EQ_OB
:
24256 case OPC_CMPU_LT_OB
:
24257 case OPC_CMPU_LE_OB
:
24258 case OPC_CMP_EQ_QH
:
24259 case OPC_CMP_LT_QH
:
24260 case OPC_CMP_LE_QH
:
24261 case OPC_CMP_EQ_PW
:
24262 case OPC_CMP_LT_PW
:
24263 case OPC_CMP_LE_PW
:
24264 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24266 case OPC_CMPGDU_EQ_OB
:
24267 case OPC_CMPGDU_LT_OB
:
24268 case OPC_CMPGDU_LE_OB
:
24269 case OPC_CMPGU_EQ_OB
:
24270 case OPC_CMPGU_LT_OB
:
24271 case OPC_CMPGU_LE_OB
:
24272 case OPC_PACKRL_PW
:
24276 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24278 default: /* Invalid */
24279 MIPS_INVAL("MASK CMPU_EQ.OB");
24280 gen_reserved_instruction(ctx
);
24284 case OPC_DAPPEND_DSP
:
24285 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24287 case OPC_DEXTR_W_DSP
:
24288 op2
= MASK_DEXTR_W(ctx
->opcode
);
24295 case OPC_DEXTR_R_L
:
24296 case OPC_DEXTR_RS_L
:
24298 case OPC_DEXTR_R_W
:
24299 case OPC_DEXTR_RS_W
:
24300 case OPC_DEXTR_S_H
:
24302 case OPC_DEXTRV_R_L
:
24303 case OPC_DEXTRV_RS_L
:
24304 case OPC_DEXTRV_S_H
:
24306 case OPC_DEXTRV_R_W
:
24307 case OPC_DEXTRV_RS_W
:
24308 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24313 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24315 default: /* Invalid */
24316 MIPS_INVAL("MASK EXTR.W");
24317 gen_reserved_instruction(ctx
);
24321 case OPC_DPAQ_W_QH_DSP
:
24322 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24324 case OPC_DPAU_H_OBL
:
24325 case OPC_DPAU_H_OBR
:
24326 case OPC_DPSU_H_OBL
:
24327 case OPC_DPSU_H_OBR
:
24329 case OPC_DPAQ_S_W_QH
:
24331 case OPC_DPSQ_S_W_QH
:
24332 case OPC_MULSAQ_S_W_QH
:
24333 case OPC_DPAQ_SA_L_PW
:
24334 case OPC_DPSQ_SA_L_PW
:
24335 case OPC_MULSAQ_S_L_PW
:
24336 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24338 case OPC_MAQ_S_W_QHLL
:
24339 case OPC_MAQ_S_W_QHLR
:
24340 case OPC_MAQ_S_W_QHRL
:
24341 case OPC_MAQ_S_W_QHRR
:
24342 case OPC_MAQ_SA_W_QHLL
:
24343 case OPC_MAQ_SA_W_QHLR
:
24344 case OPC_MAQ_SA_W_QHRL
:
24345 case OPC_MAQ_SA_W_QHRR
:
24346 case OPC_MAQ_S_L_PWL
:
24347 case OPC_MAQ_S_L_PWR
:
24352 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24354 default: /* Invalid */
24355 MIPS_INVAL("MASK DPAQ.W.QH");
24356 gen_reserved_instruction(ctx
);
24360 case OPC_DINSV_DSP
:
24361 op2
= MASK_INSV(ctx
->opcode
);
24373 t0
= tcg_temp_new();
24374 t1
= tcg_temp_new();
24376 gen_load_gpr(t0
, rt
);
24377 gen_load_gpr(t1
, rs
);
24379 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24385 default: /* Invalid */
24386 MIPS_INVAL("MASK DINSV");
24387 gen_reserved_instruction(ctx
);
24391 case OPC_SHLL_OB_DSP
:
24392 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24395 default: /* Invalid */
24396 MIPS_INVAL("special3_legacy");
24397 gen_reserved_instruction(ctx
);
24403 #if defined(TARGET_MIPS64)
24405 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24407 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24408 int rs
= extract32(ctx
->opcode
, 21, 5);
24409 int rt
= extract32(ctx
->opcode
, 16, 5);
24410 int rd
= extract32(ctx
->opcode
, 11, 5);
24413 case MMI_OPC_MULT1
:
24414 case MMI_OPC_MULTU1
:
24416 case MMI_OPC_MADDU
:
24417 case MMI_OPC_MADD1
:
24418 case MMI_OPC_MADDU1
:
24419 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24422 case MMI_OPC_DIVU1
:
24423 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24426 MIPS_INVAL("TX79 MMI class");
24427 gen_reserved_instruction(ctx
);
24432 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24434 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24437 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24439 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24443 * The TX79-specific instruction Store Quadword
24445 * +--------+-------+-------+------------------------+
24446 * | 011111 | base | rt | offset | SQ
24447 * +--------+-------+-------+------------------------+
24450 * has the same opcode as the Read Hardware Register instruction
24452 * +--------+-------+-------+-------+-------+--------+
24453 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24454 * +--------+-------+-------+-------+-------+--------+
24457 * that is required, trapped and emulated by the Linux kernel. However, all
24458 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24459 * offset is odd. Therefore all valid SQ instructions can execute normally.
24460 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24461 * between SQ and RDHWR, as the Linux kernel does.
24463 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24465 int base
= extract32(ctx
->opcode
, 21, 5);
24466 int rt
= extract32(ctx
->opcode
, 16, 5);
24467 int offset
= extract32(ctx
->opcode
, 0, 16);
24469 #ifdef CONFIG_USER_ONLY
24470 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
24471 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
24473 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
24474 int rd
= extract32(ctx
->opcode
, 11, 5);
24476 gen_rdhwr(ctx
, rt
, rd
, 0);
24481 gen_mmi_sq(ctx
, base
, rt
, offset
);
24486 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
24488 int rs
, rt
, rd
, sa
;
24492 rs
= (ctx
->opcode
>> 21) & 0x1f;
24493 rt
= (ctx
->opcode
>> 16) & 0x1f;
24494 rd
= (ctx
->opcode
>> 11) & 0x1f;
24495 sa
= (ctx
->opcode
>> 6) & 0x1f;
24496 imm
= sextract32(ctx
->opcode
, 7, 9);
24498 op1
= MASK_SPECIAL3(ctx
->opcode
);
24501 * EVA loads and stores overlap Loongson 2E instructions decoded by
24502 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24515 check_cp0_enabled(ctx
);
24516 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24523 check_cp0_enabled(ctx
);
24524 gen_st(ctx
, op1
, rt
, rs
, imm
);
24527 check_cp0_enabled(ctx
);
24528 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
24532 check_cp0_enabled(ctx
);
24533 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24534 gen_cache_operation(ctx
, rt
, rs
, imm
);
24538 check_cp0_enabled(ctx
);
24539 /* Treat as NOP. */
24547 check_insn(ctx
, ISA_MIPS_R2
);
24548 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24551 op2
= MASK_BSHFL(ctx
->opcode
);
24558 check_insn(ctx
, ISA_MIPS_R6
);
24559 decode_opc_special3_r6(env
, ctx
);
24562 check_insn(ctx
, ISA_MIPS_R2
);
24563 gen_bshfl(ctx
, op2
, rt
, rd
);
24567 #if defined(TARGET_MIPS64)
24574 check_insn(ctx
, ISA_MIPS_R2
);
24575 check_mips_64(ctx
);
24576 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24579 op2
= MASK_DBSHFL(ctx
->opcode
);
24590 check_insn(ctx
, ISA_MIPS_R6
);
24591 decode_opc_special3_r6(env
, ctx
);
24594 check_insn(ctx
, ISA_MIPS_R2
);
24595 check_mips_64(ctx
);
24596 op2
= MASK_DBSHFL(ctx
->opcode
);
24597 gen_bshfl(ctx
, op2
, rt
, rd
);
24603 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
24608 TCGv t0
= tcg_temp_new();
24609 TCGv t1
= tcg_temp_new();
24611 gen_load_gpr(t0
, rt
);
24612 gen_load_gpr(t1
, rs
);
24613 gen_helper_fork(t0
, t1
);
24621 TCGv t0
= tcg_temp_new();
24623 gen_load_gpr(t0
, rs
);
24624 gen_helper_yield(t0
, cpu_env
, t0
);
24625 gen_store_gpr(t0
, rd
);
24630 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24631 decode_opc_special3_r6(env
, ctx
);
24633 decode_opc_special3_legacy(env
, ctx
);
24638 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24641 int rs
, rt
, rd
, sa
;
24645 op
= MASK_OP_MAJOR(ctx
->opcode
);
24646 rs
= (ctx
->opcode
>> 21) & 0x1f;
24647 rt
= (ctx
->opcode
>> 16) & 0x1f;
24648 rd
= (ctx
->opcode
>> 11) & 0x1f;
24649 sa
= (ctx
->opcode
>> 6) & 0x1f;
24650 imm
= (int16_t)ctx
->opcode
;
24653 decode_opc_special(env
, ctx
);
24656 #if defined(TARGET_MIPS64)
24657 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
24658 decode_mmi(env
, ctx
);
24662 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
24663 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
24664 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
24666 decode_ase_mxu(ctx
, ctx
->opcode
);
24670 decode_opc_special2_legacy(env
, ctx
);
24673 #if defined(TARGET_MIPS64)
24674 if (ctx
->insn_flags
& INSN_R5900
) {
24675 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
24677 decode_opc_special3(env
, ctx
);
24680 decode_opc_special3(env
, ctx
);
24684 op1
= MASK_REGIMM(ctx
->opcode
);
24686 case OPC_BLTZL
: /* REGIMM branches */
24690 check_insn(ctx
, ISA_MIPS2
);
24691 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24695 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24699 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24701 /* OPC_NAL, OPC_BAL */
24702 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
24704 gen_reserved_instruction(ctx
);
24707 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24710 case OPC_TGEI
: /* REGIMM traps */
24717 check_insn(ctx
, ISA_MIPS2
);
24718 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24719 gen_trap(ctx
, op1
, rs
, -1, imm
);
24722 check_insn(ctx
, ISA_MIPS_R6
);
24723 gen_reserved_instruction(ctx
);
24726 check_insn(ctx
, ISA_MIPS_R2
);
24728 * Break the TB to be able to sync copied instructions
24731 ctx
->base
.is_jmp
= DISAS_STOP
;
24733 case OPC_BPOSGE32
: /* MIPS DSP branch */
24734 #if defined(TARGET_MIPS64)
24738 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
24740 #if defined(TARGET_MIPS64)
24742 check_insn(ctx
, ISA_MIPS_R6
);
24743 check_mips_64(ctx
);
24745 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
24749 check_insn(ctx
, ISA_MIPS_R6
);
24750 check_mips_64(ctx
);
24752 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
24756 default: /* Invalid */
24757 MIPS_INVAL("regimm");
24758 gen_reserved_instruction(ctx
);
24763 check_cp0_enabled(ctx
);
24764 op1
= MASK_CP0(ctx
->opcode
);
24772 #if defined(TARGET_MIPS64)
24776 #ifndef CONFIG_USER_ONLY
24777 gen_cp0(env
, ctx
, op1
, rt
, rd
);
24778 #endif /* !CONFIG_USER_ONLY */
24796 #ifndef CONFIG_USER_ONLY
24797 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
24798 #endif /* !CONFIG_USER_ONLY */
24801 #ifndef CONFIG_USER_ONLY
24804 TCGv t0
= tcg_temp_new();
24806 op2
= MASK_MFMC0(ctx
->opcode
);
24810 gen_helper_dmt(t0
);
24811 gen_store_gpr(t0
, rt
);
24815 gen_helper_emt(t0
);
24816 gen_store_gpr(t0
, rt
);
24820 gen_helper_dvpe(t0
, cpu_env
);
24821 gen_store_gpr(t0
, rt
);
24825 gen_helper_evpe(t0
, cpu_env
);
24826 gen_store_gpr(t0
, rt
);
24829 check_insn(ctx
, ISA_MIPS_R6
);
24831 gen_helper_dvp(t0
, cpu_env
);
24832 gen_store_gpr(t0
, rt
);
24836 check_insn(ctx
, ISA_MIPS_R6
);
24838 gen_helper_evp(t0
, cpu_env
);
24839 gen_store_gpr(t0
, rt
);
24843 check_insn(ctx
, ISA_MIPS_R2
);
24844 save_cpu_state(ctx
, 1);
24845 gen_helper_di(t0
, cpu_env
);
24846 gen_store_gpr(t0
, rt
);
24848 * Stop translation as we may have switched
24849 * the execution mode.
24851 ctx
->base
.is_jmp
= DISAS_STOP
;
24854 check_insn(ctx
, ISA_MIPS_R2
);
24855 save_cpu_state(ctx
, 1);
24856 gen_helper_ei(t0
, cpu_env
);
24857 gen_store_gpr(t0
, rt
);
24859 * DISAS_STOP isn't sufficient, we need to ensure we break
24860 * out of translated code to check for pending interrupts.
24862 gen_save_pc(ctx
->base
.pc_next
+ 4);
24863 ctx
->base
.is_jmp
= DISAS_EXIT
;
24865 default: /* Invalid */
24866 MIPS_INVAL("mfmc0");
24867 gen_reserved_instruction(ctx
);
24872 #endif /* !CONFIG_USER_ONLY */
24875 check_insn(ctx
, ISA_MIPS_R2
);
24876 gen_load_srsgpr(rt
, rd
);
24879 check_insn(ctx
, ISA_MIPS_R2
);
24880 gen_store_srsgpr(rt
, rd
);
24884 gen_reserved_instruction(ctx
);
24888 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
24889 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24890 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
24891 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24894 /* Arithmetic with immediate opcode */
24895 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24899 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24901 case OPC_SLTI
: /* Set on less than with immediate opcode */
24903 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
24905 case OPC_ANDI
: /* Arithmetic with immediate opcode */
24906 case OPC_LUI
: /* OPC_AUI */
24909 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
24911 case OPC_J
: /* Jump */
24913 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
24914 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
24917 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
24918 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24920 gen_reserved_instruction(ctx
);
24923 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
24924 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24927 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24930 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
24931 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24933 gen_reserved_instruction(ctx
);
24936 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
24937 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24940 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24943 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
24946 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24948 check_insn(ctx
, ISA_MIPS_R6
);
24949 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
24950 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24953 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
24956 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24958 check_insn(ctx
, ISA_MIPS_R6
);
24959 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
24960 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24965 check_insn(ctx
, ISA_MIPS2
);
24966 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24970 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24972 case OPC_LL
: /* Load and stores */
24973 check_insn(ctx
, ISA_MIPS2
);
24974 if (ctx
->insn_flags
& INSN_R5900
) {
24975 check_insn_opc_user_only(ctx
, INSN_R5900
);
24986 gen_ld(ctx
, op
, rt
, rs
, imm
);
24993 gen_st(ctx
, op
, rt
, rs
, imm
);
24996 check_insn(ctx
, ISA_MIPS2
);
24997 if (ctx
->insn_flags
& INSN_R5900
) {
24998 check_insn_opc_user_only(ctx
, INSN_R5900
);
25000 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25003 check_cp0_enabled(ctx
);
25004 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25005 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25006 gen_cache_operation(ctx
, rt
, rs
, imm
);
25008 /* Treat as NOP. */
25011 if (ctx
->insn_flags
& INSN_R5900
) {
25012 /* Treat as NOP. */
25014 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25015 /* Treat as NOP. */
25019 /* Floating point (COP1). */
25024 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25028 op1
= MASK_CP1(ctx
->opcode
);
25033 check_cp1_enabled(ctx
);
25034 check_insn(ctx
, ISA_MIPS_R2
);
25040 check_cp1_enabled(ctx
);
25041 gen_cp1(ctx
, op1
, rt
, rd
);
25043 #if defined(TARGET_MIPS64)
25046 check_cp1_enabled(ctx
);
25047 check_insn(ctx
, ISA_MIPS3
);
25048 check_mips_64(ctx
);
25049 gen_cp1(ctx
, op1
, rt
, rd
);
25052 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25053 check_cp1_enabled(ctx
);
25054 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25056 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25061 check_insn(ctx
, ASE_MIPS3D
);
25062 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25063 (rt
>> 2) & 0x7, imm
<< 2);
25067 check_cp1_enabled(ctx
);
25068 check_insn(ctx
, ISA_MIPS_R6
);
25069 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25073 check_cp1_enabled(ctx
);
25074 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25076 check_insn(ctx
, ASE_MIPS3D
);
25079 check_cp1_enabled(ctx
);
25080 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25081 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25082 (rt
>> 2) & 0x7, imm
<< 2);
25089 check_cp1_enabled(ctx
);
25090 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25096 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25097 check_cp1_enabled(ctx
);
25098 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25100 case R6_OPC_CMP_AF_S
:
25101 case R6_OPC_CMP_UN_S
:
25102 case R6_OPC_CMP_EQ_S
:
25103 case R6_OPC_CMP_UEQ_S
:
25104 case R6_OPC_CMP_LT_S
:
25105 case R6_OPC_CMP_ULT_S
:
25106 case R6_OPC_CMP_LE_S
:
25107 case R6_OPC_CMP_ULE_S
:
25108 case R6_OPC_CMP_SAF_S
:
25109 case R6_OPC_CMP_SUN_S
:
25110 case R6_OPC_CMP_SEQ_S
:
25111 case R6_OPC_CMP_SEUQ_S
:
25112 case R6_OPC_CMP_SLT_S
:
25113 case R6_OPC_CMP_SULT_S
:
25114 case R6_OPC_CMP_SLE_S
:
25115 case R6_OPC_CMP_SULE_S
:
25116 case R6_OPC_CMP_OR_S
:
25117 case R6_OPC_CMP_UNE_S
:
25118 case R6_OPC_CMP_NE_S
:
25119 case R6_OPC_CMP_SOR_S
:
25120 case R6_OPC_CMP_SUNE_S
:
25121 case R6_OPC_CMP_SNE_S
:
25122 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25124 case R6_OPC_CMP_AF_D
:
25125 case R6_OPC_CMP_UN_D
:
25126 case R6_OPC_CMP_EQ_D
:
25127 case R6_OPC_CMP_UEQ_D
:
25128 case R6_OPC_CMP_LT_D
:
25129 case R6_OPC_CMP_ULT_D
:
25130 case R6_OPC_CMP_LE_D
:
25131 case R6_OPC_CMP_ULE_D
:
25132 case R6_OPC_CMP_SAF_D
:
25133 case R6_OPC_CMP_SUN_D
:
25134 case R6_OPC_CMP_SEQ_D
:
25135 case R6_OPC_CMP_SEUQ_D
:
25136 case R6_OPC_CMP_SLT_D
:
25137 case R6_OPC_CMP_SULT_D
:
25138 case R6_OPC_CMP_SLE_D
:
25139 case R6_OPC_CMP_SULE_D
:
25140 case R6_OPC_CMP_OR_D
:
25141 case R6_OPC_CMP_UNE_D
:
25142 case R6_OPC_CMP_NE_D
:
25143 case R6_OPC_CMP_SOR_D
:
25144 case R6_OPC_CMP_SUNE_D
:
25145 case R6_OPC_CMP_SNE_D
:
25146 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25149 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25150 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25155 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25162 gen_reserved_instruction(ctx
);
25167 /* Compact branches [R6] and COP2 [non-R6] */
25168 case OPC_BC
: /* OPC_LWC2 */
25169 case OPC_BALC
: /* OPC_SWC2 */
25170 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25171 /* OPC_BC, OPC_BALC */
25172 gen_compute_compact_branch(ctx
, op
, 0, 0,
25173 sextract32(ctx
->opcode
<< 2, 0, 28));
25174 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25175 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25177 /* OPC_LWC2, OPC_SWC2 */
25178 /* COP2: Not implemented. */
25179 generate_exception_err(ctx
, EXCP_CpU
, 2);
25182 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25183 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25184 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25186 /* OPC_BEQZC, OPC_BNEZC */
25187 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25188 sextract32(ctx
->opcode
<< 2, 0, 23));
25190 /* OPC_JIC, OPC_JIALC */
25191 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25193 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25194 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25196 /* OPC_LWC2, OPC_SWC2 */
25197 /* COP2: Not implemented. */
25198 generate_exception_err(ctx
, EXCP_CpU
, 2);
25202 check_insn(ctx
, ASE_LMMI
);
25203 /* Note that these instructions use different fields. */
25204 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25208 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25209 check_cp1_enabled(ctx
);
25210 op1
= MASK_CP3(ctx
->opcode
);
25214 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25220 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25221 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25224 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25225 /* Treat as NOP. */
25228 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25242 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25243 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25247 gen_reserved_instruction(ctx
);
25251 generate_exception_err(ctx
, EXCP_CpU
, 1);
25255 #if defined(TARGET_MIPS64)
25256 /* MIPS64 opcodes */
25258 if (ctx
->insn_flags
& INSN_R5900
) {
25259 check_insn_opc_user_only(ctx
, INSN_R5900
);
25266 check_insn(ctx
, ISA_MIPS3
);
25267 check_mips_64(ctx
);
25268 gen_ld(ctx
, op
, rt
, rs
, imm
);
25273 check_insn(ctx
, ISA_MIPS3
);
25274 check_mips_64(ctx
);
25275 gen_st(ctx
, op
, rt
, rs
, imm
);
25278 check_insn(ctx
, ISA_MIPS3
);
25279 if (ctx
->insn_flags
& INSN_R5900
) {
25280 check_insn_opc_user_only(ctx
, INSN_R5900
);
25282 check_mips_64(ctx
);
25283 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25285 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25286 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25287 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25288 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25291 check_insn(ctx
, ISA_MIPS3
);
25292 check_mips_64(ctx
);
25293 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25297 check_insn(ctx
, ISA_MIPS3
);
25298 check_mips_64(ctx
);
25299 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25302 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25303 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25304 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25306 MIPS_INVAL("major opcode");
25307 gen_reserved_instruction(ctx
);
25311 case OPC_DAUI
: /* OPC_JALX */
25312 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25313 #if defined(TARGET_MIPS64)
25315 check_mips_64(ctx
);
25317 generate_exception(ctx
, EXCP_RI
);
25318 } else if (rt
!= 0) {
25319 TCGv t0
= tcg_temp_new();
25320 gen_load_gpr(t0
, rs
);
25321 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25325 gen_reserved_instruction(ctx
);
25326 MIPS_INVAL("major opcode");
25330 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25331 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25332 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25335 case OPC_MDMX
: /* MMI_OPC_LQ */
25336 if (ctx
->insn_flags
& INSN_R5900
) {
25337 #if defined(TARGET_MIPS64)
25338 gen_mmi_lq(env
, ctx
);
25341 /* MDMX: Not implemented. */
25345 check_insn(ctx
, ISA_MIPS_R6
);
25346 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25348 default: /* Invalid */
25349 MIPS_INVAL("major opcode");
25355 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25357 /* make sure instructions are on a word boundary */
25358 if (ctx
->base
.pc_next
& 0x3) {
25359 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25360 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25364 /* Handle blikely not taken case */
25365 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25366 TCGLabel
*l1
= gen_new_label();
25368 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25369 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25370 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25374 /* Transition to the auto-generated decoder. */
25376 /* ISA extensions */
25377 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25381 /* ISA (from latest to oldest) */
25382 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25385 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25389 if (decode_opc_legacy(env
, ctx
)) {
25393 gen_reserved_instruction(ctx
);
25396 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25398 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25399 CPUMIPSState
*env
= cs
->env_ptr
;
25401 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25402 ctx
->saved_pc
= -1;
25403 ctx
->insn_flags
= env
->insn_flags
;
25404 ctx
->CP0_Config1
= env
->CP0_Config1
;
25405 ctx
->CP0_Config2
= env
->CP0_Config2
;
25406 ctx
->CP0_Config3
= env
->CP0_Config3
;
25407 ctx
->CP0_Config5
= env
->CP0_Config5
;
25409 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25410 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25411 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25412 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25413 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25414 ctx
->PAMask
= env
->PAMask
;
25415 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25416 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25417 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25418 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25419 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25420 /* Restore delay slot state from the tb context. */
25421 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25422 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25423 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25424 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25425 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25426 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25427 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25428 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25429 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25430 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25431 restore_cpu_state(env
, ctx
);
25432 #ifdef CONFIG_USER_ONLY
25433 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25435 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25437 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25438 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25440 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25444 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25448 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25450 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25452 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25456 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25457 const CPUBreakpoint
*bp
)
25459 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25461 save_cpu_state(ctx
, 1);
25462 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25463 gen_helper_raise_exception_debug(cpu_env
);
25465 * The address covered by the breakpoint must be included in
25466 * [tb->pc, tb->pc + tb->size) in order to for it to be
25467 * properly cleared -- thus we increment the PC here so that
25468 * the logic setting tb->size below does the right thing.
25470 ctx
->base
.pc_next
+= 4;
25474 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
25476 CPUMIPSState
*env
= cs
->env_ptr
;
25477 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25481 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
25482 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
25483 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25484 insn_bytes
= decode_nanomips_opc(env
, ctx
);
25485 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
25486 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
25488 decode_opc(env
, ctx
);
25489 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
25490 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25491 insn_bytes
= decode_micromips_opc(env
, ctx
);
25492 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
25493 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25494 insn_bytes
= decode_mips16_opc(env
, ctx
);
25496 gen_reserved_instruction(ctx
);
25497 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
25501 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
25502 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
25503 MIPS_HFLAG_FBNSLOT
))) {
25505 * Force to generate branch as there is neither delay nor
25510 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
25511 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
25513 * Force to generate branch as microMIPS R6 doesn't restrict
25514 * branches in the forbidden slot.
25520 gen_branch(ctx
, insn_bytes
);
25522 ctx
->base
.pc_next
+= insn_bytes
;
25524 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
25528 * Execute a branch and its delay slot as a single instruction.
25529 * This is what GDB expects and is consistent with what the
25530 * hardware does (e.g. if a delay slot instruction faults, the
25531 * reported PC is the PC of the branch).
25533 if (ctx
->base
.singlestep_enabled
&&
25534 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
25535 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25537 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
25538 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25542 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
25544 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25546 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
25547 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
25548 gen_helper_raise_exception_debug(cpu_env
);
25550 switch (ctx
->base
.is_jmp
) {
25552 gen_save_pc(ctx
->base
.pc_next
);
25553 tcg_gen_lookup_and_goto_ptr();
25556 case DISAS_TOO_MANY
:
25557 save_cpu_state(ctx
, 0);
25558 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
25561 tcg_gen_exit_tb(NULL
, 0);
25563 case DISAS_NORETURN
:
25566 g_assert_not_reached();
25571 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
25573 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
25574 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
25577 static const TranslatorOps mips_tr_ops
= {
25578 .init_disas_context
= mips_tr_init_disas_context
,
25579 .tb_start
= mips_tr_tb_start
,
25580 .insn_start
= mips_tr_insn_start
,
25581 .breakpoint_check
= mips_tr_breakpoint_check
,
25582 .translate_insn
= mips_tr_translate_insn
,
25583 .tb_stop
= mips_tr_tb_stop
,
25584 .disas_log
= mips_tr_disas_log
,
25587 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
25591 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
25594 void mips_tcg_init(void)
25599 for (i
= 1; i
< 32; i
++)
25600 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
25601 offsetof(CPUMIPSState
,
25604 #if defined(TARGET_MIPS64)
25605 cpu_gpr_hi
[0] = NULL
;
25607 for (unsigned i
= 1; i
< 32; i
++) {
25608 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
25610 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
25611 offsetof(CPUMIPSState
,
25612 active_tc
.gpr_hi
[i
]),
25615 #endif /* !TARGET_MIPS64 */
25616 for (i
= 0; i
< 32; i
++) {
25617 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
25619 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
25621 msa_translate_init();
25622 cpu_PC
= tcg_global_mem_new(cpu_env
,
25623 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
25624 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
25625 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
25626 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
25628 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
25629 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
25632 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
25633 offsetof(CPUMIPSState
,
25634 active_tc
.DSPControl
),
25636 bcond
= tcg_global_mem_new(cpu_env
,
25637 offsetof(CPUMIPSState
, bcond
), "bcond");
25638 btarget
= tcg_global_mem_new(cpu_env
,
25639 offsetof(CPUMIPSState
, btarget
), "btarget");
25640 hflags
= tcg_global_mem_new_i32(cpu_env
,
25641 offsetof(CPUMIPSState
, hflags
), "hflags");
25643 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
25644 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
25646 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
25647 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
25649 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
25651 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
25654 if (TARGET_LONG_BITS
== 32) {
25655 mxu_translate_init();
25659 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
25660 target_ulong
*data
)
25662 env
->active_tc
.PC
= data
[0];
25663 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
25664 env
->hflags
|= data
[1];
25665 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
25666 case MIPS_HFLAG_BR
:
25668 case MIPS_HFLAG_BC
:
25669 case MIPS_HFLAG_BL
:
25671 env
->btarget
= data
[2];