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"
34 #include "target/mips/trace.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 * const regnames_HI
[] = {
1284 "HI0", "HI1", "HI2", "HI3",
1287 static const char * const regnames_LO
[] = {
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 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5635 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5638 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5641 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5644 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
5651 t0
= tcg_temp_new();
5652 gen_load_gpr(t0
, rt
);
5655 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
5657 #if defined(TARGET_MIPS64)
5659 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
5666 #ifndef CONFIG_USER_ONLY
5667 /* CP0 (MMU and control) */
5668 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
5670 TCGv_i64 t0
= tcg_temp_new_i64();
5671 TCGv_i64 t1
= tcg_temp_new_i64();
5673 tcg_gen_ext_tl_i64(t0
, arg
);
5674 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5675 #if defined(TARGET_MIPS64)
5676 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
5678 tcg_gen_concat32_i64(t1
, t1
, t0
);
5680 tcg_gen_st_i64(t1
, cpu_env
, off
);
5681 tcg_temp_free_i64(t1
);
5682 tcg_temp_free_i64(t0
);
5685 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
5687 TCGv_i64 t0
= tcg_temp_new_i64();
5688 TCGv_i64 t1
= tcg_temp_new_i64();
5690 tcg_gen_ext_tl_i64(t0
, arg
);
5691 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5692 tcg_gen_concat32_i64(t1
, t1
, t0
);
5693 tcg_gen_st_i64(t1
, cpu_env
, off
);
5694 tcg_temp_free_i64(t1
);
5695 tcg_temp_free_i64(t0
);
5698 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5700 TCGv_i64 t0
= tcg_temp_new_i64();
5702 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5703 #if defined(TARGET_MIPS64)
5704 tcg_gen_shri_i64(t0
, t0
, 30);
5706 tcg_gen_shri_i64(t0
, t0
, 32);
5708 gen_move_low32(arg
, t0
);
5709 tcg_temp_free_i64(t0
);
5712 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5714 TCGv_i64 t0
= tcg_temp_new_i64();
5716 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5717 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5718 gen_move_low32(arg
, t0
);
5719 tcg_temp_free_i64(t0
);
5722 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
5724 TCGv_i32 t0
= tcg_temp_new_i32();
5726 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5727 tcg_gen_ext_i32_tl(arg
, t0
);
5728 tcg_temp_free_i32(t0
);
5731 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
5733 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5734 tcg_gen_ext32s_tl(arg
, arg
);
5737 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
5739 TCGv_i32 t0
= tcg_temp_new_i32();
5741 tcg_gen_trunc_tl_i32(t0
, arg
);
5742 tcg_gen_st_i32(t0
, cpu_env
, off
);
5743 tcg_temp_free_i32(t0
);
5746 #define CP0_CHECK(c) \
5749 goto cp0_unimplemented; \
5753 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5755 const char *register_name
= "invalid";
5758 case CP0_REGISTER_02
:
5761 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5762 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5763 register_name
= "EntryLo0";
5766 goto cp0_unimplemented
;
5769 case CP0_REGISTER_03
:
5771 case CP0_REG03__ENTRYLO1
:
5772 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5773 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5774 register_name
= "EntryLo1";
5777 goto cp0_unimplemented
;
5780 case CP0_REGISTER_09
:
5782 case CP0_REG09__SAAR
:
5783 CP0_CHECK(ctx
->saar
);
5784 gen_helper_mfhc0_saar(arg
, cpu_env
);
5785 register_name
= "SAAR";
5788 goto cp0_unimplemented
;
5791 case CP0_REGISTER_17
:
5793 case CP0_REG17__LLADDR
:
5794 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
5795 ctx
->CP0_LLAddr_shift
);
5796 register_name
= "LLAddr";
5798 case CP0_REG17__MAAR
:
5799 CP0_CHECK(ctx
->mrp
);
5800 gen_helper_mfhc0_maar(arg
, cpu_env
);
5801 register_name
= "MAAR";
5804 goto cp0_unimplemented
;
5807 case CP0_REGISTER_19
:
5809 case CP0_REG19__WATCHHI0
:
5810 case CP0_REG19__WATCHHI1
:
5811 case CP0_REG19__WATCHHI2
:
5812 case CP0_REG19__WATCHHI3
:
5813 case CP0_REG19__WATCHHI4
:
5814 case CP0_REG19__WATCHHI5
:
5815 case CP0_REG19__WATCHHI6
:
5816 case CP0_REG19__WATCHHI7
:
5817 /* upper 32 bits are only available when Config5MI != 0 */
5819 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
5820 register_name
= "WatchHi";
5823 goto cp0_unimplemented
;
5826 case CP0_REGISTER_28
:
5832 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5833 register_name
= "TagLo";
5836 goto cp0_unimplemented
;
5840 goto cp0_unimplemented
;
5842 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
5846 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
5847 register_name
, reg
, sel
);
5848 tcg_gen_movi_tl(arg
, 0);
5851 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5853 const char *register_name
= "invalid";
5854 uint64_t mask
= ctx
->PAMask
>> 36;
5857 case CP0_REGISTER_02
:
5860 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5861 tcg_gen_andi_tl(arg
, arg
, mask
);
5862 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5863 register_name
= "EntryLo0";
5866 goto cp0_unimplemented
;
5869 case CP0_REGISTER_03
:
5871 case CP0_REG03__ENTRYLO1
:
5872 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5873 tcg_gen_andi_tl(arg
, arg
, mask
);
5874 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5875 register_name
= "EntryLo1";
5878 goto cp0_unimplemented
;
5881 case CP0_REGISTER_09
:
5883 case CP0_REG09__SAAR
:
5884 CP0_CHECK(ctx
->saar
);
5885 gen_helper_mthc0_saar(cpu_env
, arg
);
5886 register_name
= "SAAR";
5889 goto cp0_unimplemented
;
5892 case CP0_REGISTER_17
:
5894 case CP0_REG17__LLADDR
:
5896 * LLAddr is read-only (the only exception is bit 0 if LLB is
5897 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5898 * relevant for modern MIPS cores supporting MTHC0, therefore
5899 * treating MTHC0 to LLAddr as NOP.
5901 register_name
= "LLAddr";
5903 case CP0_REG17__MAAR
:
5904 CP0_CHECK(ctx
->mrp
);
5905 gen_helper_mthc0_maar(cpu_env
, arg
);
5906 register_name
= "MAAR";
5909 goto cp0_unimplemented
;
5912 case CP0_REGISTER_19
:
5914 case CP0_REG19__WATCHHI0
:
5915 case CP0_REG19__WATCHHI1
:
5916 case CP0_REG19__WATCHHI2
:
5917 case CP0_REG19__WATCHHI3
:
5918 case CP0_REG19__WATCHHI4
:
5919 case CP0_REG19__WATCHHI5
:
5920 case CP0_REG19__WATCHHI6
:
5921 case CP0_REG19__WATCHHI7
:
5922 /* upper 32 bits are only available when Config5MI != 0 */
5924 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
5925 register_name
= "WatchHi";
5928 goto cp0_unimplemented
;
5931 case CP0_REGISTER_28
:
5937 tcg_gen_andi_tl(arg
, arg
, mask
);
5938 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5939 register_name
= "TagLo";
5942 goto cp0_unimplemented
;
5946 goto cp0_unimplemented
;
5948 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
5952 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
5953 register_name
, reg
, sel
);
5956 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5958 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
5959 tcg_gen_movi_tl(arg
, 0);
5961 tcg_gen_movi_tl(arg
, ~0);
5965 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5967 const char *register_name
= "invalid";
5970 check_insn(ctx
, ISA_MIPS_R1
);
5974 case CP0_REGISTER_00
:
5976 case CP0_REG00__INDEX
:
5977 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5978 register_name
= "Index";
5980 case CP0_REG00__MVPCONTROL
:
5981 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5982 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5983 register_name
= "MVPControl";
5985 case CP0_REG00__MVPCONF0
:
5986 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5987 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5988 register_name
= "MVPConf0";
5990 case CP0_REG00__MVPCONF1
:
5991 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5992 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5993 register_name
= "MVPConf1";
5995 case CP0_REG00__VPCONTROL
:
5997 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
5998 register_name
= "VPControl";
6001 goto cp0_unimplemented
;
6004 case CP0_REGISTER_01
:
6006 case CP0_REG01__RANDOM
:
6007 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6008 gen_helper_mfc0_random(arg
, cpu_env
);
6009 register_name
= "Random";
6011 case CP0_REG01__VPECONTROL
:
6012 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6013 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6014 register_name
= "VPEControl";
6016 case CP0_REG01__VPECONF0
:
6017 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6018 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6019 register_name
= "VPEConf0";
6021 case CP0_REG01__VPECONF1
:
6022 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6023 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6024 register_name
= "VPEConf1";
6026 case CP0_REG01__YQMASK
:
6027 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6028 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6029 register_name
= "YQMask";
6031 case CP0_REG01__VPESCHEDULE
:
6032 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6033 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6034 register_name
= "VPESchedule";
6036 case CP0_REG01__VPESCHEFBACK
:
6037 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6038 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6039 register_name
= "VPEScheFBack";
6041 case CP0_REG01__VPEOPT
:
6042 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6043 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6044 register_name
= "VPEOpt";
6047 goto cp0_unimplemented
;
6050 case CP0_REGISTER_02
:
6052 case CP0_REG02__ENTRYLO0
:
6054 TCGv_i64 tmp
= tcg_temp_new_i64();
6055 tcg_gen_ld_i64(tmp
, cpu_env
,
6056 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6057 #if defined(TARGET_MIPS64)
6059 /* Move RI/XI fields to bits 31:30 */
6060 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6061 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6064 gen_move_low32(arg
, tmp
);
6065 tcg_temp_free_i64(tmp
);
6067 register_name
= "EntryLo0";
6069 case CP0_REG02__TCSTATUS
:
6070 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6071 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6072 register_name
= "TCStatus";
6074 case CP0_REG02__TCBIND
:
6075 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6076 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6077 register_name
= "TCBind";
6079 case CP0_REG02__TCRESTART
:
6080 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6081 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6082 register_name
= "TCRestart";
6084 case CP0_REG02__TCHALT
:
6085 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6086 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6087 register_name
= "TCHalt";
6089 case CP0_REG02__TCCONTEXT
:
6090 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6091 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6092 register_name
= "TCContext";
6094 case CP0_REG02__TCSCHEDULE
:
6095 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6096 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6097 register_name
= "TCSchedule";
6099 case CP0_REG02__TCSCHEFBACK
:
6100 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6101 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6102 register_name
= "TCScheFBack";
6105 goto cp0_unimplemented
;
6108 case CP0_REGISTER_03
:
6110 case CP0_REG03__ENTRYLO1
:
6112 TCGv_i64 tmp
= tcg_temp_new_i64();
6113 tcg_gen_ld_i64(tmp
, cpu_env
,
6114 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6115 #if defined(TARGET_MIPS64)
6117 /* Move RI/XI fields to bits 31:30 */
6118 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6119 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6122 gen_move_low32(arg
, tmp
);
6123 tcg_temp_free_i64(tmp
);
6125 register_name
= "EntryLo1";
6127 case CP0_REG03__GLOBALNUM
:
6129 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6130 register_name
= "GlobalNumber";
6133 goto cp0_unimplemented
;
6136 case CP0_REGISTER_04
:
6138 case CP0_REG04__CONTEXT
:
6139 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6140 tcg_gen_ext32s_tl(arg
, arg
);
6141 register_name
= "Context";
6143 case CP0_REG04__CONTEXTCONFIG
:
6145 /* gen_helper_mfc0_contextconfig(arg); */
6146 register_name
= "ContextConfig";
6147 goto cp0_unimplemented
;
6148 case CP0_REG04__USERLOCAL
:
6149 CP0_CHECK(ctx
->ulri
);
6150 tcg_gen_ld_tl(arg
, cpu_env
,
6151 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6152 tcg_gen_ext32s_tl(arg
, arg
);
6153 register_name
= "UserLocal";
6155 case CP0_REG04__MMID
:
6157 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6158 register_name
= "MMID";
6161 goto cp0_unimplemented
;
6164 case CP0_REGISTER_05
:
6166 case CP0_REG05__PAGEMASK
:
6167 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6168 register_name
= "PageMask";
6170 case CP0_REG05__PAGEGRAIN
:
6171 check_insn(ctx
, ISA_MIPS_R2
);
6172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6173 register_name
= "PageGrain";
6175 case CP0_REG05__SEGCTL0
:
6177 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6178 tcg_gen_ext32s_tl(arg
, arg
);
6179 register_name
= "SegCtl0";
6181 case CP0_REG05__SEGCTL1
:
6183 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6184 tcg_gen_ext32s_tl(arg
, arg
);
6185 register_name
= "SegCtl1";
6187 case CP0_REG05__SEGCTL2
:
6189 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6190 tcg_gen_ext32s_tl(arg
, arg
);
6191 register_name
= "SegCtl2";
6193 case CP0_REG05__PWBASE
:
6195 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6196 register_name
= "PWBase";
6198 case CP0_REG05__PWFIELD
:
6200 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6201 register_name
= "PWField";
6203 case CP0_REG05__PWSIZE
:
6205 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6206 register_name
= "PWSize";
6209 goto cp0_unimplemented
;
6212 case CP0_REGISTER_06
:
6214 case CP0_REG06__WIRED
:
6215 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6216 register_name
= "Wired";
6218 case CP0_REG06__SRSCONF0
:
6219 check_insn(ctx
, ISA_MIPS_R2
);
6220 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6221 register_name
= "SRSConf0";
6223 case CP0_REG06__SRSCONF1
:
6224 check_insn(ctx
, ISA_MIPS_R2
);
6225 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6226 register_name
= "SRSConf1";
6228 case CP0_REG06__SRSCONF2
:
6229 check_insn(ctx
, ISA_MIPS_R2
);
6230 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6231 register_name
= "SRSConf2";
6233 case CP0_REG06__SRSCONF3
:
6234 check_insn(ctx
, ISA_MIPS_R2
);
6235 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6236 register_name
= "SRSConf3";
6238 case CP0_REG06__SRSCONF4
:
6239 check_insn(ctx
, ISA_MIPS_R2
);
6240 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6241 register_name
= "SRSConf4";
6243 case CP0_REG06__PWCTL
:
6245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6246 register_name
= "PWCtl";
6249 goto cp0_unimplemented
;
6252 case CP0_REGISTER_07
:
6254 case CP0_REG07__HWRENA
:
6255 check_insn(ctx
, ISA_MIPS_R2
);
6256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6257 register_name
= "HWREna";
6260 goto cp0_unimplemented
;
6263 case CP0_REGISTER_08
:
6265 case CP0_REG08__BADVADDR
:
6266 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6267 tcg_gen_ext32s_tl(arg
, arg
);
6268 register_name
= "BadVAddr";
6270 case CP0_REG08__BADINSTR
:
6272 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6273 register_name
= "BadInstr";
6275 case CP0_REG08__BADINSTRP
:
6277 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6278 register_name
= "BadInstrP";
6280 case CP0_REG08__BADINSTRX
:
6282 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6283 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6284 register_name
= "BadInstrX";
6287 goto cp0_unimplemented
;
6290 case CP0_REGISTER_09
:
6292 case CP0_REG09__COUNT
:
6293 /* Mark as an IO operation because we read the time. */
6294 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6297 gen_helper_mfc0_count(arg
, cpu_env
);
6299 * Break the TB to be able to take timer interrupts immediately
6300 * after reading count. DISAS_STOP isn't sufficient, we need to
6301 * ensure we break completely out of translated code.
6303 gen_save_pc(ctx
->base
.pc_next
+ 4);
6304 ctx
->base
.is_jmp
= DISAS_EXIT
;
6305 register_name
= "Count";
6307 case CP0_REG09__SAARI
:
6308 CP0_CHECK(ctx
->saar
);
6309 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6310 register_name
= "SAARI";
6312 case CP0_REG09__SAAR
:
6313 CP0_CHECK(ctx
->saar
);
6314 gen_helper_mfc0_saar(arg
, cpu_env
);
6315 register_name
= "SAAR";
6318 goto cp0_unimplemented
;
6321 case CP0_REGISTER_10
:
6323 case CP0_REG10__ENTRYHI
:
6324 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6325 tcg_gen_ext32s_tl(arg
, arg
);
6326 register_name
= "EntryHi";
6329 goto cp0_unimplemented
;
6332 case CP0_REGISTER_11
:
6334 case CP0_REG11__COMPARE
:
6335 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6336 register_name
= "Compare";
6338 /* 6,7 are implementation dependent */
6340 goto cp0_unimplemented
;
6343 case CP0_REGISTER_12
:
6345 case CP0_REG12__STATUS
:
6346 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6347 register_name
= "Status";
6349 case CP0_REG12__INTCTL
:
6350 check_insn(ctx
, ISA_MIPS_R2
);
6351 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6352 register_name
= "IntCtl";
6354 case CP0_REG12__SRSCTL
:
6355 check_insn(ctx
, ISA_MIPS_R2
);
6356 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6357 register_name
= "SRSCtl";
6359 case CP0_REG12__SRSMAP
:
6360 check_insn(ctx
, ISA_MIPS_R2
);
6361 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6362 register_name
= "SRSMap";
6365 goto cp0_unimplemented
;
6368 case CP0_REGISTER_13
:
6370 case CP0_REG13__CAUSE
:
6371 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6372 register_name
= "Cause";
6375 goto cp0_unimplemented
;
6378 case CP0_REGISTER_14
:
6380 case CP0_REG14__EPC
:
6381 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6382 tcg_gen_ext32s_tl(arg
, arg
);
6383 register_name
= "EPC";
6386 goto cp0_unimplemented
;
6389 case CP0_REGISTER_15
:
6391 case CP0_REG15__PRID
:
6392 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6393 register_name
= "PRid";
6395 case CP0_REG15__EBASE
:
6396 check_insn(ctx
, ISA_MIPS_R2
);
6397 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6398 tcg_gen_ext32s_tl(arg
, arg
);
6399 register_name
= "EBase";
6401 case CP0_REG15__CMGCRBASE
:
6402 check_insn(ctx
, ISA_MIPS_R2
);
6403 CP0_CHECK(ctx
->cmgcr
);
6404 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6405 tcg_gen_ext32s_tl(arg
, arg
);
6406 register_name
= "CMGCRBase";
6409 goto cp0_unimplemented
;
6412 case CP0_REGISTER_16
:
6414 case CP0_REG16__CONFIG
:
6415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6416 register_name
= "Config";
6418 case CP0_REG16__CONFIG1
:
6419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6420 register_name
= "Config1";
6422 case CP0_REG16__CONFIG2
:
6423 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6424 register_name
= "Config2";
6426 case CP0_REG16__CONFIG3
:
6427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6428 register_name
= "Config3";
6430 case CP0_REG16__CONFIG4
:
6431 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6432 register_name
= "Config4";
6434 case CP0_REG16__CONFIG5
:
6435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6436 register_name
= "Config5";
6438 /* 6,7 are implementation dependent */
6439 case CP0_REG16__CONFIG6
:
6440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6441 register_name
= "Config6";
6443 case CP0_REG16__CONFIG7
:
6444 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6445 register_name
= "Config7";
6448 goto cp0_unimplemented
;
6451 case CP0_REGISTER_17
:
6453 case CP0_REG17__LLADDR
:
6454 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6455 register_name
= "LLAddr";
6457 case CP0_REG17__MAAR
:
6458 CP0_CHECK(ctx
->mrp
);
6459 gen_helper_mfc0_maar(arg
, cpu_env
);
6460 register_name
= "MAAR";
6462 case CP0_REG17__MAARI
:
6463 CP0_CHECK(ctx
->mrp
);
6464 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6465 register_name
= "MAARI";
6468 goto cp0_unimplemented
;
6471 case CP0_REGISTER_18
:
6473 case CP0_REG18__WATCHLO0
:
6474 case CP0_REG18__WATCHLO1
:
6475 case CP0_REG18__WATCHLO2
:
6476 case CP0_REG18__WATCHLO3
:
6477 case CP0_REG18__WATCHLO4
:
6478 case CP0_REG18__WATCHLO5
:
6479 case CP0_REG18__WATCHLO6
:
6480 case CP0_REG18__WATCHLO7
:
6481 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6482 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6483 register_name
= "WatchLo";
6486 goto cp0_unimplemented
;
6489 case CP0_REGISTER_19
:
6491 case CP0_REG19__WATCHHI0
:
6492 case CP0_REG19__WATCHHI1
:
6493 case CP0_REG19__WATCHHI2
:
6494 case CP0_REG19__WATCHHI3
:
6495 case CP0_REG19__WATCHHI4
:
6496 case CP0_REG19__WATCHHI5
:
6497 case CP0_REG19__WATCHHI6
:
6498 case CP0_REG19__WATCHHI7
:
6499 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6500 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6501 register_name
= "WatchHi";
6504 goto cp0_unimplemented
;
6507 case CP0_REGISTER_20
:
6509 case CP0_REG20__XCONTEXT
:
6510 #if defined(TARGET_MIPS64)
6511 check_insn(ctx
, ISA_MIPS3
);
6512 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6513 tcg_gen_ext32s_tl(arg
, arg
);
6514 register_name
= "XContext";
6518 goto cp0_unimplemented
;
6521 case CP0_REGISTER_21
:
6522 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6523 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6526 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6527 register_name
= "Framemask";
6530 goto cp0_unimplemented
;
6533 case CP0_REGISTER_22
:
6534 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6535 register_name
= "'Diagnostic"; /* implementation dependent */
6537 case CP0_REGISTER_23
:
6539 case CP0_REG23__DEBUG
:
6540 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6541 register_name
= "Debug";
6543 case CP0_REG23__TRACECONTROL
:
6544 /* PDtrace support */
6545 /* gen_helper_mfc0_tracecontrol(arg); */
6546 register_name
= "TraceControl";
6547 goto cp0_unimplemented
;
6548 case CP0_REG23__TRACECONTROL2
:
6549 /* PDtrace support */
6550 /* gen_helper_mfc0_tracecontrol2(arg); */
6551 register_name
= "TraceControl2";
6552 goto cp0_unimplemented
;
6553 case CP0_REG23__USERTRACEDATA1
:
6554 /* PDtrace support */
6555 /* gen_helper_mfc0_usertracedata1(arg);*/
6556 register_name
= "UserTraceData1";
6557 goto cp0_unimplemented
;
6558 case CP0_REG23__TRACEIBPC
:
6559 /* PDtrace support */
6560 /* gen_helper_mfc0_traceibpc(arg); */
6561 register_name
= "TraceIBPC";
6562 goto cp0_unimplemented
;
6563 case CP0_REG23__TRACEDBPC
:
6564 /* PDtrace support */
6565 /* gen_helper_mfc0_tracedbpc(arg); */
6566 register_name
= "TraceDBPC";
6567 goto cp0_unimplemented
;
6569 goto cp0_unimplemented
;
6572 case CP0_REGISTER_24
:
6574 case CP0_REG24__DEPC
:
6576 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6577 tcg_gen_ext32s_tl(arg
, arg
);
6578 register_name
= "DEPC";
6581 goto cp0_unimplemented
;
6584 case CP0_REGISTER_25
:
6586 case CP0_REG25__PERFCTL0
:
6587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6588 register_name
= "Performance0";
6590 case CP0_REG25__PERFCNT0
:
6591 /* gen_helper_mfc0_performance1(arg); */
6592 register_name
= "Performance1";
6593 goto cp0_unimplemented
;
6594 case CP0_REG25__PERFCTL1
:
6595 /* gen_helper_mfc0_performance2(arg); */
6596 register_name
= "Performance2";
6597 goto cp0_unimplemented
;
6598 case CP0_REG25__PERFCNT1
:
6599 /* gen_helper_mfc0_performance3(arg); */
6600 register_name
= "Performance3";
6601 goto cp0_unimplemented
;
6602 case CP0_REG25__PERFCTL2
:
6603 /* gen_helper_mfc0_performance4(arg); */
6604 register_name
= "Performance4";
6605 goto cp0_unimplemented
;
6606 case CP0_REG25__PERFCNT2
:
6607 /* gen_helper_mfc0_performance5(arg); */
6608 register_name
= "Performance5";
6609 goto cp0_unimplemented
;
6610 case CP0_REG25__PERFCTL3
:
6611 /* gen_helper_mfc0_performance6(arg); */
6612 register_name
= "Performance6";
6613 goto cp0_unimplemented
;
6614 case CP0_REG25__PERFCNT3
:
6615 /* gen_helper_mfc0_performance7(arg); */
6616 register_name
= "Performance7";
6617 goto cp0_unimplemented
;
6619 goto cp0_unimplemented
;
6622 case CP0_REGISTER_26
:
6624 case CP0_REG26__ERRCTL
:
6625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6626 register_name
= "ErrCtl";
6629 goto cp0_unimplemented
;
6632 case CP0_REGISTER_27
:
6634 case CP0_REG27__CACHERR
:
6635 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6636 register_name
= "CacheErr";
6639 goto cp0_unimplemented
;
6642 case CP0_REGISTER_28
:
6644 case CP0_REG28__TAGLO
:
6645 case CP0_REG28__TAGLO1
:
6646 case CP0_REG28__TAGLO2
:
6647 case CP0_REG28__TAGLO3
:
6649 TCGv_i64 tmp
= tcg_temp_new_i64();
6650 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
6651 gen_move_low32(arg
, tmp
);
6652 tcg_temp_free_i64(tmp
);
6654 register_name
= "TagLo";
6656 case CP0_REG28__DATALO
:
6657 case CP0_REG28__DATALO1
:
6658 case CP0_REG28__DATALO2
:
6659 case CP0_REG28__DATALO3
:
6660 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6661 register_name
= "DataLo";
6664 goto cp0_unimplemented
;
6667 case CP0_REGISTER_29
:
6669 case CP0_REG29__TAGHI
:
6670 case CP0_REG29__TAGHI1
:
6671 case CP0_REG29__TAGHI2
:
6672 case CP0_REG29__TAGHI3
:
6673 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6674 register_name
= "TagHi";
6676 case CP0_REG29__DATAHI
:
6677 case CP0_REG29__DATAHI1
:
6678 case CP0_REG29__DATAHI2
:
6679 case CP0_REG29__DATAHI3
:
6680 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6681 register_name
= "DataHi";
6684 goto cp0_unimplemented
;
6687 case CP0_REGISTER_30
:
6689 case CP0_REG30__ERROREPC
:
6690 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6691 tcg_gen_ext32s_tl(arg
, arg
);
6692 register_name
= "ErrorEPC";
6695 goto cp0_unimplemented
;
6698 case CP0_REGISTER_31
:
6700 case CP0_REG31__DESAVE
:
6702 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6703 register_name
= "DESAVE";
6705 case CP0_REG31__KSCRATCH1
:
6706 case CP0_REG31__KSCRATCH2
:
6707 case CP0_REG31__KSCRATCH3
:
6708 case CP0_REG31__KSCRATCH4
:
6709 case CP0_REG31__KSCRATCH5
:
6710 case CP0_REG31__KSCRATCH6
:
6711 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6712 tcg_gen_ld_tl(arg
, cpu_env
,
6713 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
6714 tcg_gen_ext32s_tl(arg
, arg
);
6715 register_name
= "KScratch";
6718 goto cp0_unimplemented
;
6722 goto cp0_unimplemented
;
6724 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
6728 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
6729 register_name
, reg
, sel
);
6730 gen_mfc0_unimplemented(ctx
, arg
);
6733 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6735 const char *register_name
= "invalid";
6738 check_insn(ctx
, ISA_MIPS_R1
);
6741 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6746 case CP0_REGISTER_00
:
6748 case CP0_REG00__INDEX
:
6749 gen_helper_mtc0_index(cpu_env
, arg
);
6750 register_name
= "Index";
6752 case CP0_REG00__MVPCONTROL
:
6753 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6754 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6755 register_name
= "MVPControl";
6757 case CP0_REG00__MVPCONF0
:
6758 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6760 register_name
= "MVPConf0";
6762 case CP0_REG00__MVPCONF1
:
6763 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6765 register_name
= "MVPConf1";
6767 case CP0_REG00__VPCONTROL
:
6770 register_name
= "VPControl";
6773 goto cp0_unimplemented
;
6776 case CP0_REGISTER_01
:
6778 case CP0_REG01__RANDOM
:
6780 register_name
= "Random";
6782 case CP0_REG01__VPECONTROL
:
6783 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6784 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6785 register_name
= "VPEControl";
6787 case CP0_REG01__VPECONF0
:
6788 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6789 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6790 register_name
= "VPEConf0";
6792 case CP0_REG01__VPECONF1
:
6793 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6794 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6795 register_name
= "VPEConf1";
6797 case CP0_REG01__YQMASK
:
6798 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6799 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6800 register_name
= "YQMask";
6802 case CP0_REG01__VPESCHEDULE
:
6803 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6804 tcg_gen_st_tl(arg
, cpu_env
,
6805 offsetof(CPUMIPSState
, CP0_VPESchedule
));
6806 register_name
= "VPESchedule";
6808 case CP0_REG01__VPESCHEFBACK
:
6809 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6810 tcg_gen_st_tl(arg
, cpu_env
,
6811 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6812 register_name
= "VPEScheFBack";
6814 case CP0_REG01__VPEOPT
:
6815 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6816 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6817 register_name
= "VPEOpt";
6820 goto cp0_unimplemented
;
6823 case CP0_REGISTER_02
:
6825 case CP0_REG02__ENTRYLO0
:
6826 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6827 register_name
= "EntryLo0";
6829 case CP0_REG02__TCSTATUS
:
6830 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6831 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6832 register_name
= "TCStatus";
6834 case CP0_REG02__TCBIND
:
6835 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6836 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6837 register_name
= "TCBind";
6839 case CP0_REG02__TCRESTART
:
6840 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6841 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6842 register_name
= "TCRestart";
6844 case CP0_REG02__TCHALT
:
6845 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6846 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6847 register_name
= "TCHalt";
6849 case CP0_REG02__TCCONTEXT
:
6850 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6851 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6852 register_name
= "TCContext";
6854 case CP0_REG02__TCSCHEDULE
:
6855 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6856 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6857 register_name
= "TCSchedule";
6859 case CP0_REG02__TCSCHEFBACK
:
6860 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6861 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6862 register_name
= "TCScheFBack";
6865 goto cp0_unimplemented
;
6868 case CP0_REGISTER_03
:
6870 case CP0_REG03__ENTRYLO1
:
6871 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6872 register_name
= "EntryLo1";
6874 case CP0_REG03__GLOBALNUM
:
6877 register_name
= "GlobalNumber";
6880 goto cp0_unimplemented
;
6883 case CP0_REGISTER_04
:
6885 case CP0_REG04__CONTEXT
:
6886 gen_helper_mtc0_context(cpu_env
, arg
);
6887 register_name
= "Context";
6889 case CP0_REG04__CONTEXTCONFIG
:
6891 /* gen_helper_mtc0_contextconfig(arg); */
6892 register_name
= "ContextConfig";
6893 goto cp0_unimplemented
;
6894 case CP0_REG04__USERLOCAL
:
6895 CP0_CHECK(ctx
->ulri
);
6896 tcg_gen_st_tl(arg
, cpu_env
,
6897 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6898 register_name
= "UserLocal";
6900 case CP0_REG04__MMID
:
6902 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
6903 register_name
= "MMID";
6906 goto cp0_unimplemented
;
6909 case CP0_REGISTER_05
:
6911 case CP0_REG05__PAGEMASK
:
6912 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6913 register_name
= "PageMask";
6915 case CP0_REG05__PAGEGRAIN
:
6916 check_insn(ctx
, ISA_MIPS_R2
);
6917 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6918 register_name
= "PageGrain";
6919 ctx
->base
.is_jmp
= DISAS_STOP
;
6921 case CP0_REG05__SEGCTL0
:
6923 gen_helper_mtc0_segctl0(cpu_env
, arg
);
6924 register_name
= "SegCtl0";
6926 case CP0_REG05__SEGCTL1
:
6928 gen_helper_mtc0_segctl1(cpu_env
, arg
);
6929 register_name
= "SegCtl1";
6931 case CP0_REG05__SEGCTL2
:
6933 gen_helper_mtc0_segctl2(cpu_env
, arg
);
6934 register_name
= "SegCtl2";
6936 case CP0_REG05__PWBASE
:
6938 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6939 register_name
= "PWBase";
6941 case CP0_REG05__PWFIELD
:
6943 gen_helper_mtc0_pwfield(cpu_env
, arg
);
6944 register_name
= "PWField";
6946 case CP0_REG05__PWSIZE
:
6948 gen_helper_mtc0_pwsize(cpu_env
, arg
);
6949 register_name
= "PWSize";
6952 goto cp0_unimplemented
;
6955 case CP0_REGISTER_06
:
6957 case CP0_REG06__WIRED
:
6958 gen_helper_mtc0_wired(cpu_env
, arg
);
6959 register_name
= "Wired";
6961 case CP0_REG06__SRSCONF0
:
6962 check_insn(ctx
, ISA_MIPS_R2
);
6963 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6964 register_name
= "SRSConf0";
6966 case CP0_REG06__SRSCONF1
:
6967 check_insn(ctx
, ISA_MIPS_R2
);
6968 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6969 register_name
= "SRSConf1";
6971 case CP0_REG06__SRSCONF2
:
6972 check_insn(ctx
, ISA_MIPS_R2
);
6973 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6974 register_name
= "SRSConf2";
6976 case CP0_REG06__SRSCONF3
:
6977 check_insn(ctx
, ISA_MIPS_R2
);
6978 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6979 register_name
= "SRSConf3";
6981 case CP0_REG06__SRSCONF4
:
6982 check_insn(ctx
, ISA_MIPS_R2
);
6983 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6984 register_name
= "SRSConf4";
6986 case CP0_REG06__PWCTL
:
6988 gen_helper_mtc0_pwctl(cpu_env
, arg
);
6989 register_name
= "PWCtl";
6992 goto cp0_unimplemented
;
6995 case CP0_REGISTER_07
:
6997 case CP0_REG07__HWRENA
:
6998 check_insn(ctx
, ISA_MIPS_R2
);
6999 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7000 ctx
->base
.is_jmp
= DISAS_STOP
;
7001 register_name
= "HWREna";
7004 goto cp0_unimplemented
;
7007 case CP0_REGISTER_08
:
7009 case CP0_REG08__BADVADDR
:
7011 register_name
= "BadVAddr";
7013 case CP0_REG08__BADINSTR
:
7015 register_name
= "BadInstr";
7017 case CP0_REG08__BADINSTRP
:
7019 register_name
= "BadInstrP";
7021 case CP0_REG08__BADINSTRX
:
7023 register_name
= "BadInstrX";
7026 goto cp0_unimplemented
;
7029 case CP0_REGISTER_09
:
7031 case CP0_REG09__COUNT
:
7032 gen_helper_mtc0_count(cpu_env
, arg
);
7033 register_name
= "Count";
7035 case CP0_REG09__SAARI
:
7036 CP0_CHECK(ctx
->saar
);
7037 gen_helper_mtc0_saari(cpu_env
, arg
);
7038 register_name
= "SAARI";
7040 case CP0_REG09__SAAR
:
7041 CP0_CHECK(ctx
->saar
);
7042 gen_helper_mtc0_saar(cpu_env
, arg
);
7043 register_name
= "SAAR";
7046 goto cp0_unimplemented
;
7049 case CP0_REGISTER_10
:
7051 case CP0_REG10__ENTRYHI
:
7052 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7053 register_name
= "EntryHi";
7056 goto cp0_unimplemented
;
7059 case CP0_REGISTER_11
:
7061 case CP0_REG11__COMPARE
:
7062 gen_helper_mtc0_compare(cpu_env
, arg
);
7063 register_name
= "Compare";
7065 /* 6,7 are implementation dependent */
7067 goto cp0_unimplemented
;
7070 case CP0_REGISTER_12
:
7072 case CP0_REG12__STATUS
:
7073 save_cpu_state(ctx
, 1);
7074 gen_helper_mtc0_status(cpu_env
, arg
);
7075 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7076 gen_save_pc(ctx
->base
.pc_next
+ 4);
7077 ctx
->base
.is_jmp
= DISAS_EXIT
;
7078 register_name
= "Status";
7080 case CP0_REG12__INTCTL
:
7081 check_insn(ctx
, ISA_MIPS_R2
);
7082 gen_helper_mtc0_intctl(cpu_env
, arg
);
7083 /* Stop translation as we may have switched the execution mode */
7084 ctx
->base
.is_jmp
= DISAS_STOP
;
7085 register_name
= "IntCtl";
7087 case CP0_REG12__SRSCTL
:
7088 check_insn(ctx
, ISA_MIPS_R2
);
7089 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7090 /* Stop translation as we may have switched the execution mode */
7091 ctx
->base
.is_jmp
= DISAS_STOP
;
7092 register_name
= "SRSCtl";
7094 case CP0_REG12__SRSMAP
:
7095 check_insn(ctx
, ISA_MIPS_R2
);
7096 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7097 /* Stop translation as we may have switched the execution mode */
7098 ctx
->base
.is_jmp
= DISAS_STOP
;
7099 register_name
= "SRSMap";
7102 goto cp0_unimplemented
;
7105 case CP0_REGISTER_13
:
7107 case CP0_REG13__CAUSE
:
7108 save_cpu_state(ctx
, 1);
7109 gen_helper_mtc0_cause(cpu_env
, arg
);
7111 * Stop translation as we may have triggered an interrupt.
7112 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7113 * translated code to check for pending interrupts.
7115 gen_save_pc(ctx
->base
.pc_next
+ 4);
7116 ctx
->base
.is_jmp
= DISAS_EXIT
;
7117 register_name
= "Cause";
7120 goto cp0_unimplemented
;
7123 case CP0_REGISTER_14
:
7125 case CP0_REG14__EPC
:
7126 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7127 register_name
= "EPC";
7130 goto cp0_unimplemented
;
7133 case CP0_REGISTER_15
:
7135 case CP0_REG15__PRID
:
7137 register_name
= "PRid";
7139 case CP0_REG15__EBASE
:
7140 check_insn(ctx
, ISA_MIPS_R2
);
7141 gen_helper_mtc0_ebase(cpu_env
, arg
);
7142 register_name
= "EBase";
7145 goto cp0_unimplemented
;
7148 case CP0_REGISTER_16
:
7150 case CP0_REG16__CONFIG
:
7151 gen_helper_mtc0_config0(cpu_env
, arg
);
7152 register_name
= "Config";
7153 /* Stop translation as we may have switched the execution mode */
7154 ctx
->base
.is_jmp
= DISAS_STOP
;
7156 case CP0_REG16__CONFIG1
:
7157 /* ignored, read only */
7158 register_name
= "Config1";
7160 case CP0_REG16__CONFIG2
:
7161 gen_helper_mtc0_config2(cpu_env
, arg
);
7162 register_name
= "Config2";
7163 /* Stop translation as we may have switched the execution mode */
7164 ctx
->base
.is_jmp
= DISAS_STOP
;
7166 case CP0_REG16__CONFIG3
:
7167 gen_helper_mtc0_config3(cpu_env
, arg
);
7168 register_name
= "Config3";
7169 /* Stop translation as we may have switched the execution mode */
7170 ctx
->base
.is_jmp
= DISAS_STOP
;
7172 case CP0_REG16__CONFIG4
:
7173 gen_helper_mtc0_config4(cpu_env
, arg
);
7174 register_name
= "Config4";
7175 ctx
->base
.is_jmp
= DISAS_STOP
;
7177 case CP0_REG16__CONFIG5
:
7178 gen_helper_mtc0_config5(cpu_env
, arg
);
7179 register_name
= "Config5";
7180 /* Stop translation as we may have switched the execution mode */
7181 ctx
->base
.is_jmp
= DISAS_STOP
;
7183 /* 6,7 are implementation dependent */
7184 case CP0_REG16__CONFIG6
:
7186 register_name
= "Config6";
7188 case CP0_REG16__CONFIG7
:
7190 register_name
= "Config7";
7193 register_name
= "Invalid config selector";
7194 goto cp0_unimplemented
;
7197 case CP0_REGISTER_17
:
7199 case CP0_REG17__LLADDR
:
7200 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7201 register_name
= "LLAddr";
7203 case CP0_REG17__MAAR
:
7204 CP0_CHECK(ctx
->mrp
);
7205 gen_helper_mtc0_maar(cpu_env
, arg
);
7206 register_name
= "MAAR";
7208 case CP0_REG17__MAARI
:
7209 CP0_CHECK(ctx
->mrp
);
7210 gen_helper_mtc0_maari(cpu_env
, arg
);
7211 register_name
= "MAARI";
7214 goto cp0_unimplemented
;
7217 case CP0_REGISTER_18
:
7219 case CP0_REG18__WATCHLO0
:
7220 case CP0_REG18__WATCHLO1
:
7221 case CP0_REG18__WATCHLO2
:
7222 case CP0_REG18__WATCHLO3
:
7223 case CP0_REG18__WATCHLO4
:
7224 case CP0_REG18__WATCHLO5
:
7225 case CP0_REG18__WATCHLO6
:
7226 case CP0_REG18__WATCHLO7
:
7227 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7228 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7229 register_name
= "WatchLo";
7232 goto cp0_unimplemented
;
7235 case CP0_REGISTER_19
:
7237 case CP0_REG19__WATCHHI0
:
7238 case CP0_REG19__WATCHHI1
:
7239 case CP0_REG19__WATCHHI2
:
7240 case CP0_REG19__WATCHHI3
:
7241 case CP0_REG19__WATCHHI4
:
7242 case CP0_REG19__WATCHHI5
:
7243 case CP0_REG19__WATCHHI6
:
7244 case CP0_REG19__WATCHHI7
:
7245 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7246 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7247 register_name
= "WatchHi";
7250 goto cp0_unimplemented
;
7253 case CP0_REGISTER_20
:
7255 case CP0_REG20__XCONTEXT
:
7256 #if defined(TARGET_MIPS64)
7257 check_insn(ctx
, ISA_MIPS3
);
7258 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7259 register_name
= "XContext";
7263 goto cp0_unimplemented
;
7266 case CP0_REGISTER_21
:
7267 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7268 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7271 gen_helper_mtc0_framemask(cpu_env
, arg
);
7272 register_name
= "Framemask";
7275 goto cp0_unimplemented
;
7278 case CP0_REGISTER_22
:
7280 register_name
= "Diagnostic"; /* implementation dependent */
7282 case CP0_REGISTER_23
:
7284 case CP0_REG23__DEBUG
:
7285 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7286 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7287 gen_save_pc(ctx
->base
.pc_next
+ 4);
7288 ctx
->base
.is_jmp
= DISAS_EXIT
;
7289 register_name
= "Debug";
7291 case CP0_REG23__TRACECONTROL
:
7292 /* PDtrace support */
7293 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7294 register_name
= "TraceControl";
7295 /* Stop translation as we may have switched the execution mode */
7296 ctx
->base
.is_jmp
= DISAS_STOP
;
7297 goto cp0_unimplemented
;
7298 case CP0_REG23__TRACECONTROL2
:
7299 /* PDtrace support */
7300 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7301 register_name
= "TraceControl2";
7302 /* Stop translation as we may have switched the execution mode */
7303 ctx
->base
.is_jmp
= DISAS_STOP
;
7304 goto cp0_unimplemented
;
7305 case CP0_REG23__USERTRACEDATA1
:
7306 /* Stop translation as we may have switched the execution mode */
7307 ctx
->base
.is_jmp
= DISAS_STOP
;
7308 /* PDtrace support */
7309 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7310 register_name
= "UserTraceData";
7311 /* Stop translation as we may have switched the execution mode */
7312 ctx
->base
.is_jmp
= DISAS_STOP
;
7313 goto cp0_unimplemented
;
7314 case CP0_REG23__TRACEIBPC
:
7315 /* PDtrace support */
7316 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7317 /* Stop translation as we may have switched the execution mode */
7318 ctx
->base
.is_jmp
= DISAS_STOP
;
7319 register_name
= "TraceIBPC";
7320 goto cp0_unimplemented
;
7321 case CP0_REG23__TRACEDBPC
:
7322 /* PDtrace support */
7323 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7324 /* Stop translation as we may have switched the execution mode */
7325 ctx
->base
.is_jmp
= DISAS_STOP
;
7326 register_name
= "TraceDBPC";
7327 goto cp0_unimplemented
;
7329 goto cp0_unimplemented
;
7332 case CP0_REGISTER_24
:
7334 case CP0_REG24__DEPC
:
7336 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7337 register_name
= "DEPC";
7340 goto cp0_unimplemented
;
7343 case CP0_REGISTER_25
:
7345 case CP0_REG25__PERFCTL0
:
7346 gen_helper_mtc0_performance0(cpu_env
, arg
);
7347 register_name
= "Performance0";
7349 case CP0_REG25__PERFCNT0
:
7350 /* gen_helper_mtc0_performance1(arg); */
7351 register_name
= "Performance1";
7352 goto cp0_unimplemented
;
7353 case CP0_REG25__PERFCTL1
:
7354 /* gen_helper_mtc0_performance2(arg); */
7355 register_name
= "Performance2";
7356 goto cp0_unimplemented
;
7357 case CP0_REG25__PERFCNT1
:
7358 /* gen_helper_mtc0_performance3(arg); */
7359 register_name
= "Performance3";
7360 goto cp0_unimplemented
;
7361 case CP0_REG25__PERFCTL2
:
7362 /* gen_helper_mtc0_performance4(arg); */
7363 register_name
= "Performance4";
7364 goto cp0_unimplemented
;
7365 case CP0_REG25__PERFCNT2
:
7366 /* gen_helper_mtc0_performance5(arg); */
7367 register_name
= "Performance5";
7368 goto cp0_unimplemented
;
7369 case CP0_REG25__PERFCTL3
:
7370 /* gen_helper_mtc0_performance6(arg); */
7371 register_name
= "Performance6";
7372 goto cp0_unimplemented
;
7373 case CP0_REG25__PERFCNT3
:
7374 /* gen_helper_mtc0_performance7(arg); */
7375 register_name
= "Performance7";
7376 goto cp0_unimplemented
;
7378 goto cp0_unimplemented
;
7381 case CP0_REGISTER_26
:
7383 case CP0_REG26__ERRCTL
:
7384 gen_helper_mtc0_errctl(cpu_env
, arg
);
7385 ctx
->base
.is_jmp
= DISAS_STOP
;
7386 register_name
= "ErrCtl";
7389 goto cp0_unimplemented
;
7392 case CP0_REGISTER_27
:
7394 case CP0_REG27__CACHERR
:
7396 register_name
= "CacheErr";
7399 goto cp0_unimplemented
;
7402 case CP0_REGISTER_28
:
7404 case CP0_REG28__TAGLO
:
7405 case CP0_REG28__TAGLO1
:
7406 case CP0_REG28__TAGLO2
:
7407 case CP0_REG28__TAGLO3
:
7408 gen_helper_mtc0_taglo(cpu_env
, arg
);
7409 register_name
= "TagLo";
7411 case CP0_REG28__DATALO
:
7412 case CP0_REG28__DATALO1
:
7413 case CP0_REG28__DATALO2
:
7414 case CP0_REG28__DATALO3
:
7415 gen_helper_mtc0_datalo(cpu_env
, arg
);
7416 register_name
= "DataLo";
7419 goto cp0_unimplemented
;
7422 case CP0_REGISTER_29
:
7424 case CP0_REG29__TAGHI
:
7425 case CP0_REG29__TAGHI1
:
7426 case CP0_REG29__TAGHI2
:
7427 case CP0_REG29__TAGHI3
:
7428 gen_helper_mtc0_taghi(cpu_env
, arg
);
7429 register_name
= "TagHi";
7431 case CP0_REG29__DATAHI
:
7432 case CP0_REG29__DATAHI1
:
7433 case CP0_REG29__DATAHI2
:
7434 case CP0_REG29__DATAHI3
:
7435 gen_helper_mtc0_datahi(cpu_env
, arg
);
7436 register_name
= "DataHi";
7439 register_name
= "invalid sel";
7440 goto cp0_unimplemented
;
7443 case CP0_REGISTER_30
:
7445 case CP0_REG30__ERROREPC
:
7446 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7447 register_name
= "ErrorEPC";
7450 goto cp0_unimplemented
;
7453 case CP0_REGISTER_31
:
7455 case CP0_REG31__DESAVE
:
7457 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7458 register_name
= "DESAVE";
7460 case CP0_REG31__KSCRATCH1
:
7461 case CP0_REG31__KSCRATCH2
:
7462 case CP0_REG31__KSCRATCH3
:
7463 case CP0_REG31__KSCRATCH4
:
7464 case CP0_REG31__KSCRATCH5
:
7465 case CP0_REG31__KSCRATCH6
:
7466 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7467 tcg_gen_st_tl(arg
, cpu_env
,
7468 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7469 register_name
= "KScratch";
7472 goto cp0_unimplemented
;
7476 goto cp0_unimplemented
;
7478 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7480 /* For simplicity assume that all writes can cause interrupts. */
7481 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7483 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7484 * translated code to check for pending interrupts.
7486 gen_save_pc(ctx
->base
.pc_next
+ 4);
7487 ctx
->base
.is_jmp
= DISAS_EXIT
;
7492 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7493 register_name
, reg
, sel
);
7496 #if defined(TARGET_MIPS64)
7497 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7499 const char *register_name
= "invalid";
7502 check_insn(ctx
, ISA_MIPS_R1
);
7506 case CP0_REGISTER_00
:
7508 case CP0_REG00__INDEX
:
7509 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7510 register_name
= "Index";
7512 case CP0_REG00__MVPCONTROL
:
7513 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7514 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7515 register_name
= "MVPControl";
7517 case CP0_REG00__MVPCONF0
:
7518 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7519 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7520 register_name
= "MVPConf0";
7522 case CP0_REG00__MVPCONF1
:
7523 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7524 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7525 register_name
= "MVPConf1";
7527 case CP0_REG00__VPCONTROL
:
7529 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7530 register_name
= "VPControl";
7533 goto cp0_unimplemented
;
7536 case CP0_REGISTER_01
:
7538 case CP0_REG01__RANDOM
:
7539 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7540 gen_helper_mfc0_random(arg
, cpu_env
);
7541 register_name
= "Random";
7543 case CP0_REG01__VPECONTROL
:
7544 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7545 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7546 register_name
= "VPEControl";
7548 case CP0_REG01__VPECONF0
:
7549 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7551 register_name
= "VPEConf0";
7553 case CP0_REG01__VPECONF1
:
7554 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7555 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7556 register_name
= "VPEConf1";
7558 case CP0_REG01__YQMASK
:
7559 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7560 tcg_gen_ld_tl(arg
, cpu_env
,
7561 offsetof(CPUMIPSState
, CP0_YQMask
));
7562 register_name
= "YQMask";
7564 case CP0_REG01__VPESCHEDULE
:
7565 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7566 tcg_gen_ld_tl(arg
, cpu_env
,
7567 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7568 register_name
= "VPESchedule";
7570 case CP0_REG01__VPESCHEFBACK
:
7571 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7572 tcg_gen_ld_tl(arg
, cpu_env
,
7573 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7574 register_name
= "VPEScheFBack";
7576 case CP0_REG01__VPEOPT
:
7577 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7578 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7579 register_name
= "VPEOpt";
7582 goto cp0_unimplemented
;
7585 case CP0_REGISTER_02
:
7587 case CP0_REG02__ENTRYLO0
:
7588 tcg_gen_ld_tl(arg
, cpu_env
,
7589 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7590 register_name
= "EntryLo0";
7592 case CP0_REG02__TCSTATUS
:
7593 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7594 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7595 register_name
= "TCStatus";
7597 case CP0_REG02__TCBIND
:
7598 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7599 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7600 register_name
= "TCBind";
7602 case CP0_REG02__TCRESTART
:
7603 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7604 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7605 register_name
= "TCRestart";
7607 case CP0_REG02__TCHALT
:
7608 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7609 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7610 register_name
= "TCHalt";
7612 case CP0_REG02__TCCONTEXT
:
7613 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7614 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7615 register_name
= "TCContext";
7617 case CP0_REG02__TCSCHEDULE
:
7618 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7619 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7620 register_name
= "TCSchedule";
7622 case CP0_REG02__TCSCHEFBACK
:
7623 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7624 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7625 register_name
= "TCScheFBack";
7628 goto cp0_unimplemented
;
7631 case CP0_REGISTER_03
:
7633 case CP0_REG03__ENTRYLO1
:
7634 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7635 register_name
= "EntryLo1";
7637 case CP0_REG03__GLOBALNUM
:
7639 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7640 register_name
= "GlobalNumber";
7643 goto cp0_unimplemented
;
7646 case CP0_REGISTER_04
:
7648 case CP0_REG04__CONTEXT
:
7649 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7650 register_name
= "Context";
7652 case CP0_REG04__CONTEXTCONFIG
:
7654 /* gen_helper_dmfc0_contextconfig(arg); */
7655 register_name
= "ContextConfig";
7656 goto cp0_unimplemented
;
7657 case CP0_REG04__USERLOCAL
:
7658 CP0_CHECK(ctx
->ulri
);
7659 tcg_gen_ld_tl(arg
, cpu_env
,
7660 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7661 register_name
= "UserLocal";
7663 case CP0_REG04__MMID
:
7665 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7666 register_name
= "MMID";
7669 goto cp0_unimplemented
;
7672 case CP0_REGISTER_05
:
7674 case CP0_REG05__PAGEMASK
:
7675 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7676 register_name
= "PageMask";
7678 case CP0_REG05__PAGEGRAIN
:
7679 check_insn(ctx
, ISA_MIPS_R2
);
7680 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7681 register_name
= "PageGrain";
7683 case CP0_REG05__SEGCTL0
:
7685 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7686 register_name
= "SegCtl0";
7688 case CP0_REG05__SEGCTL1
:
7690 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7691 register_name
= "SegCtl1";
7693 case CP0_REG05__SEGCTL2
:
7695 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7696 register_name
= "SegCtl2";
7698 case CP0_REG05__PWBASE
:
7700 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
7701 register_name
= "PWBase";
7703 case CP0_REG05__PWFIELD
:
7705 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
7706 register_name
= "PWField";
7708 case CP0_REG05__PWSIZE
:
7710 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
7711 register_name
= "PWSize";
7714 goto cp0_unimplemented
;
7717 case CP0_REGISTER_06
:
7719 case CP0_REG06__WIRED
:
7720 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7721 register_name
= "Wired";
7723 case CP0_REG06__SRSCONF0
:
7724 check_insn(ctx
, ISA_MIPS_R2
);
7725 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7726 register_name
= "SRSConf0";
7728 case CP0_REG06__SRSCONF1
:
7729 check_insn(ctx
, ISA_MIPS_R2
);
7730 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7731 register_name
= "SRSConf1";
7733 case CP0_REG06__SRSCONF2
:
7734 check_insn(ctx
, ISA_MIPS_R2
);
7735 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7736 register_name
= "SRSConf2";
7738 case CP0_REG06__SRSCONF3
:
7739 check_insn(ctx
, ISA_MIPS_R2
);
7740 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7741 register_name
= "SRSConf3";
7743 case CP0_REG06__SRSCONF4
:
7744 check_insn(ctx
, ISA_MIPS_R2
);
7745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7746 register_name
= "SRSConf4";
7748 case CP0_REG06__PWCTL
:
7750 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7751 register_name
= "PWCtl";
7754 goto cp0_unimplemented
;
7757 case CP0_REGISTER_07
:
7759 case CP0_REG07__HWRENA
:
7760 check_insn(ctx
, ISA_MIPS_R2
);
7761 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7762 register_name
= "HWREna";
7765 goto cp0_unimplemented
;
7768 case CP0_REGISTER_08
:
7770 case CP0_REG08__BADVADDR
:
7771 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7772 register_name
= "BadVAddr";
7774 case CP0_REG08__BADINSTR
:
7776 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7777 register_name
= "BadInstr";
7779 case CP0_REG08__BADINSTRP
:
7781 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7782 register_name
= "BadInstrP";
7784 case CP0_REG08__BADINSTRX
:
7786 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7787 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7788 register_name
= "BadInstrX";
7791 goto cp0_unimplemented
;
7794 case CP0_REGISTER_09
:
7796 case CP0_REG09__COUNT
:
7797 /* Mark as an IO operation because we read the time. */
7798 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7801 gen_helper_mfc0_count(arg
, cpu_env
);
7803 * Break the TB to be able to take timer interrupts immediately
7804 * after reading count. DISAS_STOP isn't sufficient, we need to
7805 * ensure we break completely out of translated code.
7807 gen_save_pc(ctx
->base
.pc_next
+ 4);
7808 ctx
->base
.is_jmp
= DISAS_EXIT
;
7809 register_name
= "Count";
7811 case CP0_REG09__SAARI
:
7812 CP0_CHECK(ctx
->saar
);
7813 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7814 register_name
= "SAARI";
7816 case CP0_REG09__SAAR
:
7817 CP0_CHECK(ctx
->saar
);
7818 gen_helper_dmfc0_saar(arg
, cpu_env
);
7819 register_name
= "SAAR";
7822 goto cp0_unimplemented
;
7825 case CP0_REGISTER_10
:
7827 case CP0_REG10__ENTRYHI
:
7828 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7829 register_name
= "EntryHi";
7832 goto cp0_unimplemented
;
7835 case CP0_REGISTER_11
:
7837 case CP0_REG11__COMPARE
:
7838 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7839 register_name
= "Compare";
7841 /* 6,7 are implementation dependent */
7843 goto cp0_unimplemented
;
7846 case CP0_REGISTER_12
:
7848 case CP0_REG12__STATUS
:
7849 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7850 register_name
= "Status";
7852 case CP0_REG12__INTCTL
:
7853 check_insn(ctx
, ISA_MIPS_R2
);
7854 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7855 register_name
= "IntCtl";
7857 case CP0_REG12__SRSCTL
:
7858 check_insn(ctx
, ISA_MIPS_R2
);
7859 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7860 register_name
= "SRSCtl";
7862 case CP0_REG12__SRSMAP
:
7863 check_insn(ctx
, ISA_MIPS_R2
);
7864 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7865 register_name
= "SRSMap";
7868 goto cp0_unimplemented
;
7871 case CP0_REGISTER_13
:
7873 case CP0_REG13__CAUSE
:
7874 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7875 register_name
= "Cause";
7878 goto cp0_unimplemented
;
7881 case CP0_REGISTER_14
:
7883 case CP0_REG14__EPC
:
7884 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7885 register_name
= "EPC";
7888 goto cp0_unimplemented
;
7891 case CP0_REGISTER_15
:
7893 case CP0_REG15__PRID
:
7894 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7895 register_name
= "PRid";
7897 case CP0_REG15__EBASE
:
7898 check_insn(ctx
, ISA_MIPS_R2
);
7899 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7900 register_name
= "EBase";
7902 case CP0_REG15__CMGCRBASE
:
7903 check_insn(ctx
, ISA_MIPS_R2
);
7904 CP0_CHECK(ctx
->cmgcr
);
7905 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7906 register_name
= "CMGCRBase";
7909 goto cp0_unimplemented
;
7912 case CP0_REGISTER_16
:
7914 case CP0_REG16__CONFIG
:
7915 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7916 register_name
= "Config";
7918 case CP0_REG16__CONFIG1
:
7919 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7920 register_name
= "Config1";
7922 case CP0_REG16__CONFIG2
:
7923 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7924 register_name
= "Config2";
7926 case CP0_REG16__CONFIG3
:
7927 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7928 register_name
= "Config3";
7930 case CP0_REG16__CONFIG4
:
7931 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7932 register_name
= "Config4";
7934 case CP0_REG16__CONFIG5
:
7935 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7936 register_name
= "Config5";
7938 /* 6,7 are implementation dependent */
7939 case CP0_REG16__CONFIG6
:
7940 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7941 register_name
= "Config6";
7943 case CP0_REG16__CONFIG7
:
7944 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7945 register_name
= "Config7";
7948 goto cp0_unimplemented
;
7951 case CP0_REGISTER_17
:
7953 case CP0_REG17__LLADDR
:
7954 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
7955 register_name
= "LLAddr";
7957 case CP0_REG17__MAAR
:
7958 CP0_CHECK(ctx
->mrp
);
7959 gen_helper_dmfc0_maar(arg
, cpu_env
);
7960 register_name
= "MAAR";
7962 case CP0_REG17__MAARI
:
7963 CP0_CHECK(ctx
->mrp
);
7964 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7965 register_name
= "MAARI";
7968 goto cp0_unimplemented
;
7971 case CP0_REGISTER_18
:
7973 case CP0_REG18__WATCHLO0
:
7974 case CP0_REG18__WATCHLO1
:
7975 case CP0_REG18__WATCHLO2
:
7976 case CP0_REG18__WATCHLO3
:
7977 case CP0_REG18__WATCHLO4
:
7978 case CP0_REG18__WATCHLO5
:
7979 case CP0_REG18__WATCHLO6
:
7980 case CP0_REG18__WATCHLO7
:
7981 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7982 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
7983 register_name
= "WatchLo";
7986 goto cp0_unimplemented
;
7989 case CP0_REGISTER_19
:
7991 case CP0_REG19__WATCHHI0
:
7992 case CP0_REG19__WATCHHI1
:
7993 case CP0_REG19__WATCHHI2
:
7994 case CP0_REG19__WATCHHI3
:
7995 case CP0_REG19__WATCHHI4
:
7996 case CP0_REG19__WATCHHI5
:
7997 case CP0_REG19__WATCHHI6
:
7998 case CP0_REG19__WATCHHI7
:
7999 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8000 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8001 register_name
= "WatchHi";
8004 goto cp0_unimplemented
;
8007 case CP0_REGISTER_20
:
8009 case CP0_REG20__XCONTEXT
:
8010 check_insn(ctx
, ISA_MIPS3
);
8011 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8012 register_name
= "XContext";
8015 goto cp0_unimplemented
;
8018 case CP0_REGISTER_21
:
8019 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8020 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8023 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8024 register_name
= "Framemask";
8027 goto cp0_unimplemented
;
8030 case CP0_REGISTER_22
:
8031 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8032 register_name
= "'Diagnostic"; /* implementation dependent */
8034 case CP0_REGISTER_23
:
8036 case CP0_REG23__DEBUG
:
8037 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8038 register_name
= "Debug";
8040 case CP0_REG23__TRACECONTROL
:
8041 /* PDtrace support */
8042 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8043 register_name
= "TraceControl";
8044 goto cp0_unimplemented
;
8045 case CP0_REG23__TRACECONTROL2
:
8046 /* PDtrace support */
8047 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8048 register_name
= "TraceControl2";
8049 goto cp0_unimplemented
;
8050 case CP0_REG23__USERTRACEDATA1
:
8051 /* PDtrace support */
8052 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8053 register_name
= "UserTraceData1";
8054 goto cp0_unimplemented
;
8055 case CP0_REG23__TRACEIBPC
:
8056 /* PDtrace support */
8057 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8058 register_name
= "TraceIBPC";
8059 goto cp0_unimplemented
;
8060 case CP0_REG23__TRACEDBPC
:
8061 /* PDtrace support */
8062 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8063 register_name
= "TraceDBPC";
8064 goto cp0_unimplemented
;
8066 goto cp0_unimplemented
;
8069 case CP0_REGISTER_24
:
8071 case CP0_REG24__DEPC
:
8073 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8074 register_name
= "DEPC";
8077 goto cp0_unimplemented
;
8080 case CP0_REGISTER_25
:
8082 case CP0_REG25__PERFCTL0
:
8083 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8084 register_name
= "Performance0";
8086 case CP0_REG25__PERFCNT0
:
8087 /* gen_helper_dmfc0_performance1(arg); */
8088 register_name
= "Performance1";
8089 goto cp0_unimplemented
;
8090 case CP0_REG25__PERFCTL1
:
8091 /* gen_helper_dmfc0_performance2(arg); */
8092 register_name
= "Performance2";
8093 goto cp0_unimplemented
;
8094 case CP0_REG25__PERFCNT1
:
8095 /* gen_helper_dmfc0_performance3(arg); */
8096 register_name
= "Performance3";
8097 goto cp0_unimplemented
;
8098 case CP0_REG25__PERFCTL2
:
8099 /* gen_helper_dmfc0_performance4(arg); */
8100 register_name
= "Performance4";
8101 goto cp0_unimplemented
;
8102 case CP0_REG25__PERFCNT2
:
8103 /* gen_helper_dmfc0_performance5(arg); */
8104 register_name
= "Performance5";
8105 goto cp0_unimplemented
;
8106 case CP0_REG25__PERFCTL3
:
8107 /* gen_helper_dmfc0_performance6(arg); */
8108 register_name
= "Performance6";
8109 goto cp0_unimplemented
;
8110 case CP0_REG25__PERFCNT3
:
8111 /* gen_helper_dmfc0_performance7(arg); */
8112 register_name
= "Performance7";
8113 goto cp0_unimplemented
;
8115 goto cp0_unimplemented
;
8118 case CP0_REGISTER_26
:
8120 case CP0_REG26__ERRCTL
:
8121 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8122 register_name
= "ErrCtl";
8125 goto cp0_unimplemented
;
8128 case CP0_REGISTER_27
:
8131 case CP0_REG27__CACHERR
:
8132 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8133 register_name
= "CacheErr";
8136 goto cp0_unimplemented
;
8139 case CP0_REGISTER_28
:
8141 case CP0_REG28__TAGLO
:
8142 case CP0_REG28__TAGLO1
:
8143 case CP0_REG28__TAGLO2
:
8144 case CP0_REG28__TAGLO3
:
8145 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8146 register_name
= "TagLo";
8148 case CP0_REG28__DATALO
:
8149 case CP0_REG28__DATALO1
:
8150 case CP0_REG28__DATALO2
:
8151 case CP0_REG28__DATALO3
:
8152 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8153 register_name
= "DataLo";
8156 goto cp0_unimplemented
;
8159 case CP0_REGISTER_29
:
8161 case CP0_REG29__TAGHI
:
8162 case CP0_REG29__TAGHI1
:
8163 case CP0_REG29__TAGHI2
:
8164 case CP0_REG29__TAGHI3
:
8165 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8166 register_name
= "TagHi";
8168 case CP0_REG29__DATAHI
:
8169 case CP0_REG29__DATAHI1
:
8170 case CP0_REG29__DATAHI2
:
8171 case CP0_REG29__DATAHI3
:
8172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8173 register_name
= "DataHi";
8176 goto cp0_unimplemented
;
8179 case CP0_REGISTER_30
:
8181 case CP0_REG30__ERROREPC
:
8182 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8183 register_name
= "ErrorEPC";
8186 goto cp0_unimplemented
;
8189 case CP0_REGISTER_31
:
8191 case CP0_REG31__DESAVE
:
8193 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8194 register_name
= "DESAVE";
8196 case CP0_REG31__KSCRATCH1
:
8197 case CP0_REG31__KSCRATCH2
:
8198 case CP0_REG31__KSCRATCH3
:
8199 case CP0_REG31__KSCRATCH4
:
8200 case CP0_REG31__KSCRATCH5
:
8201 case CP0_REG31__KSCRATCH6
:
8202 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8203 tcg_gen_ld_tl(arg
, cpu_env
,
8204 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8205 register_name
= "KScratch";
8208 goto cp0_unimplemented
;
8212 goto cp0_unimplemented
;
8214 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8218 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8219 register_name
, reg
, sel
);
8220 gen_mfc0_unimplemented(ctx
, arg
);
8223 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8225 const char *register_name
= "invalid";
8228 check_insn(ctx
, ISA_MIPS_R1
);
8231 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8236 case CP0_REGISTER_00
:
8238 case CP0_REG00__INDEX
:
8239 gen_helper_mtc0_index(cpu_env
, arg
);
8240 register_name
= "Index";
8242 case CP0_REG00__MVPCONTROL
:
8243 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8244 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8245 register_name
= "MVPControl";
8247 case CP0_REG00__MVPCONF0
:
8248 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8250 register_name
= "MVPConf0";
8252 case CP0_REG00__MVPCONF1
:
8253 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8255 register_name
= "MVPConf1";
8257 case CP0_REG00__VPCONTROL
:
8260 register_name
= "VPControl";
8263 goto cp0_unimplemented
;
8266 case CP0_REGISTER_01
:
8268 case CP0_REG01__RANDOM
:
8270 register_name
= "Random";
8272 case CP0_REG01__VPECONTROL
:
8273 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8274 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8275 register_name
= "VPEControl";
8277 case CP0_REG01__VPECONF0
:
8278 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8279 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8280 register_name
= "VPEConf0";
8282 case CP0_REG01__VPECONF1
:
8283 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8284 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8285 register_name
= "VPEConf1";
8287 case CP0_REG01__YQMASK
:
8288 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8289 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8290 register_name
= "YQMask";
8292 case CP0_REG01__VPESCHEDULE
:
8293 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8294 tcg_gen_st_tl(arg
, cpu_env
,
8295 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8296 register_name
= "VPESchedule";
8298 case CP0_REG01__VPESCHEFBACK
:
8299 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8300 tcg_gen_st_tl(arg
, cpu_env
,
8301 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8302 register_name
= "VPEScheFBack";
8304 case CP0_REG01__VPEOPT
:
8305 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8306 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8307 register_name
= "VPEOpt";
8310 goto cp0_unimplemented
;
8313 case CP0_REGISTER_02
:
8315 case CP0_REG02__ENTRYLO0
:
8316 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8317 register_name
= "EntryLo0";
8319 case CP0_REG02__TCSTATUS
:
8320 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8321 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8322 register_name
= "TCStatus";
8324 case CP0_REG02__TCBIND
:
8325 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8326 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8327 register_name
= "TCBind";
8329 case CP0_REG02__TCRESTART
:
8330 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8331 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8332 register_name
= "TCRestart";
8334 case CP0_REG02__TCHALT
:
8335 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8336 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8337 register_name
= "TCHalt";
8339 case CP0_REG02__TCCONTEXT
:
8340 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8341 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8342 register_name
= "TCContext";
8344 case CP0_REG02__TCSCHEDULE
:
8345 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8346 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8347 register_name
= "TCSchedule";
8349 case CP0_REG02__TCSCHEFBACK
:
8350 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8351 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8352 register_name
= "TCScheFBack";
8355 goto cp0_unimplemented
;
8358 case CP0_REGISTER_03
:
8360 case CP0_REG03__ENTRYLO1
:
8361 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8362 register_name
= "EntryLo1";
8364 case CP0_REG03__GLOBALNUM
:
8367 register_name
= "GlobalNumber";
8370 goto cp0_unimplemented
;
8373 case CP0_REGISTER_04
:
8375 case CP0_REG04__CONTEXT
:
8376 gen_helper_mtc0_context(cpu_env
, arg
);
8377 register_name
= "Context";
8379 case CP0_REG04__CONTEXTCONFIG
:
8381 /* gen_helper_dmtc0_contextconfig(arg); */
8382 register_name
= "ContextConfig";
8383 goto cp0_unimplemented
;
8384 case CP0_REG04__USERLOCAL
:
8385 CP0_CHECK(ctx
->ulri
);
8386 tcg_gen_st_tl(arg
, cpu_env
,
8387 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8388 register_name
= "UserLocal";
8390 case CP0_REG04__MMID
:
8392 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8393 register_name
= "MMID";
8396 goto cp0_unimplemented
;
8399 case CP0_REGISTER_05
:
8401 case CP0_REG05__PAGEMASK
:
8402 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8403 register_name
= "PageMask";
8405 case CP0_REG05__PAGEGRAIN
:
8406 check_insn(ctx
, ISA_MIPS_R2
);
8407 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8408 register_name
= "PageGrain";
8410 case CP0_REG05__SEGCTL0
:
8412 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8413 register_name
= "SegCtl0";
8415 case CP0_REG05__SEGCTL1
:
8417 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8418 register_name
= "SegCtl1";
8420 case CP0_REG05__SEGCTL2
:
8422 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8423 register_name
= "SegCtl2";
8425 case CP0_REG05__PWBASE
:
8427 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8428 register_name
= "PWBase";
8430 case CP0_REG05__PWFIELD
:
8432 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8433 register_name
= "PWField";
8435 case CP0_REG05__PWSIZE
:
8437 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8438 register_name
= "PWSize";
8441 goto cp0_unimplemented
;
8444 case CP0_REGISTER_06
:
8446 case CP0_REG06__WIRED
:
8447 gen_helper_mtc0_wired(cpu_env
, arg
);
8448 register_name
= "Wired";
8450 case CP0_REG06__SRSCONF0
:
8451 check_insn(ctx
, ISA_MIPS_R2
);
8452 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8453 register_name
= "SRSConf0";
8455 case CP0_REG06__SRSCONF1
:
8456 check_insn(ctx
, ISA_MIPS_R2
);
8457 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8458 register_name
= "SRSConf1";
8460 case CP0_REG06__SRSCONF2
:
8461 check_insn(ctx
, ISA_MIPS_R2
);
8462 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8463 register_name
= "SRSConf2";
8465 case CP0_REG06__SRSCONF3
:
8466 check_insn(ctx
, ISA_MIPS_R2
);
8467 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8468 register_name
= "SRSConf3";
8470 case CP0_REG06__SRSCONF4
:
8471 check_insn(ctx
, ISA_MIPS_R2
);
8472 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8473 register_name
= "SRSConf4";
8475 case CP0_REG06__PWCTL
:
8477 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8478 register_name
= "PWCtl";
8481 goto cp0_unimplemented
;
8484 case CP0_REGISTER_07
:
8486 case CP0_REG07__HWRENA
:
8487 check_insn(ctx
, ISA_MIPS_R2
);
8488 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8489 ctx
->base
.is_jmp
= DISAS_STOP
;
8490 register_name
= "HWREna";
8493 goto cp0_unimplemented
;
8496 case CP0_REGISTER_08
:
8498 case CP0_REG08__BADVADDR
:
8500 register_name
= "BadVAddr";
8502 case CP0_REG08__BADINSTR
:
8504 register_name
= "BadInstr";
8506 case CP0_REG08__BADINSTRP
:
8508 register_name
= "BadInstrP";
8510 case CP0_REG08__BADINSTRX
:
8512 register_name
= "BadInstrX";
8515 goto cp0_unimplemented
;
8518 case CP0_REGISTER_09
:
8520 case CP0_REG09__COUNT
:
8521 gen_helper_mtc0_count(cpu_env
, arg
);
8522 register_name
= "Count";
8524 case CP0_REG09__SAARI
:
8525 CP0_CHECK(ctx
->saar
);
8526 gen_helper_mtc0_saari(cpu_env
, arg
);
8527 register_name
= "SAARI";
8529 case CP0_REG09__SAAR
:
8530 CP0_CHECK(ctx
->saar
);
8531 gen_helper_mtc0_saar(cpu_env
, arg
);
8532 register_name
= "SAAR";
8535 goto cp0_unimplemented
;
8537 /* Stop translation as we may have switched the execution mode */
8538 ctx
->base
.is_jmp
= DISAS_STOP
;
8540 case CP0_REGISTER_10
:
8542 case CP0_REG10__ENTRYHI
:
8543 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8544 register_name
= "EntryHi";
8547 goto cp0_unimplemented
;
8550 case CP0_REGISTER_11
:
8552 case CP0_REG11__COMPARE
:
8553 gen_helper_mtc0_compare(cpu_env
, arg
);
8554 register_name
= "Compare";
8556 /* 6,7 are implementation dependent */
8558 goto cp0_unimplemented
;
8560 /* Stop translation as we may have switched the execution mode */
8561 ctx
->base
.is_jmp
= DISAS_STOP
;
8563 case CP0_REGISTER_12
:
8565 case CP0_REG12__STATUS
:
8566 save_cpu_state(ctx
, 1);
8567 gen_helper_mtc0_status(cpu_env
, arg
);
8568 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8569 gen_save_pc(ctx
->base
.pc_next
+ 4);
8570 ctx
->base
.is_jmp
= DISAS_EXIT
;
8571 register_name
= "Status";
8573 case CP0_REG12__INTCTL
:
8574 check_insn(ctx
, ISA_MIPS_R2
);
8575 gen_helper_mtc0_intctl(cpu_env
, arg
);
8576 /* Stop translation as we may have switched the execution mode */
8577 ctx
->base
.is_jmp
= DISAS_STOP
;
8578 register_name
= "IntCtl";
8580 case CP0_REG12__SRSCTL
:
8581 check_insn(ctx
, ISA_MIPS_R2
);
8582 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8583 /* Stop translation as we may have switched the execution mode */
8584 ctx
->base
.is_jmp
= DISAS_STOP
;
8585 register_name
= "SRSCtl";
8587 case CP0_REG12__SRSMAP
:
8588 check_insn(ctx
, ISA_MIPS_R2
);
8589 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8590 /* Stop translation as we may have switched the execution mode */
8591 ctx
->base
.is_jmp
= DISAS_STOP
;
8592 register_name
= "SRSMap";
8595 goto cp0_unimplemented
;
8598 case CP0_REGISTER_13
:
8600 case CP0_REG13__CAUSE
:
8601 save_cpu_state(ctx
, 1);
8602 gen_helper_mtc0_cause(cpu_env
, arg
);
8604 * Stop translation as we may have triggered an interrupt.
8605 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8606 * translated code to check for pending interrupts.
8608 gen_save_pc(ctx
->base
.pc_next
+ 4);
8609 ctx
->base
.is_jmp
= DISAS_EXIT
;
8610 register_name
= "Cause";
8613 goto cp0_unimplemented
;
8616 case CP0_REGISTER_14
:
8618 case CP0_REG14__EPC
:
8619 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8620 register_name
= "EPC";
8623 goto cp0_unimplemented
;
8626 case CP0_REGISTER_15
:
8628 case CP0_REG15__PRID
:
8630 register_name
= "PRid";
8632 case CP0_REG15__EBASE
:
8633 check_insn(ctx
, ISA_MIPS_R2
);
8634 gen_helper_mtc0_ebase(cpu_env
, arg
);
8635 register_name
= "EBase";
8638 goto cp0_unimplemented
;
8641 case CP0_REGISTER_16
:
8643 case CP0_REG16__CONFIG
:
8644 gen_helper_mtc0_config0(cpu_env
, arg
);
8645 register_name
= "Config";
8646 /* Stop translation as we may have switched the execution mode */
8647 ctx
->base
.is_jmp
= DISAS_STOP
;
8649 case CP0_REG16__CONFIG1
:
8650 /* ignored, read only */
8651 register_name
= "Config1";
8653 case CP0_REG16__CONFIG2
:
8654 gen_helper_mtc0_config2(cpu_env
, arg
);
8655 register_name
= "Config2";
8656 /* Stop translation as we may have switched the execution mode */
8657 ctx
->base
.is_jmp
= DISAS_STOP
;
8659 case CP0_REG16__CONFIG3
:
8660 gen_helper_mtc0_config3(cpu_env
, arg
);
8661 register_name
= "Config3";
8662 /* Stop translation as we may have switched the execution mode */
8663 ctx
->base
.is_jmp
= DISAS_STOP
;
8665 case CP0_REG16__CONFIG4
:
8666 /* currently ignored */
8667 register_name
= "Config4";
8669 case CP0_REG16__CONFIG5
:
8670 gen_helper_mtc0_config5(cpu_env
, arg
);
8671 register_name
= "Config5";
8672 /* Stop translation as we may have switched the execution mode */
8673 ctx
->base
.is_jmp
= DISAS_STOP
;
8675 /* 6,7 are implementation dependent */
8677 register_name
= "Invalid config selector";
8678 goto cp0_unimplemented
;
8681 case CP0_REGISTER_17
:
8683 case CP0_REG17__LLADDR
:
8684 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8685 register_name
= "LLAddr";
8687 case CP0_REG17__MAAR
:
8688 CP0_CHECK(ctx
->mrp
);
8689 gen_helper_mtc0_maar(cpu_env
, arg
);
8690 register_name
= "MAAR";
8692 case CP0_REG17__MAARI
:
8693 CP0_CHECK(ctx
->mrp
);
8694 gen_helper_mtc0_maari(cpu_env
, arg
);
8695 register_name
= "MAARI";
8698 goto cp0_unimplemented
;
8701 case CP0_REGISTER_18
:
8703 case CP0_REG18__WATCHLO0
:
8704 case CP0_REG18__WATCHLO1
:
8705 case CP0_REG18__WATCHLO2
:
8706 case CP0_REG18__WATCHLO3
:
8707 case CP0_REG18__WATCHLO4
:
8708 case CP0_REG18__WATCHLO5
:
8709 case CP0_REG18__WATCHLO6
:
8710 case CP0_REG18__WATCHLO7
:
8711 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8712 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8713 register_name
= "WatchLo";
8716 goto cp0_unimplemented
;
8719 case CP0_REGISTER_19
:
8721 case CP0_REG19__WATCHHI0
:
8722 case CP0_REG19__WATCHHI1
:
8723 case CP0_REG19__WATCHHI2
:
8724 case CP0_REG19__WATCHHI3
:
8725 case CP0_REG19__WATCHHI4
:
8726 case CP0_REG19__WATCHHI5
:
8727 case CP0_REG19__WATCHHI6
:
8728 case CP0_REG19__WATCHHI7
:
8729 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8730 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8731 register_name
= "WatchHi";
8734 goto cp0_unimplemented
;
8737 case CP0_REGISTER_20
:
8739 case CP0_REG20__XCONTEXT
:
8740 check_insn(ctx
, ISA_MIPS3
);
8741 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8742 register_name
= "XContext";
8745 goto cp0_unimplemented
;
8748 case CP0_REGISTER_21
:
8749 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8750 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8753 gen_helper_mtc0_framemask(cpu_env
, arg
);
8754 register_name
= "Framemask";
8757 goto cp0_unimplemented
;
8760 case CP0_REGISTER_22
:
8762 register_name
= "Diagnostic"; /* implementation dependent */
8764 case CP0_REGISTER_23
:
8766 case CP0_REG23__DEBUG
:
8767 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8768 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8769 gen_save_pc(ctx
->base
.pc_next
+ 4);
8770 ctx
->base
.is_jmp
= DISAS_EXIT
;
8771 register_name
= "Debug";
8773 case CP0_REG23__TRACECONTROL
:
8774 /* PDtrace support */
8775 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8776 /* Stop translation as we may have switched the execution mode */
8777 ctx
->base
.is_jmp
= DISAS_STOP
;
8778 register_name
= "TraceControl";
8779 goto cp0_unimplemented
;
8780 case CP0_REG23__TRACECONTROL2
:
8781 /* PDtrace support */
8782 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8783 /* Stop translation as we may have switched the execution mode */
8784 ctx
->base
.is_jmp
= DISAS_STOP
;
8785 register_name
= "TraceControl2";
8786 goto cp0_unimplemented
;
8787 case CP0_REG23__USERTRACEDATA1
:
8788 /* PDtrace support */
8789 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8790 /* Stop translation as we may have switched the execution mode */
8791 ctx
->base
.is_jmp
= DISAS_STOP
;
8792 register_name
= "UserTraceData1";
8793 goto cp0_unimplemented
;
8794 case CP0_REG23__TRACEIBPC
:
8795 /* PDtrace support */
8796 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8797 /* Stop translation as we may have switched the execution mode */
8798 ctx
->base
.is_jmp
= DISAS_STOP
;
8799 register_name
= "TraceIBPC";
8800 goto cp0_unimplemented
;
8801 case CP0_REG23__TRACEDBPC
:
8802 /* PDtrace support */
8803 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8804 /* Stop translation as we may have switched the execution mode */
8805 ctx
->base
.is_jmp
= DISAS_STOP
;
8806 register_name
= "TraceDBPC";
8807 goto cp0_unimplemented
;
8809 goto cp0_unimplemented
;
8812 case CP0_REGISTER_24
:
8814 case CP0_REG24__DEPC
:
8816 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8817 register_name
= "DEPC";
8820 goto cp0_unimplemented
;
8823 case CP0_REGISTER_25
:
8825 case CP0_REG25__PERFCTL0
:
8826 gen_helper_mtc0_performance0(cpu_env
, arg
);
8827 register_name
= "Performance0";
8829 case CP0_REG25__PERFCNT0
:
8830 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8831 register_name
= "Performance1";
8832 goto cp0_unimplemented
;
8833 case CP0_REG25__PERFCTL1
:
8834 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8835 register_name
= "Performance2";
8836 goto cp0_unimplemented
;
8837 case CP0_REG25__PERFCNT1
:
8838 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8839 register_name
= "Performance3";
8840 goto cp0_unimplemented
;
8841 case CP0_REG25__PERFCTL2
:
8842 /* gen_helper_mtc0_performance4(cpu_env, arg); */
8843 register_name
= "Performance4";
8844 goto cp0_unimplemented
;
8845 case CP0_REG25__PERFCNT2
:
8846 /* gen_helper_mtc0_performance5(cpu_env, arg); */
8847 register_name
= "Performance5";
8848 goto cp0_unimplemented
;
8849 case CP0_REG25__PERFCTL3
:
8850 /* gen_helper_mtc0_performance6(cpu_env, arg); */
8851 register_name
= "Performance6";
8852 goto cp0_unimplemented
;
8853 case CP0_REG25__PERFCNT3
:
8854 /* gen_helper_mtc0_performance7(cpu_env, arg); */
8855 register_name
= "Performance7";
8856 goto cp0_unimplemented
;
8858 goto cp0_unimplemented
;
8861 case CP0_REGISTER_26
:
8863 case CP0_REG26__ERRCTL
:
8864 gen_helper_mtc0_errctl(cpu_env
, arg
);
8865 ctx
->base
.is_jmp
= DISAS_STOP
;
8866 register_name
= "ErrCtl";
8869 goto cp0_unimplemented
;
8872 case CP0_REGISTER_27
:
8874 case CP0_REG27__CACHERR
:
8876 register_name
= "CacheErr";
8879 goto cp0_unimplemented
;
8882 case CP0_REGISTER_28
:
8884 case CP0_REG28__TAGLO
:
8885 case CP0_REG28__TAGLO1
:
8886 case CP0_REG28__TAGLO2
:
8887 case CP0_REG28__TAGLO3
:
8888 gen_helper_mtc0_taglo(cpu_env
, arg
);
8889 register_name
= "TagLo";
8891 case CP0_REG28__DATALO
:
8892 case CP0_REG28__DATALO1
:
8893 case CP0_REG28__DATALO2
:
8894 case CP0_REG28__DATALO3
:
8895 gen_helper_mtc0_datalo(cpu_env
, arg
);
8896 register_name
= "DataLo";
8899 goto cp0_unimplemented
;
8902 case CP0_REGISTER_29
:
8904 case CP0_REG29__TAGHI
:
8905 case CP0_REG29__TAGHI1
:
8906 case CP0_REG29__TAGHI2
:
8907 case CP0_REG29__TAGHI3
:
8908 gen_helper_mtc0_taghi(cpu_env
, arg
);
8909 register_name
= "TagHi";
8911 case CP0_REG29__DATAHI
:
8912 case CP0_REG29__DATAHI1
:
8913 case CP0_REG29__DATAHI2
:
8914 case CP0_REG29__DATAHI3
:
8915 gen_helper_mtc0_datahi(cpu_env
, arg
);
8916 register_name
= "DataHi";
8919 register_name
= "invalid sel";
8920 goto cp0_unimplemented
;
8923 case CP0_REGISTER_30
:
8925 case CP0_REG30__ERROREPC
:
8926 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8927 register_name
= "ErrorEPC";
8930 goto cp0_unimplemented
;
8933 case CP0_REGISTER_31
:
8935 case CP0_REG31__DESAVE
:
8937 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8938 register_name
= "DESAVE";
8940 case CP0_REG31__KSCRATCH1
:
8941 case CP0_REG31__KSCRATCH2
:
8942 case CP0_REG31__KSCRATCH3
:
8943 case CP0_REG31__KSCRATCH4
:
8944 case CP0_REG31__KSCRATCH5
:
8945 case CP0_REG31__KSCRATCH6
:
8946 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8947 tcg_gen_st_tl(arg
, cpu_env
,
8948 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8949 register_name
= "KScratch";
8952 goto cp0_unimplemented
;
8956 goto cp0_unimplemented
;
8958 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
8960 /* For simplicity assume that all writes can cause interrupts. */
8961 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8963 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8964 * translated code to check for pending interrupts.
8966 gen_save_pc(ctx
->base
.pc_next
+ 4);
8967 ctx
->base
.is_jmp
= DISAS_EXIT
;
8972 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
8973 register_name
, reg
, sel
);
8975 #endif /* TARGET_MIPS64 */
8977 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
8978 int u
, int sel
, int h
)
8980 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
8981 TCGv t0
= tcg_temp_local_new();
8983 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
8984 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
8985 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
8986 tcg_gen_movi_tl(t0
, -1);
8987 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
8988 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
8989 tcg_gen_movi_tl(t0
, -1);
8990 } else if (u
== 0) {
8995 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
8998 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9008 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9011 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9014 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9017 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9020 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9023 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9026 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9029 gen_mfc0(ctx
, t0
, rt
, sel
);
9036 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9039 gen_mfc0(ctx
, t0
, rt
, sel
);
9046 gen_helper_mftc0_status(t0
, cpu_env
);
9049 gen_mfc0(ctx
, t0
, rt
, sel
);
9056 gen_helper_mftc0_cause(t0
, cpu_env
);
9066 gen_helper_mftc0_epc(t0
, cpu_env
);
9076 gen_helper_mftc0_ebase(t0
, cpu_env
);
9093 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9103 gen_helper_mftc0_debug(t0
, cpu_env
);
9106 gen_mfc0(ctx
, t0
, rt
, sel
);
9111 gen_mfc0(ctx
, t0
, rt
, sel
);
9115 /* GPR registers. */
9117 gen_helper_1e0i(mftgpr
, t0
, rt
);
9119 /* Auxiliary CPU registers */
9123 gen_helper_1e0i(mftlo
, t0
, 0);
9126 gen_helper_1e0i(mfthi
, t0
, 0);
9129 gen_helper_1e0i(mftacx
, t0
, 0);
9132 gen_helper_1e0i(mftlo
, t0
, 1);
9135 gen_helper_1e0i(mfthi
, t0
, 1);
9138 gen_helper_1e0i(mftacx
, t0
, 1);
9141 gen_helper_1e0i(mftlo
, t0
, 2);
9144 gen_helper_1e0i(mfthi
, t0
, 2);
9147 gen_helper_1e0i(mftacx
, t0
, 2);
9150 gen_helper_1e0i(mftlo
, t0
, 3);
9153 gen_helper_1e0i(mfthi
, t0
, 3);
9156 gen_helper_1e0i(mftacx
, t0
, 3);
9159 gen_helper_mftdsp(t0
, cpu_env
);
9165 /* Floating point (COP1). */
9167 /* XXX: For now we support only a single FPU context. */
9169 TCGv_i32 fp0
= tcg_temp_new_i32();
9171 gen_load_fpr32(ctx
, fp0
, rt
);
9172 tcg_gen_ext_i32_tl(t0
, fp0
);
9173 tcg_temp_free_i32(fp0
);
9175 TCGv_i32 fp0
= tcg_temp_new_i32();
9177 gen_load_fpr32h(ctx
, fp0
, rt
);
9178 tcg_gen_ext_i32_tl(t0
, fp0
);
9179 tcg_temp_free_i32(fp0
);
9183 /* XXX: For now we support only a single FPU context. */
9184 gen_helper_1e0i(cfc1
, t0
, rt
);
9186 /* COP2: Not implemented. */
9194 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9195 gen_store_gpr(t0
, rd
);
9201 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9202 gen_reserved_instruction(ctx
);
9205 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9206 int u
, int sel
, int h
)
9208 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9209 TCGv t0
= tcg_temp_local_new();
9211 gen_load_gpr(t0
, rt
);
9212 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9213 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9214 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9217 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9218 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9221 } else if (u
== 0) {
9226 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9229 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9239 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9242 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9245 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9248 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9251 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9254 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9257 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9260 gen_mtc0(ctx
, t0
, rd
, sel
);
9267 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9270 gen_mtc0(ctx
, t0
, rd
, sel
);
9277 gen_helper_mttc0_status(cpu_env
, t0
);
9280 gen_mtc0(ctx
, t0
, rd
, sel
);
9287 gen_helper_mttc0_cause(cpu_env
, t0
);
9297 gen_helper_mttc0_ebase(cpu_env
, t0
);
9307 gen_helper_mttc0_debug(cpu_env
, t0
);
9310 gen_mtc0(ctx
, t0
, rd
, sel
);
9315 gen_mtc0(ctx
, t0
, rd
, sel
);
9319 /* GPR registers. */
9321 gen_helper_0e1i(mttgpr
, t0
, rd
);
9323 /* Auxiliary CPU registers */
9327 gen_helper_0e1i(mttlo
, t0
, 0);
9330 gen_helper_0e1i(mtthi
, t0
, 0);
9333 gen_helper_0e1i(mttacx
, t0
, 0);
9336 gen_helper_0e1i(mttlo
, t0
, 1);
9339 gen_helper_0e1i(mtthi
, t0
, 1);
9342 gen_helper_0e1i(mttacx
, t0
, 1);
9345 gen_helper_0e1i(mttlo
, t0
, 2);
9348 gen_helper_0e1i(mtthi
, t0
, 2);
9351 gen_helper_0e1i(mttacx
, t0
, 2);
9354 gen_helper_0e1i(mttlo
, t0
, 3);
9357 gen_helper_0e1i(mtthi
, t0
, 3);
9360 gen_helper_0e1i(mttacx
, t0
, 3);
9363 gen_helper_mttdsp(cpu_env
, t0
);
9369 /* Floating point (COP1). */
9371 /* XXX: For now we support only a single FPU context. */
9373 TCGv_i32 fp0
= tcg_temp_new_i32();
9375 tcg_gen_trunc_tl_i32(fp0
, t0
);
9376 gen_store_fpr32(ctx
, fp0
, rd
);
9377 tcg_temp_free_i32(fp0
);
9379 TCGv_i32 fp0
= tcg_temp_new_i32();
9381 tcg_gen_trunc_tl_i32(fp0
, t0
);
9382 gen_store_fpr32h(ctx
, fp0
, rd
);
9383 tcg_temp_free_i32(fp0
);
9387 /* XXX: For now we support only a single FPU context. */
9389 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9391 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9392 tcg_temp_free_i32(fs_tmp
);
9394 /* Stop translation as we may have changed hflags */
9395 ctx
->base
.is_jmp
= DISAS_STOP
;
9397 /* COP2: Not implemented. */
9405 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9411 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9412 gen_reserved_instruction(ctx
);
9415 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9418 const char *opn
= "ldst";
9420 check_cp0_enabled(ctx
);
9427 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9432 TCGv t0
= tcg_temp_new();
9434 gen_load_gpr(t0
, rt
);
9435 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9440 #if defined(TARGET_MIPS64)
9442 check_insn(ctx
, ISA_MIPS3
);
9447 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9451 check_insn(ctx
, ISA_MIPS3
);
9453 TCGv t0
= tcg_temp_new();
9455 gen_load_gpr(t0
, rt
);
9456 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9468 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9474 TCGv t0
= tcg_temp_new();
9475 gen_load_gpr(t0
, rt
);
9476 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9482 check_cp0_enabled(ctx
);
9487 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9488 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9492 check_cp0_enabled(ctx
);
9493 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9494 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9499 if (!env
->tlb
->helper_tlbwi
) {
9502 gen_helper_tlbwi(cpu_env
);
9507 if (!env
->tlb
->helper_tlbinv
) {
9510 gen_helper_tlbinv(cpu_env
);
9511 } /* treat as nop if TLBINV not supported */
9516 if (!env
->tlb
->helper_tlbinvf
) {
9519 gen_helper_tlbinvf(cpu_env
);
9520 } /* treat as nop if TLBINV not supported */
9524 if (!env
->tlb
->helper_tlbwr
) {
9527 gen_helper_tlbwr(cpu_env
);
9531 if (!env
->tlb
->helper_tlbp
) {
9534 gen_helper_tlbp(cpu_env
);
9538 if (!env
->tlb
->helper_tlbr
) {
9541 gen_helper_tlbr(cpu_env
);
9543 case OPC_ERET
: /* OPC_ERETNC */
9544 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9545 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9548 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9549 if (ctx
->opcode
& (1 << bit_shift
)) {
9552 check_insn(ctx
, ISA_MIPS_R5
);
9553 gen_helper_eretnc(cpu_env
);
9557 check_insn(ctx
, ISA_MIPS2
);
9558 gen_helper_eret(cpu_env
);
9560 ctx
->base
.is_jmp
= DISAS_EXIT
;
9565 check_insn(ctx
, ISA_MIPS_R1
);
9566 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9567 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9570 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9572 gen_reserved_instruction(ctx
);
9574 gen_helper_deret(cpu_env
);
9575 ctx
->base
.is_jmp
= DISAS_EXIT
;
9580 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9581 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9582 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9585 /* If we get an exception, we want to restart at next instruction */
9586 ctx
->base
.pc_next
+= 4;
9587 save_cpu_state(ctx
, 1);
9588 ctx
->base
.pc_next
-= 4;
9589 gen_helper_wait(cpu_env
);
9590 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9595 gen_reserved_instruction(ctx
);
9598 (void)opn
; /* avoid a compiler warning */
9600 #endif /* !CONFIG_USER_ONLY */
9602 /* CP1 Branches (before delay slot) */
9603 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9604 int32_t cc
, int32_t offset
)
9606 target_ulong btarget
;
9607 TCGv_i32 t0
= tcg_temp_new_i32();
9609 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9610 gen_reserved_instruction(ctx
);
9615 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9618 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9622 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9623 tcg_gen_not_i32(t0
, t0
);
9624 tcg_gen_andi_i32(t0
, t0
, 1);
9625 tcg_gen_extu_i32_tl(bcond
, t0
);
9628 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9629 tcg_gen_not_i32(t0
, t0
);
9630 tcg_gen_andi_i32(t0
, t0
, 1);
9631 tcg_gen_extu_i32_tl(bcond
, t0
);
9634 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9635 tcg_gen_andi_i32(t0
, t0
, 1);
9636 tcg_gen_extu_i32_tl(bcond
, t0
);
9639 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9640 tcg_gen_andi_i32(t0
, t0
, 1);
9641 tcg_gen_extu_i32_tl(bcond
, t0
);
9643 ctx
->hflags
|= MIPS_HFLAG_BL
;
9647 TCGv_i32 t1
= tcg_temp_new_i32();
9648 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9649 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9650 tcg_gen_nand_i32(t0
, t0
, t1
);
9651 tcg_temp_free_i32(t1
);
9652 tcg_gen_andi_i32(t0
, t0
, 1);
9653 tcg_gen_extu_i32_tl(bcond
, t0
);
9658 TCGv_i32 t1
= tcg_temp_new_i32();
9659 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9660 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9661 tcg_gen_or_i32(t0
, t0
, t1
);
9662 tcg_temp_free_i32(t1
);
9663 tcg_gen_andi_i32(t0
, t0
, 1);
9664 tcg_gen_extu_i32_tl(bcond
, t0
);
9669 TCGv_i32 t1
= tcg_temp_new_i32();
9670 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9671 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9672 tcg_gen_and_i32(t0
, t0
, t1
);
9673 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9674 tcg_gen_and_i32(t0
, t0
, t1
);
9675 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9676 tcg_gen_nand_i32(t0
, t0
, t1
);
9677 tcg_temp_free_i32(t1
);
9678 tcg_gen_andi_i32(t0
, t0
, 1);
9679 tcg_gen_extu_i32_tl(bcond
, t0
);
9684 TCGv_i32 t1
= tcg_temp_new_i32();
9685 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9686 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9687 tcg_gen_or_i32(t0
, t0
, t1
);
9688 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9689 tcg_gen_or_i32(t0
, t0
, t1
);
9690 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9691 tcg_gen_or_i32(t0
, t0
, t1
);
9692 tcg_temp_free_i32(t1
);
9693 tcg_gen_andi_i32(t0
, t0
, 1);
9694 tcg_gen_extu_i32_tl(bcond
, t0
);
9697 ctx
->hflags
|= MIPS_HFLAG_BC
;
9700 MIPS_INVAL("cp1 cond branch");
9701 gen_reserved_instruction(ctx
);
9704 ctx
->btarget
= btarget
;
9705 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9707 tcg_temp_free_i32(t0
);
9710 /* R6 CP1 Branches */
9711 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
9712 int32_t ft
, int32_t offset
,
9715 target_ulong btarget
;
9716 TCGv_i64 t0
= tcg_temp_new_i64();
9718 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9719 #ifdef MIPS_DEBUG_DISAS
9720 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9721 "\n", ctx
->base
.pc_next
);
9723 gen_reserved_instruction(ctx
);
9727 gen_load_fpr64(ctx
, t0
, ft
);
9728 tcg_gen_andi_i64(t0
, t0
, 1);
9730 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
9734 tcg_gen_xori_i64(t0
, t0
, 1);
9735 ctx
->hflags
|= MIPS_HFLAG_BC
;
9738 /* t0 already set */
9739 ctx
->hflags
|= MIPS_HFLAG_BC
;
9742 MIPS_INVAL("cp1 cond branch");
9743 gen_reserved_instruction(ctx
);
9747 tcg_gen_trunc_i64_tl(bcond
, t0
);
9749 ctx
->btarget
= btarget
;
9751 switch (delayslot_size
) {
9753 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
9756 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9761 tcg_temp_free_i64(t0
);
9764 /* Coprocessor 1 (FPU) */
9766 #define FOP(func, fmt) (((fmt) << 21) | (func))
9769 OPC_ADD_S
= FOP(0, FMT_S
),
9770 OPC_SUB_S
= FOP(1, FMT_S
),
9771 OPC_MUL_S
= FOP(2, FMT_S
),
9772 OPC_DIV_S
= FOP(3, FMT_S
),
9773 OPC_SQRT_S
= FOP(4, FMT_S
),
9774 OPC_ABS_S
= FOP(5, FMT_S
),
9775 OPC_MOV_S
= FOP(6, FMT_S
),
9776 OPC_NEG_S
= FOP(7, FMT_S
),
9777 OPC_ROUND_L_S
= FOP(8, FMT_S
),
9778 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
9779 OPC_CEIL_L_S
= FOP(10, FMT_S
),
9780 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
9781 OPC_ROUND_W_S
= FOP(12, FMT_S
),
9782 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
9783 OPC_CEIL_W_S
= FOP(14, FMT_S
),
9784 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
9785 OPC_SEL_S
= FOP(16, FMT_S
),
9786 OPC_MOVCF_S
= FOP(17, FMT_S
),
9787 OPC_MOVZ_S
= FOP(18, FMT_S
),
9788 OPC_MOVN_S
= FOP(19, FMT_S
),
9789 OPC_SELEQZ_S
= FOP(20, FMT_S
),
9790 OPC_RECIP_S
= FOP(21, FMT_S
),
9791 OPC_RSQRT_S
= FOP(22, FMT_S
),
9792 OPC_SELNEZ_S
= FOP(23, FMT_S
),
9793 OPC_MADDF_S
= FOP(24, FMT_S
),
9794 OPC_MSUBF_S
= FOP(25, FMT_S
),
9795 OPC_RINT_S
= FOP(26, FMT_S
),
9796 OPC_CLASS_S
= FOP(27, FMT_S
),
9797 OPC_MIN_S
= FOP(28, FMT_S
),
9798 OPC_RECIP2_S
= FOP(28, FMT_S
),
9799 OPC_MINA_S
= FOP(29, FMT_S
),
9800 OPC_RECIP1_S
= FOP(29, FMT_S
),
9801 OPC_MAX_S
= FOP(30, FMT_S
),
9802 OPC_RSQRT1_S
= FOP(30, FMT_S
),
9803 OPC_MAXA_S
= FOP(31, FMT_S
),
9804 OPC_RSQRT2_S
= FOP(31, FMT_S
),
9805 OPC_CVT_D_S
= FOP(33, FMT_S
),
9806 OPC_CVT_W_S
= FOP(36, FMT_S
),
9807 OPC_CVT_L_S
= FOP(37, FMT_S
),
9808 OPC_CVT_PS_S
= FOP(38, FMT_S
),
9809 OPC_CMP_F_S
= FOP(48, FMT_S
),
9810 OPC_CMP_UN_S
= FOP(49, FMT_S
),
9811 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
9812 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
9813 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
9814 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
9815 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
9816 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
9817 OPC_CMP_SF_S
= FOP(56, FMT_S
),
9818 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
9819 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
9820 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
9821 OPC_CMP_LT_S
= FOP(60, FMT_S
),
9822 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
9823 OPC_CMP_LE_S
= FOP(62, FMT_S
),
9824 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
9826 OPC_ADD_D
= FOP(0, FMT_D
),
9827 OPC_SUB_D
= FOP(1, FMT_D
),
9828 OPC_MUL_D
= FOP(2, FMT_D
),
9829 OPC_DIV_D
= FOP(3, FMT_D
),
9830 OPC_SQRT_D
= FOP(4, FMT_D
),
9831 OPC_ABS_D
= FOP(5, FMT_D
),
9832 OPC_MOV_D
= FOP(6, FMT_D
),
9833 OPC_NEG_D
= FOP(7, FMT_D
),
9834 OPC_ROUND_L_D
= FOP(8, FMT_D
),
9835 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
9836 OPC_CEIL_L_D
= FOP(10, FMT_D
),
9837 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
9838 OPC_ROUND_W_D
= FOP(12, FMT_D
),
9839 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
9840 OPC_CEIL_W_D
= FOP(14, FMT_D
),
9841 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
9842 OPC_SEL_D
= FOP(16, FMT_D
),
9843 OPC_MOVCF_D
= FOP(17, FMT_D
),
9844 OPC_MOVZ_D
= FOP(18, FMT_D
),
9845 OPC_MOVN_D
= FOP(19, FMT_D
),
9846 OPC_SELEQZ_D
= FOP(20, FMT_D
),
9847 OPC_RECIP_D
= FOP(21, FMT_D
),
9848 OPC_RSQRT_D
= FOP(22, FMT_D
),
9849 OPC_SELNEZ_D
= FOP(23, FMT_D
),
9850 OPC_MADDF_D
= FOP(24, FMT_D
),
9851 OPC_MSUBF_D
= FOP(25, FMT_D
),
9852 OPC_RINT_D
= FOP(26, FMT_D
),
9853 OPC_CLASS_D
= FOP(27, FMT_D
),
9854 OPC_MIN_D
= FOP(28, FMT_D
),
9855 OPC_RECIP2_D
= FOP(28, FMT_D
),
9856 OPC_MINA_D
= FOP(29, FMT_D
),
9857 OPC_RECIP1_D
= FOP(29, FMT_D
),
9858 OPC_MAX_D
= FOP(30, FMT_D
),
9859 OPC_RSQRT1_D
= FOP(30, FMT_D
),
9860 OPC_MAXA_D
= FOP(31, FMT_D
),
9861 OPC_RSQRT2_D
= FOP(31, FMT_D
),
9862 OPC_CVT_S_D
= FOP(32, FMT_D
),
9863 OPC_CVT_W_D
= FOP(36, FMT_D
),
9864 OPC_CVT_L_D
= FOP(37, FMT_D
),
9865 OPC_CMP_F_D
= FOP(48, FMT_D
),
9866 OPC_CMP_UN_D
= FOP(49, FMT_D
),
9867 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
9868 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
9869 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
9870 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
9871 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
9872 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
9873 OPC_CMP_SF_D
= FOP(56, FMT_D
),
9874 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
9875 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
9876 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
9877 OPC_CMP_LT_D
= FOP(60, FMT_D
),
9878 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
9879 OPC_CMP_LE_D
= FOP(62, FMT_D
),
9880 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
9882 OPC_CVT_S_W
= FOP(32, FMT_W
),
9883 OPC_CVT_D_W
= FOP(33, FMT_W
),
9884 OPC_CVT_S_L
= FOP(32, FMT_L
),
9885 OPC_CVT_D_L
= FOP(33, FMT_L
),
9886 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
9888 OPC_ADD_PS
= FOP(0, FMT_PS
),
9889 OPC_SUB_PS
= FOP(1, FMT_PS
),
9890 OPC_MUL_PS
= FOP(2, FMT_PS
),
9891 OPC_DIV_PS
= FOP(3, FMT_PS
),
9892 OPC_ABS_PS
= FOP(5, FMT_PS
),
9893 OPC_MOV_PS
= FOP(6, FMT_PS
),
9894 OPC_NEG_PS
= FOP(7, FMT_PS
),
9895 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
9896 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
9897 OPC_MOVN_PS
= FOP(19, FMT_PS
),
9898 OPC_ADDR_PS
= FOP(24, FMT_PS
),
9899 OPC_MULR_PS
= FOP(26, FMT_PS
),
9900 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
9901 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
9902 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
9903 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
9905 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
9906 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
9907 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
9908 OPC_PLL_PS
= FOP(44, FMT_PS
),
9909 OPC_PLU_PS
= FOP(45, FMT_PS
),
9910 OPC_PUL_PS
= FOP(46, FMT_PS
),
9911 OPC_PUU_PS
= FOP(47, FMT_PS
),
9912 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
9913 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
9914 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
9915 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
9916 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
9917 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
9918 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
9919 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
9920 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
9921 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
9922 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
9923 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
9924 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
9925 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
9926 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
9927 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
9931 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
9932 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
9933 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
9934 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
9935 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
9936 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
9937 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
9938 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
9939 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
9940 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
9941 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
9942 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
9943 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
9944 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
9945 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
9946 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
9947 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
9948 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
9949 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
9950 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
9951 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
9952 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
9954 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
9955 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
9956 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
9957 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
9958 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
9959 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
9960 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
9961 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
9962 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
9963 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
9964 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
9965 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
9966 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
9967 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
9968 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
9969 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
9970 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
9971 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
9972 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
9973 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
9974 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
9975 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
9978 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
9980 TCGv t0
= tcg_temp_new();
9985 TCGv_i32 fp0
= tcg_temp_new_i32();
9987 gen_load_fpr32(ctx
, fp0
, fs
);
9988 tcg_gen_ext_i32_tl(t0
, fp0
);
9989 tcg_temp_free_i32(fp0
);
9991 gen_store_gpr(t0
, rt
);
9994 gen_load_gpr(t0
, rt
);
9996 TCGv_i32 fp0
= tcg_temp_new_i32();
9998 tcg_gen_trunc_tl_i32(fp0
, t0
);
9999 gen_store_fpr32(ctx
, fp0
, fs
);
10000 tcg_temp_free_i32(fp0
);
10004 gen_helper_1e0i(cfc1
, t0
, fs
);
10005 gen_store_gpr(t0
, rt
);
10008 gen_load_gpr(t0
, rt
);
10009 save_cpu_state(ctx
, 0);
10011 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10013 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10014 tcg_temp_free_i32(fs_tmp
);
10016 /* Stop translation as we may have changed hflags */
10017 ctx
->base
.is_jmp
= DISAS_STOP
;
10019 #if defined(TARGET_MIPS64)
10021 gen_load_fpr64(ctx
, t0
, fs
);
10022 gen_store_gpr(t0
, rt
);
10025 gen_load_gpr(t0
, rt
);
10026 gen_store_fpr64(ctx
, t0
, fs
);
10031 TCGv_i32 fp0
= tcg_temp_new_i32();
10033 gen_load_fpr32h(ctx
, fp0
, fs
);
10034 tcg_gen_ext_i32_tl(t0
, fp0
);
10035 tcg_temp_free_i32(fp0
);
10037 gen_store_gpr(t0
, rt
);
10040 gen_load_gpr(t0
, rt
);
10042 TCGv_i32 fp0
= tcg_temp_new_i32();
10044 tcg_gen_trunc_tl_i32(fp0
, t0
);
10045 gen_store_fpr32h(ctx
, fp0
, fs
);
10046 tcg_temp_free_i32(fp0
);
10050 MIPS_INVAL("cp1 move");
10051 gen_reserved_instruction(ctx
);
10059 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10066 /* Treat as NOP. */
10071 cond
= TCG_COND_EQ
;
10073 cond
= TCG_COND_NE
;
10076 l1
= gen_new_label();
10077 t0
= tcg_temp_new_i32();
10078 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10079 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10080 tcg_temp_free_i32(t0
);
10081 gen_load_gpr(cpu_gpr
[rd
], rs
);
10085 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10089 TCGv_i32 t0
= tcg_temp_new_i32();
10090 TCGLabel
*l1
= gen_new_label();
10093 cond
= TCG_COND_EQ
;
10095 cond
= TCG_COND_NE
;
10098 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10099 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10100 gen_load_fpr32(ctx
, t0
, fs
);
10101 gen_store_fpr32(ctx
, t0
, fd
);
10103 tcg_temp_free_i32(t0
);
10106 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10110 TCGv_i32 t0
= tcg_temp_new_i32();
10112 TCGLabel
*l1
= gen_new_label();
10115 cond
= TCG_COND_EQ
;
10117 cond
= TCG_COND_NE
;
10120 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10121 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10122 tcg_temp_free_i32(t0
);
10123 fp0
= tcg_temp_new_i64();
10124 gen_load_fpr64(ctx
, fp0
, fs
);
10125 gen_store_fpr64(ctx
, fp0
, fd
);
10126 tcg_temp_free_i64(fp0
);
10130 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10134 TCGv_i32 t0
= tcg_temp_new_i32();
10135 TCGLabel
*l1
= gen_new_label();
10136 TCGLabel
*l2
= gen_new_label();
10139 cond
= TCG_COND_EQ
;
10141 cond
= TCG_COND_NE
;
10144 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10145 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10146 gen_load_fpr32(ctx
, t0
, fs
);
10147 gen_store_fpr32(ctx
, t0
, fd
);
10150 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10151 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10152 gen_load_fpr32h(ctx
, t0
, fs
);
10153 gen_store_fpr32h(ctx
, t0
, fd
);
10154 tcg_temp_free_i32(t0
);
10158 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10161 TCGv_i32 t1
= tcg_const_i32(0);
10162 TCGv_i32 fp0
= tcg_temp_new_i32();
10163 TCGv_i32 fp1
= tcg_temp_new_i32();
10164 TCGv_i32 fp2
= tcg_temp_new_i32();
10165 gen_load_fpr32(ctx
, fp0
, fd
);
10166 gen_load_fpr32(ctx
, fp1
, ft
);
10167 gen_load_fpr32(ctx
, fp2
, fs
);
10171 tcg_gen_andi_i32(fp0
, fp0
, 1);
10172 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10175 tcg_gen_andi_i32(fp1
, fp1
, 1);
10176 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10179 tcg_gen_andi_i32(fp1
, fp1
, 1);
10180 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10183 MIPS_INVAL("gen_sel_s");
10184 gen_reserved_instruction(ctx
);
10188 gen_store_fpr32(ctx
, fp0
, fd
);
10189 tcg_temp_free_i32(fp2
);
10190 tcg_temp_free_i32(fp1
);
10191 tcg_temp_free_i32(fp0
);
10192 tcg_temp_free_i32(t1
);
10195 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10198 TCGv_i64 t1
= tcg_const_i64(0);
10199 TCGv_i64 fp0
= tcg_temp_new_i64();
10200 TCGv_i64 fp1
= tcg_temp_new_i64();
10201 TCGv_i64 fp2
= tcg_temp_new_i64();
10202 gen_load_fpr64(ctx
, fp0
, fd
);
10203 gen_load_fpr64(ctx
, fp1
, ft
);
10204 gen_load_fpr64(ctx
, fp2
, fs
);
10208 tcg_gen_andi_i64(fp0
, fp0
, 1);
10209 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10212 tcg_gen_andi_i64(fp1
, fp1
, 1);
10213 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10216 tcg_gen_andi_i64(fp1
, fp1
, 1);
10217 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10220 MIPS_INVAL("gen_sel_d");
10221 gen_reserved_instruction(ctx
);
10225 gen_store_fpr64(ctx
, fp0
, fd
);
10226 tcg_temp_free_i64(fp2
);
10227 tcg_temp_free_i64(fp1
);
10228 tcg_temp_free_i64(fp0
);
10229 tcg_temp_free_i64(t1
);
10232 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10233 int ft
, int fs
, int fd
, int cc
)
10235 uint32_t func
= ctx
->opcode
& 0x3f;
10239 TCGv_i32 fp0
= tcg_temp_new_i32();
10240 TCGv_i32 fp1
= tcg_temp_new_i32();
10242 gen_load_fpr32(ctx
, fp0
, fs
);
10243 gen_load_fpr32(ctx
, fp1
, ft
);
10244 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10245 tcg_temp_free_i32(fp1
);
10246 gen_store_fpr32(ctx
, fp0
, fd
);
10247 tcg_temp_free_i32(fp0
);
10252 TCGv_i32 fp0
= tcg_temp_new_i32();
10253 TCGv_i32 fp1
= tcg_temp_new_i32();
10255 gen_load_fpr32(ctx
, fp0
, fs
);
10256 gen_load_fpr32(ctx
, fp1
, ft
);
10257 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10258 tcg_temp_free_i32(fp1
);
10259 gen_store_fpr32(ctx
, fp0
, fd
);
10260 tcg_temp_free_i32(fp0
);
10265 TCGv_i32 fp0
= tcg_temp_new_i32();
10266 TCGv_i32 fp1
= tcg_temp_new_i32();
10268 gen_load_fpr32(ctx
, fp0
, fs
);
10269 gen_load_fpr32(ctx
, fp1
, ft
);
10270 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10271 tcg_temp_free_i32(fp1
);
10272 gen_store_fpr32(ctx
, fp0
, fd
);
10273 tcg_temp_free_i32(fp0
);
10278 TCGv_i32 fp0
= tcg_temp_new_i32();
10279 TCGv_i32 fp1
= tcg_temp_new_i32();
10281 gen_load_fpr32(ctx
, fp0
, fs
);
10282 gen_load_fpr32(ctx
, fp1
, ft
);
10283 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10284 tcg_temp_free_i32(fp1
);
10285 gen_store_fpr32(ctx
, fp0
, fd
);
10286 tcg_temp_free_i32(fp0
);
10291 TCGv_i32 fp0
= tcg_temp_new_i32();
10293 gen_load_fpr32(ctx
, fp0
, fs
);
10294 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10295 gen_store_fpr32(ctx
, fp0
, fd
);
10296 tcg_temp_free_i32(fp0
);
10301 TCGv_i32 fp0
= tcg_temp_new_i32();
10303 gen_load_fpr32(ctx
, fp0
, fs
);
10304 if (ctx
->abs2008
) {
10305 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10307 gen_helper_float_abs_s(fp0
, fp0
);
10309 gen_store_fpr32(ctx
, fp0
, fd
);
10310 tcg_temp_free_i32(fp0
);
10315 TCGv_i32 fp0
= tcg_temp_new_i32();
10317 gen_load_fpr32(ctx
, fp0
, fs
);
10318 gen_store_fpr32(ctx
, fp0
, fd
);
10319 tcg_temp_free_i32(fp0
);
10324 TCGv_i32 fp0
= tcg_temp_new_i32();
10326 gen_load_fpr32(ctx
, fp0
, fs
);
10327 if (ctx
->abs2008
) {
10328 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10330 gen_helper_float_chs_s(fp0
, fp0
);
10332 gen_store_fpr32(ctx
, fp0
, fd
);
10333 tcg_temp_free_i32(fp0
);
10336 case OPC_ROUND_L_S
:
10337 check_cp1_64bitmode(ctx
);
10339 TCGv_i32 fp32
= tcg_temp_new_i32();
10340 TCGv_i64 fp64
= tcg_temp_new_i64();
10342 gen_load_fpr32(ctx
, fp32
, fs
);
10343 if (ctx
->nan2008
) {
10344 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10346 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10348 tcg_temp_free_i32(fp32
);
10349 gen_store_fpr64(ctx
, fp64
, fd
);
10350 tcg_temp_free_i64(fp64
);
10353 case OPC_TRUNC_L_S
:
10354 check_cp1_64bitmode(ctx
);
10356 TCGv_i32 fp32
= tcg_temp_new_i32();
10357 TCGv_i64 fp64
= tcg_temp_new_i64();
10359 gen_load_fpr32(ctx
, fp32
, fs
);
10360 if (ctx
->nan2008
) {
10361 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10363 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10365 tcg_temp_free_i32(fp32
);
10366 gen_store_fpr64(ctx
, fp64
, fd
);
10367 tcg_temp_free_i64(fp64
);
10371 check_cp1_64bitmode(ctx
);
10373 TCGv_i32 fp32
= tcg_temp_new_i32();
10374 TCGv_i64 fp64
= tcg_temp_new_i64();
10376 gen_load_fpr32(ctx
, fp32
, fs
);
10377 if (ctx
->nan2008
) {
10378 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10380 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10382 tcg_temp_free_i32(fp32
);
10383 gen_store_fpr64(ctx
, fp64
, fd
);
10384 tcg_temp_free_i64(fp64
);
10387 case OPC_FLOOR_L_S
:
10388 check_cp1_64bitmode(ctx
);
10390 TCGv_i32 fp32
= tcg_temp_new_i32();
10391 TCGv_i64 fp64
= tcg_temp_new_i64();
10393 gen_load_fpr32(ctx
, fp32
, fs
);
10394 if (ctx
->nan2008
) {
10395 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10397 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10399 tcg_temp_free_i32(fp32
);
10400 gen_store_fpr64(ctx
, fp64
, fd
);
10401 tcg_temp_free_i64(fp64
);
10404 case OPC_ROUND_W_S
:
10406 TCGv_i32 fp0
= tcg_temp_new_i32();
10408 gen_load_fpr32(ctx
, fp0
, fs
);
10409 if (ctx
->nan2008
) {
10410 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10412 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10414 gen_store_fpr32(ctx
, fp0
, fd
);
10415 tcg_temp_free_i32(fp0
);
10418 case OPC_TRUNC_W_S
:
10420 TCGv_i32 fp0
= tcg_temp_new_i32();
10422 gen_load_fpr32(ctx
, fp0
, fs
);
10423 if (ctx
->nan2008
) {
10424 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10426 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10428 gen_store_fpr32(ctx
, fp0
, fd
);
10429 tcg_temp_free_i32(fp0
);
10434 TCGv_i32 fp0
= tcg_temp_new_i32();
10436 gen_load_fpr32(ctx
, fp0
, fs
);
10437 if (ctx
->nan2008
) {
10438 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10440 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10442 gen_store_fpr32(ctx
, fp0
, fd
);
10443 tcg_temp_free_i32(fp0
);
10446 case OPC_FLOOR_W_S
:
10448 TCGv_i32 fp0
= tcg_temp_new_i32();
10450 gen_load_fpr32(ctx
, fp0
, fs
);
10451 if (ctx
->nan2008
) {
10452 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10454 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10456 gen_store_fpr32(ctx
, fp0
, fd
);
10457 tcg_temp_free_i32(fp0
);
10461 check_insn(ctx
, ISA_MIPS_R6
);
10462 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10465 check_insn(ctx
, ISA_MIPS_R6
);
10466 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10469 check_insn(ctx
, ISA_MIPS_R6
);
10470 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10473 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10474 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10477 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10479 TCGLabel
*l1
= gen_new_label();
10483 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10485 fp0
= tcg_temp_new_i32();
10486 gen_load_fpr32(ctx
, fp0
, fs
);
10487 gen_store_fpr32(ctx
, fp0
, fd
);
10488 tcg_temp_free_i32(fp0
);
10493 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10495 TCGLabel
*l1
= gen_new_label();
10499 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10500 fp0
= tcg_temp_new_i32();
10501 gen_load_fpr32(ctx
, fp0
, fs
);
10502 gen_store_fpr32(ctx
, fp0
, fd
);
10503 tcg_temp_free_i32(fp0
);
10510 TCGv_i32 fp0
= tcg_temp_new_i32();
10512 gen_load_fpr32(ctx
, fp0
, fs
);
10513 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10514 gen_store_fpr32(ctx
, fp0
, fd
);
10515 tcg_temp_free_i32(fp0
);
10520 TCGv_i32 fp0
= tcg_temp_new_i32();
10522 gen_load_fpr32(ctx
, fp0
, fs
);
10523 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10524 gen_store_fpr32(ctx
, fp0
, fd
);
10525 tcg_temp_free_i32(fp0
);
10529 check_insn(ctx
, ISA_MIPS_R6
);
10531 TCGv_i32 fp0
= tcg_temp_new_i32();
10532 TCGv_i32 fp1
= tcg_temp_new_i32();
10533 TCGv_i32 fp2
= tcg_temp_new_i32();
10534 gen_load_fpr32(ctx
, fp0
, fs
);
10535 gen_load_fpr32(ctx
, fp1
, ft
);
10536 gen_load_fpr32(ctx
, fp2
, fd
);
10537 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10538 gen_store_fpr32(ctx
, fp2
, fd
);
10539 tcg_temp_free_i32(fp2
);
10540 tcg_temp_free_i32(fp1
);
10541 tcg_temp_free_i32(fp0
);
10545 check_insn(ctx
, ISA_MIPS_R6
);
10547 TCGv_i32 fp0
= tcg_temp_new_i32();
10548 TCGv_i32 fp1
= tcg_temp_new_i32();
10549 TCGv_i32 fp2
= tcg_temp_new_i32();
10550 gen_load_fpr32(ctx
, fp0
, fs
);
10551 gen_load_fpr32(ctx
, fp1
, ft
);
10552 gen_load_fpr32(ctx
, fp2
, fd
);
10553 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10554 gen_store_fpr32(ctx
, fp2
, fd
);
10555 tcg_temp_free_i32(fp2
);
10556 tcg_temp_free_i32(fp1
);
10557 tcg_temp_free_i32(fp0
);
10561 check_insn(ctx
, ISA_MIPS_R6
);
10563 TCGv_i32 fp0
= tcg_temp_new_i32();
10564 gen_load_fpr32(ctx
, fp0
, fs
);
10565 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10566 gen_store_fpr32(ctx
, fp0
, fd
);
10567 tcg_temp_free_i32(fp0
);
10571 check_insn(ctx
, ISA_MIPS_R6
);
10573 TCGv_i32 fp0
= tcg_temp_new_i32();
10574 gen_load_fpr32(ctx
, fp0
, fs
);
10575 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10576 gen_store_fpr32(ctx
, fp0
, fd
);
10577 tcg_temp_free_i32(fp0
);
10580 case OPC_MIN_S
: /* OPC_RECIP2_S */
10581 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10583 TCGv_i32 fp0
= tcg_temp_new_i32();
10584 TCGv_i32 fp1
= tcg_temp_new_i32();
10585 TCGv_i32 fp2
= tcg_temp_new_i32();
10586 gen_load_fpr32(ctx
, fp0
, fs
);
10587 gen_load_fpr32(ctx
, fp1
, ft
);
10588 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10589 gen_store_fpr32(ctx
, fp2
, fd
);
10590 tcg_temp_free_i32(fp2
);
10591 tcg_temp_free_i32(fp1
);
10592 tcg_temp_free_i32(fp0
);
10595 check_cp1_64bitmode(ctx
);
10597 TCGv_i32 fp0
= tcg_temp_new_i32();
10598 TCGv_i32 fp1
= tcg_temp_new_i32();
10600 gen_load_fpr32(ctx
, fp0
, fs
);
10601 gen_load_fpr32(ctx
, fp1
, ft
);
10602 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10603 tcg_temp_free_i32(fp1
);
10604 gen_store_fpr32(ctx
, fp0
, fd
);
10605 tcg_temp_free_i32(fp0
);
10609 case OPC_MINA_S
: /* OPC_RECIP1_S */
10610 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10612 TCGv_i32 fp0
= tcg_temp_new_i32();
10613 TCGv_i32 fp1
= tcg_temp_new_i32();
10614 TCGv_i32 fp2
= tcg_temp_new_i32();
10615 gen_load_fpr32(ctx
, fp0
, fs
);
10616 gen_load_fpr32(ctx
, fp1
, ft
);
10617 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10618 gen_store_fpr32(ctx
, fp2
, fd
);
10619 tcg_temp_free_i32(fp2
);
10620 tcg_temp_free_i32(fp1
);
10621 tcg_temp_free_i32(fp0
);
10624 check_cp1_64bitmode(ctx
);
10626 TCGv_i32 fp0
= tcg_temp_new_i32();
10628 gen_load_fpr32(ctx
, fp0
, fs
);
10629 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10630 gen_store_fpr32(ctx
, fp0
, fd
);
10631 tcg_temp_free_i32(fp0
);
10635 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10636 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10638 TCGv_i32 fp0
= tcg_temp_new_i32();
10639 TCGv_i32 fp1
= tcg_temp_new_i32();
10640 gen_load_fpr32(ctx
, fp0
, fs
);
10641 gen_load_fpr32(ctx
, fp1
, ft
);
10642 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10643 gen_store_fpr32(ctx
, fp1
, fd
);
10644 tcg_temp_free_i32(fp1
);
10645 tcg_temp_free_i32(fp0
);
10648 check_cp1_64bitmode(ctx
);
10650 TCGv_i32 fp0
= tcg_temp_new_i32();
10652 gen_load_fpr32(ctx
, fp0
, fs
);
10653 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
10654 gen_store_fpr32(ctx
, fp0
, fd
);
10655 tcg_temp_free_i32(fp0
);
10659 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
10660 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10662 TCGv_i32 fp0
= tcg_temp_new_i32();
10663 TCGv_i32 fp1
= tcg_temp_new_i32();
10664 gen_load_fpr32(ctx
, fp0
, fs
);
10665 gen_load_fpr32(ctx
, fp1
, ft
);
10666 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
10667 gen_store_fpr32(ctx
, fp1
, fd
);
10668 tcg_temp_free_i32(fp1
);
10669 tcg_temp_free_i32(fp0
);
10672 check_cp1_64bitmode(ctx
);
10674 TCGv_i32 fp0
= tcg_temp_new_i32();
10675 TCGv_i32 fp1
= tcg_temp_new_i32();
10677 gen_load_fpr32(ctx
, fp0
, fs
);
10678 gen_load_fpr32(ctx
, fp1
, ft
);
10679 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
10680 tcg_temp_free_i32(fp1
);
10681 gen_store_fpr32(ctx
, fp0
, fd
);
10682 tcg_temp_free_i32(fp0
);
10687 check_cp1_registers(ctx
, fd
);
10689 TCGv_i32 fp32
= tcg_temp_new_i32();
10690 TCGv_i64 fp64
= tcg_temp_new_i64();
10692 gen_load_fpr32(ctx
, fp32
, fs
);
10693 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
10694 tcg_temp_free_i32(fp32
);
10695 gen_store_fpr64(ctx
, fp64
, fd
);
10696 tcg_temp_free_i64(fp64
);
10701 TCGv_i32 fp0
= tcg_temp_new_i32();
10703 gen_load_fpr32(ctx
, fp0
, fs
);
10704 if (ctx
->nan2008
) {
10705 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
10707 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
10709 gen_store_fpr32(ctx
, fp0
, fd
);
10710 tcg_temp_free_i32(fp0
);
10714 check_cp1_64bitmode(ctx
);
10716 TCGv_i32 fp32
= tcg_temp_new_i32();
10717 TCGv_i64 fp64
= tcg_temp_new_i64();
10719 gen_load_fpr32(ctx
, fp32
, fs
);
10720 if (ctx
->nan2008
) {
10721 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
10723 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
10725 tcg_temp_free_i32(fp32
);
10726 gen_store_fpr64(ctx
, fp64
, fd
);
10727 tcg_temp_free_i64(fp64
);
10733 TCGv_i64 fp64
= tcg_temp_new_i64();
10734 TCGv_i32 fp32_0
= tcg_temp_new_i32();
10735 TCGv_i32 fp32_1
= tcg_temp_new_i32();
10737 gen_load_fpr32(ctx
, fp32_0
, fs
);
10738 gen_load_fpr32(ctx
, fp32_1
, ft
);
10739 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
10740 tcg_temp_free_i32(fp32_1
);
10741 tcg_temp_free_i32(fp32_0
);
10742 gen_store_fpr64(ctx
, fp64
, fd
);
10743 tcg_temp_free_i64(fp64
);
10749 case OPC_CMP_UEQ_S
:
10750 case OPC_CMP_OLT_S
:
10751 case OPC_CMP_ULT_S
:
10752 case OPC_CMP_OLE_S
:
10753 case OPC_CMP_ULE_S
:
10755 case OPC_CMP_NGLE_S
:
10756 case OPC_CMP_SEQ_S
:
10757 case OPC_CMP_NGL_S
:
10759 case OPC_CMP_NGE_S
:
10761 case OPC_CMP_NGT_S
:
10762 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10763 if (ctx
->opcode
& (1 << 6)) {
10764 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
10766 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
10770 check_cp1_registers(ctx
, fs
| ft
| fd
);
10772 TCGv_i64 fp0
= tcg_temp_new_i64();
10773 TCGv_i64 fp1
= tcg_temp_new_i64();
10775 gen_load_fpr64(ctx
, fp0
, fs
);
10776 gen_load_fpr64(ctx
, fp1
, ft
);
10777 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
10778 tcg_temp_free_i64(fp1
);
10779 gen_store_fpr64(ctx
, fp0
, fd
);
10780 tcg_temp_free_i64(fp0
);
10784 check_cp1_registers(ctx
, fs
| ft
| fd
);
10786 TCGv_i64 fp0
= tcg_temp_new_i64();
10787 TCGv_i64 fp1
= tcg_temp_new_i64();
10789 gen_load_fpr64(ctx
, fp0
, fs
);
10790 gen_load_fpr64(ctx
, fp1
, ft
);
10791 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
10792 tcg_temp_free_i64(fp1
);
10793 gen_store_fpr64(ctx
, fp0
, fd
);
10794 tcg_temp_free_i64(fp0
);
10798 check_cp1_registers(ctx
, fs
| ft
| fd
);
10800 TCGv_i64 fp0
= tcg_temp_new_i64();
10801 TCGv_i64 fp1
= tcg_temp_new_i64();
10803 gen_load_fpr64(ctx
, fp0
, fs
);
10804 gen_load_fpr64(ctx
, fp1
, ft
);
10805 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
10806 tcg_temp_free_i64(fp1
);
10807 gen_store_fpr64(ctx
, fp0
, fd
);
10808 tcg_temp_free_i64(fp0
);
10812 check_cp1_registers(ctx
, fs
| ft
| fd
);
10814 TCGv_i64 fp0
= tcg_temp_new_i64();
10815 TCGv_i64 fp1
= tcg_temp_new_i64();
10817 gen_load_fpr64(ctx
, fp0
, fs
);
10818 gen_load_fpr64(ctx
, fp1
, ft
);
10819 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
10820 tcg_temp_free_i64(fp1
);
10821 gen_store_fpr64(ctx
, fp0
, fd
);
10822 tcg_temp_free_i64(fp0
);
10826 check_cp1_registers(ctx
, fs
| fd
);
10828 TCGv_i64 fp0
= tcg_temp_new_i64();
10830 gen_load_fpr64(ctx
, fp0
, fs
);
10831 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
10832 gen_store_fpr64(ctx
, fp0
, fd
);
10833 tcg_temp_free_i64(fp0
);
10837 check_cp1_registers(ctx
, fs
| fd
);
10839 TCGv_i64 fp0
= tcg_temp_new_i64();
10841 gen_load_fpr64(ctx
, fp0
, fs
);
10842 if (ctx
->abs2008
) {
10843 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
10845 gen_helper_float_abs_d(fp0
, fp0
);
10847 gen_store_fpr64(ctx
, fp0
, fd
);
10848 tcg_temp_free_i64(fp0
);
10852 check_cp1_registers(ctx
, fs
| fd
);
10854 TCGv_i64 fp0
= tcg_temp_new_i64();
10856 gen_load_fpr64(ctx
, fp0
, fs
);
10857 gen_store_fpr64(ctx
, fp0
, fd
);
10858 tcg_temp_free_i64(fp0
);
10862 check_cp1_registers(ctx
, fs
| fd
);
10864 TCGv_i64 fp0
= tcg_temp_new_i64();
10866 gen_load_fpr64(ctx
, fp0
, fs
);
10867 if (ctx
->abs2008
) {
10868 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
10870 gen_helper_float_chs_d(fp0
, fp0
);
10872 gen_store_fpr64(ctx
, fp0
, fd
);
10873 tcg_temp_free_i64(fp0
);
10876 case OPC_ROUND_L_D
:
10877 check_cp1_64bitmode(ctx
);
10879 TCGv_i64 fp0
= tcg_temp_new_i64();
10881 gen_load_fpr64(ctx
, fp0
, fs
);
10882 if (ctx
->nan2008
) {
10883 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
10885 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
10887 gen_store_fpr64(ctx
, fp0
, fd
);
10888 tcg_temp_free_i64(fp0
);
10891 case OPC_TRUNC_L_D
:
10892 check_cp1_64bitmode(ctx
);
10894 TCGv_i64 fp0
= tcg_temp_new_i64();
10896 gen_load_fpr64(ctx
, fp0
, fs
);
10897 if (ctx
->nan2008
) {
10898 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
10900 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
10902 gen_store_fpr64(ctx
, fp0
, fd
);
10903 tcg_temp_free_i64(fp0
);
10907 check_cp1_64bitmode(ctx
);
10909 TCGv_i64 fp0
= tcg_temp_new_i64();
10911 gen_load_fpr64(ctx
, fp0
, fs
);
10912 if (ctx
->nan2008
) {
10913 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
10915 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
10917 gen_store_fpr64(ctx
, fp0
, fd
);
10918 tcg_temp_free_i64(fp0
);
10921 case OPC_FLOOR_L_D
:
10922 check_cp1_64bitmode(ctx
);
10924 TCGv_i64 fp0
= tcg_temp_new_i64();
10926 gen_load_fpr64(ctx
, fp0
, fs
);
10927 if (ctx
->nan2008
) {
10928 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
10930 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
10932 gen_store_fpr64(ctx
, fp0
, fd
);
10933 tcg_temp_free_i64(fp0
);
10936 case OPC_ROUND_W_D
:
10937 check_cp1_registers(ctx
, fs
);
10939 TCGv_i32 fp32
= tcg_temp_new_i32();
10940 TCGv_i64 fp64
= tcg_temp_new_i64();
10942 gen_load_fpr64(ctx
, fp64
, fs
);
10943 if (ctx
->nan2008
) {
10944 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
10946 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
10948 tcg_temp_free_i64(fp64
);
10949 gen_store_fpr32(ctx
, fp32
, fd
);
10950 tcg_temp_free_i32(fp32
);
10953 case OPC_TRUNC_W_D
:
10954 check_cp1_registers(ctx
, fs
);
10956 TCGv_i32 fp32
= tcg_temp_new_i32();
10957 TCGv_i64 fp64
= tcg_temp_new_i64();
10959 gen_load_fpr64(ctx
, fp64
, fs
);
10960 if (ctx
->nan2008
) {
10961 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
10963 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
10965 tcg_temp_free_i64(fp64
);
10966 gen_store_fpr32(ctx
, fp32
, fd
);
10967 tcg_temp_free_i32(fp32
);
10971 check_cp1_registers(ctx
, fs
);
10973 TCGv_i32 fp32
= tcg_temp_new_i32();
10974 TCGv_i64 fp64
= tcg_temp_new_i64();
10976 gen_load_fpr64(ctx
, fp64
, fs
);
10977 if (ctx
->nan2008
) {
10978 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
10980 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
10982 tcg_temp_free_i64(fp64
);
10983 gen_store_fpr32(ctx
, fp32
, fd
);
10984 tcg_temp_free_i32(fp32
);
10987 case OPC_FLOOR_W_D
:
10988 check_cp1_registers(ctx
, fs
);
10990 TCGv_i32 fp32
= tcg_temp_new_i32();
10991 TCGv_i64 fp64
= tcg_temp_new_i64();
10993 gen_load_fpr64(ctx
, fp64
, fs
);
10994 if (ctx
->nan2008
) {
10995 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
10997 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
10999 tcg_temp_free_i64(fp64
);
11000 gen_store_fpr32(ctx
, fp32
, fd
);
11001 tcg_temp_free_i32(fp32
);
11005 check_insn(ctx
, ISA_MIPS_R6
);
11006 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11009 check_insn(ctx
, ISA_MIPS_R6
);
11010 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11013 check_insn(ctx
, ISA_MIPS_R6
);
11014 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11017 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11018 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11021 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11023 TCGLabel
*l1
= gen_new_label();
11027 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11029 fp0
= tcg_temp_new_i64();
11030 gen_load_fpr64(ctx
, fp0
, fs
);
11031 gen_store_fpr64(ctx
, fp0
, fd
);
11032 tcg_temp_free_i64(fp0
);
11037 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11039 TCGLabel
*l1
= gen_new_label();
11043 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11044 fp0
= tcg_temp_new_i64();
11045 gen_load_fpr64(ctx
, fp0
, fs
);
11046 gen_store_fpr64(ctx
, fp0
, fd
);
11047 tcg_temp_free_i64(fp0
);
11053 check_cp1_registers(ctx
, fs
| fd
);
11055 TCGv_i64 fp0
= tcg_temp_new_i64();
11057 gen_load_fpr64(ctx
, fp0
, fs
);
11058 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11059 gen_store_fpr64(ctx
, fp0
, fd
);
11060 tcg_temp_free_i64(fp0
);
11064 check_cp1_registers(ctx
, fs
| fd
);
11066 TCGv_i64 fp0
= tcg_temp_new_i64();
11068 gen_load_fpr64(ctx
, fp0
, fs
);
11069 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11070 gen_store_fpr64(ctx
, fp0
, fd
);
11071 tcg_temp_free_i64(fp0
);
11075 check_insn(ctx
, ISA_MIPS_R6
);
11077 TCGv_i64 fp0
= tcg_temp_new_i64();
11078 TCGv_i64 fp1
= tcg_temp_new_i64();
11079 TCGv_i64 fp2
= tcg_temp_new_i64();
11080 gen_load_fpr64(ctx
, fp0
, fs
);
11081 gen_load_fpr64(ctx
, fp1
, ft
);
11082 gen_load_fpr64(ctx
, fp2
, fd
);
11083 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11084 gen_store_fpr64(ctx
, fp2
, fd
);
11085 tcg_temp_free_i64(fp2
);
11086 tcg_temp_free_i64(fp1
);
11087 tcg_temp_free_i64(fp0
);
11091 check_insn(ctx
, ISA_MIPS_R6
);
11093 TCGv_i64 fp0
= tcg_temp_new_i64();
11094 TCGv_i64 fp1
= tcg_temp_new_i64();
11095 TCGv_i64 fp2
= tcg_temp_new_i64();
11096 gen_load_fpr64(ctx
, fp0
, fs
);
11097 gen_load_fpr64(ctx
, fp1
, ft
);
11098 gen_load_fpr64(ctx
, fp2
, fd
);
11099 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11100 gen_store_fpr64(ctx
, fp2
, fd
);
11101 tcg_temp_free_i64(fp2
);
11102 tcg_temp_free_i64(fp1
);
11103 tcg_temp_free_i64(fp0
);
11107 check_insn(ctx
, ISA_MIPS_R6
);
11109 TCGv_i64 fp0
= tcg_temp_new_i64();
11110 gen_load_fpr64(ctx
, fp0
, fs
);
11111 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11112 gen_store_fpr64(ctx
, fp0
, fd
);
11113 tcg_temp_free_i64(fp0
);
11117 check_insn(ctx
, ISA_MIPS_R6
);
11119 TCGv_i64 fp0
= tcg_temp_new_i64();
11120 gen_load_fpr64(ctx
, fp0
, fs
);
11121 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11122 gen_store_fpr64(ctx
, fp0
, fd
);
11123 tcg_temp_free_i64(fp0
);
11126 case OPC_MIN_D
: /* OPC_RECIP2_D */
11127 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11129 TCGv_i64 fp0
= tcg_temp_new_i64();
11130 TCGv_i64 fp1
= tcg_temp_new_i64();
11131 gen_load_fpr64(ctx
, fp0
, fs
);
11132 gen_load_fpr64(ctx
, fp1
, ft
);
11133 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11134 gen_store_fpr64(ctx
, fp1
, fd
);
11135 tcg_temp_free_i64(fp1
);
11136 tcg_temp_free_i64(fp0
);
11139 check_cp1_64bitmode(ctx
);
11141 TCGv_i64 fp0
= tcg_temp_new_i64();
11142 TCGv_i64 fp1
= tcg_temp_new_i64();
11144 gen_load_fpr64(ctx
, fp0
, fs
);
11145 gen_load_fpr64(ctx
, fp1
, ft
);
11146 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11147 tcg_temp_free_i64(fp1
);
11148 gen_store_fpr64(ctx
, fp0
, fd
);
11149 tcg_temp_free_i64(fp0
);
11153 case OPC_MINA_D
: /* OPC_RECIP1_D */
11154 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11156 TCGv_i64 fp0
= tcg_temp_new_i64();
11157 TCGv_i64 fp1
= tcg_temp_new_i64();
11158 gen_load_fpr64(ctx
, fp0
, fs
);
11159 gen_load_fpr64(ctx
, fp1
, ft
);
11160 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11161 gen_store_fpr64(ctx
, fp1
, fd
);
11162 tcg_temp_free_i64(fp1
);
11163 tcg_temp_free_i64(fp0
);
11166 check_cp1_64bitmode(ctx
);
11168 TCGv_i64 fp0
= tcg_temp_new_i64();
11170 gen_load_fpr64(ctx
, fp0
, fs
);
11171 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11172 gen_store_fpr64(ctx
, fp0
, fd
);
11173 tcg_temp_free_i64(fp0
);
11177 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11178 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11180 TCGv_i64 fp0
= tcg_temp_new_i64();
11181 TCGv_i64 fp1
= tcg_temp_new_i64();
11182 gen_load_fpr64(ctx
, fp0
, fs
);
11183 gen_load_fpr64(ctx
, fp1
, ft
);
11184 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11185 gen_store_fpr64(ctx
, fp1
, fd
);
11186 tcg_temp_free_i64(fp1
);
11187 tcg_temp_free_i64(fp0
);
11190 check_cp1_64bitmode(ctx
);
11192 TCGv_i64 fp0
= tcg_temp_new_i64();
11194 gen_load_fpr64(ctx
, fp0
, fs
);
11195 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11196 gen_store_fpr64(ctx
, fp0
, fd
);
11197 tcg_temp_free_i64(fp0
);
11201 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11202 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11204 TCGv_i64 fp0
= tcg_temp_new_i64();
11205 TCGv_i64 fp1
= tcg_temp_new_i64();
11206 gen_load_fpr64(ctx
, fp0
, fs
);
11207 gen_load_fpr64(ctx
, fp1
, ft
);
11208 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11209 gen_store_fpr64(ctx
, fp1
, fd
);
11210 tcg_temp_free_i64(fp1
);
11211 tcg_temp_free_i64(fp0
);
11214 check_cp1_64bitmode(ctx
);
11216 TCGv_i64 fp0
= tcg_temp_new_i64();
11217 TCGv_i64 fp1
= tcg_temp_new_i64();
11219 gen_load_fpr64(ctx
, fp0
, fs
);
11220 gen_load_fpr64(ctx
, fp1
, ft
);
11221 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11222 tcg_temp_free_i64(fp1
);
11223 gen_store_fpr64(ctx
, fp0
, fd
);
11224 tcg_temp_free_i64(fp0
);
11231 case OPC_CMP_UEQ_D
:
11232 case OPC_CMP_OLT_D
:
11233 case OPC_CMP_ULT_D
:
11234 case OPC_CMP_OLE_D
:
11235 case OPC_CMP_ULE_D
:
11237 case OPC_CMP_NGLE_D
:
11238 case OPC_CMP_SEQ_D
:
11239 case OPC_CMP_NGL_D
:
11241 case OPC_CMP_NGE_D
:
11243 case OPC_CMP_NGT_D
:
11244 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11245 if (ctx
->opcode
& (1 << 6)) {
11246 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11248 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11252 check_cp1_registers(ctx
, fs
);
11254 TCGv_i32 fp32
= tcg_temp_new_i32();
11255 TCGv_i64 fp64
= tcg_temp_new_i64();
11257 gen_load_fpr64(ctx
, fp64
, fs
);
11258 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11259 tcg_temp_free_i64(fp64
);
11260 gen_store_fpr32(ctx
, fp32
, fd
);
11261 tcg_temp_free_i32(fp32
);
11265 check_cp1_registers(ctx
, fs
);
11267 TCGv_i32 fp32
= tcg_temp_new_i32();
11268 TCGv_i64 fp64
= tcg_temp_new_i64();
11270 gen_load_fpr64(ctx
, fp64
, fs
);
11271 if (ctx
->nan2008
) {
11272 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11274 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11276 tcg_temp_free_i64(fp64
);
11277 gen_store_fpr32(ctx
, fp32
, fd
);
11278 tcg_temp_free_i32(fp32
);
11282 check_cp1_64bitmode(ctx
);
11284 TCGv_i64 fp0
= tcg_temp_new_i64();
11286 gen_load_fpr64(ctx
, fp0
, fs
);
11287 if (ctx
->nan2008
) {
11288 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11290 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11292 gen_store_fpr64(ctx
, fp0
, fd
);
11293 tcg_temp_free_i64(fp0
);
11298 TCGv_i32 fp0
= tcg_temp_new_i32();
11300 gen_load_fpr32(ctx
, fp0
, fs
);
11301 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11302 gen_store_fpr32(ctx
, fp0
, fd
);
11303 tcg_temp_free_i32(fp0
);
11307 check_cp1_registers(ctx
, fd
);
11309 TCGv_i32 fp32
= tcg_temp_new_i32();
11310 TCGv_i64 fp64
= tcg_temp_new_i64();
11312 gen_load_fpr32(ctx
, fp32
, fs
);
11313 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11314 tcg_temp_free_i32(fp32
);
11315 gen_store_fpr64(ctx
, fp64
, fd
);
11316 tcg_temp_free_i64(fp64
);
11320 check_cp1_64bitmode(ctx
);
11322 TCGv_i32 fp32
= tcg_temp_new_i32();
11323 TCGv_i64 fp64
= tcg_temp_new_i64();
11325 gen_load_fpr64(ctx
, fp64
, fs
);
11326 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11327 tcg_temp_free_i64(fp64
);
11328 gen_store_fpr32(ctx
, fp32
, fd
);
11329 tcg_temp_free_i32(fp32
);
11333 check_cp1_64bitmode(ctx
);
11335 TCGv_i64 fp0
= tcg_temp_new_i64();
11337 gen_load_fpr64(ctx
, fp0
, fs
);
11338 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11339 gen_store_fpr64(ctx
, fp0
, fd
);
11340 tcg_temp_free_i64(fp0
);
11343 case OPC_CVT_PS_PW
:
11346 TCGv_i64 fp0
= tcg_temp_new_i64();
11348 gen_load_fpr64(ctx
, fp0
, fs
);
11349 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11350 gen_store_fpr64(ctx
, fp0
, fd
);
11351 tcg_temp_free_i64(fp0
);
11357 TCGv_i64 fp0
= tcg_temp_new_i64();
11358 TCGv_i64 fp1
= tcg_temp_new_i64();
11360 gen_load_fpr64(ctx
, fp0
, fs
);
11361 gen_load_fpr64(ctx
, fp1
, ft
);
11362 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11363 tcg_temp_free_i64(fp1
);
11364 gen_store_fpr64(ctx
, fp0
, fd
);
11365 tcg_temp_free_i64(fp0
);
11371 TCGv_i64 fp0
= tcg_temp_new_i64();
11372 TCGv_i64 fp1
= tcg_temp_new_i64();
11374 gen_load_fpr64(ctx
, fp0
, fs
);
11375 gen_load_fpr64(ctx
, fp1
, ft
);
11376 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11377 tcg_temp_free_i64(fp1
);
11378 gen_store_fpr64(ctx
, fp0
, fd
);
11379 tcg_temp_free_i64(fp0
);
11385 TCGv_i64 fp0
= tcg_temp_new_i64();
11386 TCGv_i64 fp1
= tcg_temp_new_i64();
11388 gen_load_fpr64(ctx
, fp0
, fs
);
11389 gen_load_fpr64(ctx
, fp1
, ft
);
11390 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11391 tcg_temp_free_i64(fp1
);
11392 gen_store_fpr64(ctx
, fp0
, fd
);
11393 tcg_temp_free_i64(fp0
);
11399 TCGv_i64 fp0
= tcg_temp_new_i64();
11401 gen_load_fpr64(ctx
, fp0
, fs
);
11402 gen_helper_float_abs_ps(fp0
, fp0
);
11403 gen_store_fpr64(ctx
, fp0
, fd
);
11404 tcg_temp_free_i64(fp0
);
11410 TCGv_i64 fp0
= tcg_temp_new_i64();
11412 gen_load_fpr64(ctx
, fp0
, fs
);
11413 gen_store_fpr64(ctx
, fp0
, fd
);
11414 tcg_temp_free_i64(fp0
);
11420 TCGv_i64 fp0
= tcg_temp_new_i64();
11422 gen_load_fpr64(ctx
, fp0
, fs
);
11423 gen_helper_float_chs_ps(fp0
, fp0
);
11424 gen_store_fpr64(ctx
, fp0
, fd
);
11425 tcg_temp_free_i64(fp0
);
11430 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11435 TCGLabel
*l1
= gen_new_label();
11439 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11441 fp0
= tcg_temp_new_i64();
11442 gen_load_fpr64(ctx
, fp0
, fs
);
11443 gen_store_fpr64(ctx
, fp0
, fd
);
11444 tcg_temp_free_i64(fp0
);
11451 TCGLabel
*l1
= gen_new_label();
11455 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11456 fp0
= tcg_temp_new_i64();
11457 gen_load_fpr64(ctx
, fp0
, fs
);
11458 gen_store_fpr64(ctx
, fp0
, fd
);
11459 tcg_temp_free_i64(fp0
);
11467 TCGv_i64 fp0
= tcg_temp_new_i64();
11468 TCGv_i64 fp1
= tcg_temp_new_i64();
11470 gen_load_fpr64(ctx
, fp0
, ft
);
11471 gen_load_fpr64(ctx
, fp1
, fs
);
11472 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11473 tcg_temp_free_i64(fp1
);
11474 gen_store_fpr64(ctx
, fp0
, fd
);
11475 tcg_temp_free_i64(fp0
);
11481 TCGv_i64 fp0
= tcg_temp_new_i64();
11482 TCGv_i64 fp1
= tcg_temp_new_i64();
11484 gen_load_fpr64(ctx
, fp0
, ft
);
11485 gen_load_fpr64(ctx
, fp1
, fs
);
11486 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11487 tcg_temp_free_i64(fp1
);
11488 gen_store_fpr64(ctx
, fp0
, fd
);
11489 tcg_temp_free_i64(fp0
);
11492 case OPC_RECIP2_PS
:
11495 TCGv_i64 fp0
= tcg_temp_new_i64();
11496 TCGv_i64 fp1
= tcg_temp_new_i64();
11498 gen_load_fpr64(ctx
, fp0
, fs
);
11499 gen_load_fpr64(ctx
, fp1
, ft
);
11500 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11501 tcg_temp_free_i64(fp1
);
11502 gen_store_fpr64(ctx
, fp0
, fd
);
11503 tcg_temp_free_i64(fp0
);
11506 case OPC_RECIP1_PS
:
11509 TCGv_i64 fp0
= tcg_temp_new_i64();
11511 gen_load_fpr64(ctx
, fp0
, fs
);
11512 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11513 gen_store_fpr64(ctx
, fp0
, fd
);
11514 tcg_temp_free_i64(fp0
);
11517 case OPC_RSQRT1_PS
:
11520 TCGv_i64 fp0
= tcg_temp_new_i64();
11522 gen_load_fpr64(ctx
, fp0
, fs
);
11523 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11524 gen_store_fpr64(ctx
, fp0
, fd
);
11525 tcg_temp_free_i64(fp0
);
11528 case OPC_RSQRT2_PS
:
11531 TCGv_i64 fp0
= tcg_temp_new_i64();
11532 TCGv_i64 fp1
= tcg_temp_new_i64();
11534 gen_load_fpr64(ctx
, fp0
, fs
);
11535 gen_load_fpr64(ctx
, fp1
, ft
);
11536 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
11537 tcg_temp_free_i64(fp1
);
11538 gen_store_fpr64(ctx
, fp0
, fd
);
11539 tcg_temp_free_i64(fp0
);
11543 check_cp1_64bitmode(ctx
);
11545 TCGv_i32 fp0
= tcg_temp_new_i32();
11547 gen_load_fpr32h(ctx
, fp0
, fs
);
11548 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11549 gen_store_fpr32(ctx
, fp0
, fd
);
11550 tcg_temp_free_i32(fp0
);
11553 case OPC_CVT_PW_PS
:
11556 TCGv_i64 fp0
= tcg_temp_new_i64();
11558 gen_load_fpr64(ctx
, fp0
, fs
);
11559 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11560 gen_store_fpr64(ctx
, fp0
, fd
);
11561 tcg_temp_free_i64(fp0
);
11565 check_cp1_64bitmode(ctx
);
11567 TCGv_i32 fp0
= tcg_temp_new_i32();
11569 gen_load_fpr32(ctx
, fp0
, fs
);
11570 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11571 gen_store_fpr32(ctx
, fp0
, fd
);
11572 tcg_temp_free_i32(fp0
);
11578 TCGv_i32 fp0
= tcg_temp_new_i32();
11579 TCGv_i32 fp1
= tcg_temp_new_i32();
11581 gen_load_fpr32(ctx
, fp0
, fs
);
11582 gen_load_fpr32(ctx
, fp1
, ft
);
11583 gen_store_fpr32h(ctx
, fp0
, fd
);
11584 gen_store_fpr32(ctx
, fp1
, fd
);
11585 tcg_temp_free_i32(fp0
);
11586 tcg_temp_free_i32(fp1
);
11592 TCGv_i32 fp0
= tcg_temp_new_i32();
11593 TCGv_i32 fp1
= tcg_temp_new_i32();
11595 gen_load_fpr32(ctx
, fp0
, fs
);
11596 gen_load_fpr32h(ctx
, fp1
, ft
);
11597 gen_store_fpr32(ctx
, fp1
, fd
);
11598 gen_store_fpr32h(ctx
, fp0
, fd
);
11599 tcg_temp_free_i32(fp0
);
11600 tcg_temp_free_i32(fp1
);
11606 TCGv_i32 fp0
= tcg_temp_new_i32();
11607 TCGv_i32 fp1
= tcg_temp_new_i32();
11609 gen_load_fpr32h(ctx
, fp0
, fs
);
11610 gen_load_fpr32(ctx
, fp1
, ft
);
11611 gen_store_fpr32(ctx
, fp1
, fd
);
11612 gen_store_fpr32h(ctx
, fp0
, fd
);
11613 tcg_temp_free_i32(fp0
);
11614 tcg_temp_free_i32(fp1
);
11620 TCGv_i32 fp0
= tcg_temp_new_i32();
11621 TCGv_i32 fp1
= tcg_temp_new_i32();
11623 gen_load_fpr32h(ctx
, fp0
, fs
);
11624 gen_load_fpr32h(ctx
, fp1
, ft
);
11625 gen_store_fpr32(ctx
, fp1
, fd
);
11626 gen_store_fpr32h(ctx
, fp0
, fd
);
11627 tcg_temp_free_i32(fp0
);
11628 tcg_temp_free_i32(fp1
);
11632 case OPC_CMP_UN_PS
:
11633 case OPC_CMP_EQ_PS
:
11634 case OPC_CMP_UEQ_PS
:
11635 case OPC_CMP_OLT_PS
:
11636 case OPC_CMP_ULT_PS
:
11637 case OPC_CMP_OLE_PS
:
11638 case OPC_CMP_ULE_PS
:
11639 case OPC_CMP_SF_PS
:
11640 case OPC_CMP_NGLE_PS
:
11641 case OPC_CMP_SEQ_PS
:
11642 case OPC_CMP_NGL_PS
:
11643 case OPC_CMP_LT_PS
:
11644 case OPC_CMP_NGE_PS
:
11645 case OPC_CMP_LE_PS
:
11646 case OPC_CMP_NGT_PS
:
11647 if (ctx
->opcode
& (1 << 6)) {
11648 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
11650 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
11654 MIPS_INVAL("farith");
11655 gen_reserved_instruction(ctx
);
11660 /* Coprocessor 3 (FPU) */
11661 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
11662 int fd
, int fs
, int base
, int index
)
11664 TCGv t0
= tcg_temp_new();
11667 gen_load_gpr(t0
, index
);
11668 } else if (index
== 0) {
11669 gen_load_gpr(t0
, base
);
11671 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
11674 * Don't do NOP if destination is zero: we must perform the actual
11681 TCGv_i32 fp0
= tcg_temp_new_i32();
11683 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
11684 tcg_gen_trunc_tl_i32(fp0
, t0
);
11685 gen_store_fpr32(ctx
, fp0
, fd
);
11686 tcg_temp_free_i32(fp0
);
11691 check_cp1_registers(ctx
, fd
);
11693 TCGv_i64 fp0
= tcg_temp_new_i64();
11694 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11695 gen_store_fpr64(ctx
, fp0
, fd
);
11696 tcg_temp_free_i64(fp0
);
11700 check_cp1_64bitmode(ctx
);
11701 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11703 TCGv_i64 fp0
= tcg_temp_new_i64();
11705 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11706 gen_store_fpr64(ctx
, fp0
, fd
);
11707 tcg_temp_free_i64(fp0
);
11713 TCGv_i32 fp0
= tcg_temp_new_i32();
11714 gen_load_fpr32(ctx
, fp0
, fs
);
11715 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
11716 tcg_temp_free_i32(fp0
);
11721 check_cp1_registers(ctx
, fs
);
11723 TCGv_i64 fp0
= tcg_temp_new_i64();
11724 gen_load_fpr64(ctx
, fp0
, fs
);
11725 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11726 tcg_temp_free_i64(fp0
);
11730 check_cp1_64bitmode(ctx
);
11731 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11733 TCGv_i64 fp0
= tcg_temp_new_i64();
11734 gen_load_fpr64(ctx
, fp0
, fs
);
11735 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11736 tcg_temp_free_i64(fp0
);
11743 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
11744 int fd
, int fr
, int fs
, int ft
)
11750 TCGv t0
= tcg_temp_local_new();
11751 TCGv_i32 fp
= tcg_temp_new_i32();
11752 TCGv_i32 fph
= tcg_temp_new_i32();
11753 TCGLabel
*l1
= gen_new_label();
11754 TCGLabel
*l2
= gen_new_label();
11756 gen_load_gpr(t0
, fr
);
11757 tcg_gen_andi_tl(t0
, t0
, 0x7);
11759 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
11760 gen_load_fpr32(ctx
, fp
, fs
);
11761 gen_load_fpr32h(ctx
, fph
, fs
);
11762 gen_store_fpr32(ctx
, fp
, fd
);
11763 gen_store_fpr32h(ctx
, fph
, fd
);
11766 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
11768 #ifdef TARGET_WORDS_BIGENDIAN
11769 gen_load_fpr32(ctx
, fp
, fs
);
11770 gen_load_fpr32h(ctx
, fph
, ft
);
11771 gen_store_fpr32h(ctx
, fp
, fd
);
11772 gen_store_fpr32(ctx
, fph
, fd
);
11774 gen_load_fpr32h(ctx
, fph
, fs
);
11775 gen_load_fpr32(ctx
, fp
, ft
);
11776 gen_store_fpr32(ctx
, fph
, fd
);
11777 gen_store_fpr32h(ctx
, fp
, fd
);
11780 tcg_temp_free_i32(fp
);
11781 tcg_temp_free_i32(fph
);
11787 TCGv_i32 fp0
= tcg_temp_new_i32();
11788 TCGv_i32 fp1
= tcg_temp_new_i32();
11789 TCGv_i32 fp2
= tcg_temp_new_i32();
11791 gen_load_fpr32(ctx
, fp0
, fs
);
11792 gen_load_fpr32(ctx
, fp1
, ft
);
11793 gen_load_fpr32(ctx
, fp2
, fr
);
11794 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11795 tcg_temp_free_i32(fp0
);
11796 tcg_temp_free_i32(fp1
);
11797 gen_store_fpr32(ctx
, fp2
, fd
);
11798 tcg_temp_free_i32(fp2
);
11803 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11805 TCGv_i64 fp0
= tcg_temp_new_i64();
11806 TCGv_i64 fp1
= tcg_temp_new_i64();
11807 TCGv_i64 fp2
= tcg_temp_new_i64();
11809 gen_load_fpr64(ctx
, fp0
, fs
);
11810 gen_load_fpr64(ctx
, fp1
, ft
);
11811 gen_load_fpr64(ctx
, fp2
, fr
);
11812 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11813 tcg_temp_free_i64(fp0
);
11814 tcg_temp_free_i64(fp1
);
11815 gen_store_fpr64(ctx
, fp2
, fd
);
11816 tcg_temp_free_i64(fp2
);
11822 TCGv_i64 fp0
= tcg_temp_new_i64();
11823 TCGv_i64 fp1
= tcg_temp_new_i64();
11824 TCGv_i64 fp2
= tcg_temp_new_i64();
11826 gen_load_fpr64(ctx
, fp0
, fs
);
11827 gen_load_fpr64(ctx
, fp1
, ft
);
11828 gen_load_fpr64(ctx
, fp2
, fr
);
11829 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11830 tcg_temp_free_i64(fp0
);
11831 tcg_temp_free_i64(fp1
);
11832 gen_store_fpr64(ctx
, fp2
, fd
);
11833 tcg_temp_free_i64(fp2
);
11839 TCGv_i32 fp0
= tcg_temp_new_i32();
11840 TCGv_i32 fp1
= tcg_temp_new_i32();
11841 TCGv_i32 fp2
= tcg_temp_new_i32();
11843 gen_load_fpr32(ctx
, fp0
, fs
);
11844 gen_load_fpr32(ctx
, fp1
, ft
);
11845 gen_load_fpr32(ctx
, fp2
, fr
);
11846 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11847 tcg_temp_free_i32(fp0
);
11848 tcg_temp_free_i32(fp1
);
11849 gen_store_fpr32(ctx
, fp2
, fd
);
11850 tcg_temp_free_i32(fp2
);
11855 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11857 TCGv_i64 fp0
= tcg_temp_new_i64();
11858 TCGv_i64 fp1
= tcg_temp_new_i64();
11859 TCGv_i64 fp2
= tcg_temp_new_i64();
11861 gen_load_fpr64(ctx
, fp0
, fs
);
11862 gen_load_fpr64(ctx
, fp1
, ft
);
11863 gen_load_fpr64(ctx
, fp2
, fr
);
11864 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11865 tcg_temp_free_i64(fp0
);
11866 tcg_temp_free_i64(fp1
);
11867 gen_store_fpr64(ctx
, fp2
, fd
);
11868 tcg_temp_free_i64(fp2
);
11874 TCGv_i64 fp0
= tcg_temp_new_i64();
11875 TCGv_i64 fp1
= tcg_temp_new_i64();
11876 TCGv_i64 fp2
= tcg_temp_new_i64();
11878 gen_load_fpr64(ctx
, fp0
, fs
);
11879 gen_load_fpr64(ctx
, fp1
, ft
);
11880 gen_load_fpr64(ctx
, fp2
, fr
);
11881 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11882 tcg_temp_free_i64(fp0
);
11883 tcg_temp_free_i64(fp1
);
11884 gen_store_fpr64(ctx
, fp2
, fd
);
11885 tcg_temp_free_i64(fp2
);
11891 TCGv_i32 fp0
= tcg_temp_new_i32();
11892 TCGv_i32 fp1
= tcg_temp_new_i32();
11893 TCGv_i32 fp2
= tcg_temp_new_i32();
11895 gen_load_fpr32(ctx
, fp0
, fs
);
11896 gen_load_fpr32(ctx
, fp1
, ft
);
11897 gen_load_fpr32(ctx
, fp2
, fr
);
11898 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11899 tcg_temp_free_i32(fp0
);
11900 tcg_temp_free_i32(fp1
);
11901 gen_store_fpr32(ctx
, fp2
, fd
);
11902 tcg_temp_free_i32(fp2
);
11907 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11909 TCGv_i64 fp0
= tcg_temp_new_i64();
11910 TCGv_i64 fp1
= tcg_temp_new_i64();
11911 TCGv_i64 fp2
= tcg_temp_new_i64();
11913 gen_load_fpr64(ctx
, fp0
, fs
);
11914 gen_load_fpr64(ctx
, fp1
, ft
);
11915 gen_load_fpr64(ctx
, fp2
, fr
);
11916 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11917 tcg_temp_free_i64(fp0
);
11918 tcg_temp_free_i64(fp1
);
11919 gen_store_fpr64(ctx
, fp2
, fd
);
11920 tcg_temp_free_i64(fp2
);
11926 TCGv_i64 fp0
= tcg_temp_new_i64();
11927 TCGv_i64 fp1
= tcg_temp_new_i64();
11928 TCGv_i64 fp2
= tcg_temp_new_i64();
11930 gen_load_fpr64(ctx
, fp0
, fs
);
11931 gen_load_fpr64(ctx
, fp1
, ft
);
11932 gen_load_fpr64(ctx
, fp2
, fr
);
11933 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11934 tcg_temp_free_i64(fp0
);
11935 tcg_temp_free_i64(fp1
);
11936 gen_store_fpr64(ctx
, fp2
, fd
);
11937 tcg_temp_free_i64(fp2
);
11943 TCGv_i32 fp0
= tcg_temp_new_i32();
11944 TCGv_i32 fp1
= tcg_temp_new_i32();
11945 TCGv_i32 fp2
= tcg_temp_new_i32();
11947 gen_load_fpr32(ctx
, fp0
, fs
);
11948 gen_load_fpr32(ctx
, fp1
, ft
);
11949 gen_load_fpr32(ctx
, fp2
, fr
);
11950 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11951 tcg_temp_free_i32(fp0
);
11952 tcg_temp_free_i32(fp1
);
11953 gen_store_fpr32(ctx
, fp2
, fd
);
11954 tcg_temp_free_i32(fp2
);
11959 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11961 TCGv_i64 fp0
= tcg_temp_new_i64();
11962 TCGv_i64 fp1
= tcg_temp_new_i64();
11963 TCGv_i64 fp2
= tcg_temp_new_i64();
11965 gen_load_fpr64(ctx
, fp0
, fs
);
11966 gen_load_fpr64(ctx
, fp1
, ft
);
11967 gen_load_fpr64(ctx
, fp2
, fr
);
11968 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11969 tcg_temp_free_i64(fp0
);
11970 tcg_temp_free_i64(fp1
);
11971 gen_store_fpr64(ctx
, fp2
, fd
);
11972 tcg_temp_free_i64(fp2
);
11978 TCGv_i64 fp0
= tcg_temp_new_i64();
11979 TCGv_i64 fp1
= tcg_temp_new_i64();
11980 TCGv_i64 fp2
= tcg_temp_new_i64();
11982 gen_load_fpr64(ctx
, fp0
, fs
);
11983 gen_load_fpr64(ctx
, fp1
, ft
);
11984 gen_load_fpr64(ctx
, fp2
, fr
);
11985 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11986 tcg_temp_free_i64(fp0
);
11987 tcg_temp_free_i64(fp1
);
11988 gen_store_fpr64(ctx
, fp2
, fd
);
11989 tcg_temp_free_i64(fp2
);
11993 MIPS_INVAL("flt3_arith");
11994 gen_reserved_instruction(ctx
);
11999 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12003 #if !defined(CONFIG_USER_ONLY)
12005 * The Linux kernel will emulate rdhwr if it's not supported natively.
12006 * Therefore only check the ISA in system mode.
12008 check_insn(ctx
, ISA_MIPS_R2
);
12010 t0
= tcg_temp_new();
12014 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12015 gen_store_gpr(t0
, rt
);
12018 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12019 gen_store_gpr(t0
, rt
);
12022 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12025 gen_helper_rdhwr_cc(t0
, cpu_env
);
12026 gen_store_gpr(t0
, rt
);
12028 * Break the TB to be able to take timer interrupts immediately
12029 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12030 * we break completely out of translated code.
12032 gen_save_pc(ctx
->base
.pc_next
+ 4);
12033 ctx
->base
.is_jmp
= DISAS_EXIT
;
12036 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12037 gen_store_gpr(t0
, rt
);
12040 check_insn(ctx
, ISA_MIPS_R6
);
12043 * Performance counter registers are not implemented other than
12044 * control register 0.
12046 generate_exception(ctx
, EXCP_RI
);
12048 gen_helper_rdhwr_performance(t0
, cpu_env
);
12049 gen_store_gpr(t0
, rt
);
12052 check_insn(ctx
, ISA_MIPS_R6
);
12053 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12054 gen_store_gpr(t0
, rt
);
12057 #if defined(CONFIG_USER_ONLY)
12058 tcg_gen_ld_tl(t0
, cpu_env
,
12059 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12060 gen_store_gpr(t0
, rt
);
12063 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12064 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12065 tcg_gen_ld_tl(t0
, cpu_env
,
12066 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12067 gen_store_gpr(t0
, rt
);
12069 gen_reserved_instruction(ctx
);
12073 default: /* Invalid */
12074 MIPS_INVAL("rdhwr");
12075 gen_reserved_instruction(ctx
);
12081 static inline void clear_branch_hflags(DisasContext
*ctx
)
12083 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12084 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12085 save_cpu_state(ctx
, 0);
12088 * It is not safe to save ctx->hflags as hflags may be changed
12089 * in execution time by the instruction in delay / forbidden slot.
12091 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12095 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12097 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12098 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12099 /* Branches completion */
12100 clear_branch_hflags(ctx
);
12101 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12102 /* FIXME: Need to clear can_do_io. */
12103 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12104 case MIPS_HFLAG_FBNSLOT
:
12105 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12108 /* unconditional branch */
12109 if (proc_hflags
& MIPS_HFLAG_BX
) {
12110 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12112 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12114 case MIPS_HFLAG_BL
:
12115 /* blikely taken case */
12116 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12118 case MIPS_HFLAG_BC
:
12119 /* Conditional branch */
12121 TCGLabel
*l1
= gen_new_label();
12123 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12124 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12126 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12129 case MIPS_HFLAG_BR
:
12130 /* unconditional branch to register */
12131 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12132 TCGv t0
= tcg_temp_new();
12133 TCGv_i32 t1
= tcg_temp_new_i32();
12135 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12136 tcg_gen_trunc_tl_i32(t1
, t0
);
12138 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12139 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12140 tcg_gen_or_i32(hflags
, hflags
, t1
);
12141 tcg_temp_free_i32(t1
);
12143 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12145 tcg_gen_mov_tl(cpu_PC
, btarget
);
12147 if (ctx
->base
.singlestep_enabled
) {
12148 save_cpu_state(ctx
, 0);
12149 gen_helper_raise_exception_debug(cpu_env
);
12151 tcg_gen_lookup_and_goto_ptr();
12154 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12160 /* Compact Branches */
12161 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12162 int rs
, int rt
, int32_t offset
)
12164 int bcond_compute
= 0;
12165 TCGv t0
= tcg_temp_new();
12166 TCGv t1
= tcg_temp_new();
12167 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12169 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12170 #ifdef MIPS_DEBUG_DISAS
12171 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12172 "\n", ctx
->base
.pc_next
);
12174 gen_reserved_instruction(ctx
);
12178 /* Load needed operands and calculate btarget */
12180 /* compact branch */
12181 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12182 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12183 gen_load_gpr(t0
, rs
);
12184 gen_load_gpr(t1
, rt
);
12186 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12187 if (rs
<= rt
&& rs
== 0) {
12188 /* OPC_BEQZALC, OPC_BNEZALC */
12189 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12192 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12193 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12194 gen_load_gpr(t0
, rs
);
12195 gen_load_gpr(t1
, rt
);
12197 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12199 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12200 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12201 if (rs
== 0 || rs
== rt
) {
12202 /* OPC_BLEZALC, OPC_BGEZALC */
12203 /* OPC_BGTZALC, OPC_BLTZALC */
12204 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12206 gen_load_gpr(t0
, rs
);
12207 gen_load_gpr(t1
, rt
);
12209 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12213 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12218 /* OPC_BEQZC, OPC_BNEZC */
12219 gen_load_gpr(t0
, rs
);
12221 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12223 /* OPC_JIC, OPC_JIALC */
12224 TCGv tbase
= tcg_temp_new();
12225 TCGv toffset
= tcg_temp_new();
12227 gen_load_gpr(tbase
, rt
);
12228 tcg_gen_movi_tl(toffset
, offset
);
12229 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12230 tcg_temp_free(tbase
);
12231 tcg_temp_free(toffset
);
12235 MIPS_INVAL("Compact branch/jump");
12236 gen_reserved_instruction(ctx
);
12240 if (bcond_compute
== 0) {
12241 /* Unconditional compact branch */
12244 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12247 ctx
->hflags
|= MIPS_HFLAG_BR
;
12250 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12253 ctx
->hflags
|= MIPS_HFLAG_B
;
12256 MIPS_INVAL("Compact branch/jump");
12257 gen_reserved_instruction(ctx
);
12261 /* Generating branch here as compact branches don't have delay slot */
12262 gen_branch(ctx
, 4);
12264 /* Conditional compact branch */
12265 TCGLabel
*fs
= gen_new_label();
12266 save_cpu_state(ctx
, 0);
12269 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12270 if (rs
== 0 && rt
!= 0) {
12272 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12273 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12275 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12278 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12281 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12282 if (rs
== 0 && rt
!= 0) {
12284 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12285 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12287 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12290 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12293 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12294 if (rs
== 0 && rt
!= 0) {
12296 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12297 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12299 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12302 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12305 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12306 if (rs
== 0 && rt
!= 0) {
12308 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12309 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12311 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12314 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12317 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12318 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12320 /* OPC_BOVC, OPC_BNVC */
12321 TCGv t2
= tcg_temp_new();
12322 TCGv t3
= tcg_temp_new();
12323 TCGv t4
= tcg_temp_new();
12324 TCGv input_overflow
= tcg_temp_new();
12326 gen_load_gpr(t0
, rs
);
12327 gen_load_gpr(t1
, rt
);
12328 tcg_gen_ext32s_tl(t2
, t0
);
12329 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12330 tcg_gen_ext32s_tl(t3
, t1
);
12331 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12332 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12334 tcg_gen_add_tl(t4
, t2
, t3
);
12335 tcg_gen_ext32s_tl(t4
, t4
);
12336 tcg_gen_xor_tl(t2
, t2
, t3
);
12337 tcg_gen_xor_tl(t3
, t4
, t3
);
12338 tcg_gen_andc_tl(t2
, t3
, t2
);
12339 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12340 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12341 if (opc
== OPC_BOVC
) {
12343 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12346 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12348 tcg_temp_free(input_overflow
);
12352 } else if (rs
< rt
&& rs
== 0) {
12353 /* OPC_BEQZALC, OPC_BNEZALC */
12354 if (opc
== OPC_BEQZALC
) {
12356 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12359 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12362 /* OPC_BEQC, OPC_BNEC */
12363 if (opc
== OPC_BEQC
) {
12365 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12368 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12373 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12376 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12379 MIPS_INVAL("Compact conditional branch/jump");
12380 gen_reserved_instruction(ctx
);
12384 /* Generating branch here as compact branches don't have delay slot */
12385 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12388 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12396 /* ISA extensions (ASEs) */
12397 /* MIPS16 extension to MIPS32 */
12399 /* MIPS16 major opcodes */
12401 M16_OPC_ADDIUSP
= 0x00,
12402 M16_OPC_ADDIUPC
= 0x01,
12404 M16_OPC_JAL
= 0x03,
12405 M16_OPC_BEQZ
= 0x04,
12406 M16_OPC_BNEQZ
= 0x05,
12407 M16_OPC_SHIFT
= 0x06,
12409 M16_OPC_RRIA
= 0x08,
12410 M16_OPC_ADDIU8
= 0x09,
12411 M16_OPC_SLTI
= 0x0a,
12412 M16_OPC_SLTIU
= 0x0b,
12415 M16_OPC_CMPI
= 0x0e,
12419 M16_OPC_LWSP
= 0x12,
12421 M16_OPC_LBU
= 0x14,
12422 M16_OPC_LHU
= 0x15,
12423 M16_OPC_LWPC
= 0x16,
12424 M16_OPC_LWU
= 0x17,
12427 M16_OPC_SWSP
= 0x1a,
12429 M16_OPC_RRR
= 0x1c,
12431 M16_OPC_EXTEND
= 0x1e,
12435 /* I8 funct field */
12454 /* RR funct field */
12488 /* I64 funct field */
12496 I64_DADDIUPC
= 0x6,
12500 /* RR ry field for CNVT */
12502 RR_RY_CNVT_ZEB
= 0x0,
12503 RR_RY_CNVT_ZEH
= 0x1,
12504 RR_RY_CNVT_ZEW
= 0x2,
12505 RR_RY_CNVT_SEB
= 0x4,
12506 RR_RY_CNVT_SEH
= 0x5,
12507 RR_RY_CNVT_SEW
= 0x6,
12510 static int xlat(int r
)
12512 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12517 static void gen_mips16_save(DisasContext
*ctx
,
12518 int xsregs
, int aregs
,
12519 int do_ra
, int do_s0
, int do_s1
,
12522 TCGv t0
= tcg_temp_new();
12523 TCGv t1
= tcg_temp_new();
12524 TCGv t2
= tcg_temp_new();
12554 gen_reserved_instruction(ctx
);
12560 gen_base_offset_addr(ctx
, t0
, 29, 12);
12561 gen_load_gpr(t1
, 7);
12562 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12565 gen_base_offset_addr(ctx
, t0
, 29, 8);
12566 gen_load_gpr(t1
, 6);
12567 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12570 gen_base_offset_addr(ctx
, t0
, 29, 4);
12571 gen_load_gpr(t1
, 5);
12572 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12575 gen_base_offset_addr(ctx
, t0
, 29, 0);
12576 gen_load_gpr(t1
, 4);
12577 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12580 gen_load_gpr(t0
, 29);
12582 #define DECR_AND_STORE(reg) do { \
12583 tcg_gen_movi_tl(t2, -4); \
12584 gen_op_addr_add(ctx, t0, t0, t2); \
12585 gen_load_gpr(t1, reg); \
12586 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12590 DECR_AND_STORE(31);
12595 DECR_AND_STORE(30);
12598 DECR_AND_STORE(23);
12601 DECR_AND_STORE(22);
12604 DECR_AND_STORE(21);
12607 DECR_AND_STORE(20);
12610 DECR_AND_STORE(19);
12613 DECR_AND_STORE(18);
12617 DECR_AND_STORE(17);
12620 DECR_AND_STORE(16);
12650 gen_reserved_instruction(ctx
);
12666 #undef DECR_AND_STORE
12668 tcg_gen_movi_tl(t2
, -framesize
);
12669 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12675 static void gen_mips16_restore(DisasContext
*ctx
,
12676 int xsregs
, int aregs
,
12677 int do_ra
, int do_s0
, int do_s1
,
12681 TCGv t0
= tcg_temp_new();
12682 TCGv t1
= tcg_temp_new();
12683 TCGv t2
= tcg_temp_new();
12685 tcg_gen_movi_tl(t2
, framesize
);
12686 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
12688 #define DECR_AND_LOAD(reg) do { \
12689 tcg_gen_movi_tl(t2, -4); \
12690 gen_op_addr_add(ctx, t0, t0, t2); \
12691 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12692 gen_store_gpr(t1, reg); \
12756 gen_reserved_instruction(ctx
);
12772 #undef DECR_AND_LOAD
12774 tcg_gen_movi_tl(t2
, framesize
);
12775 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12781 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
12782 int is_64_bit
, int extended
)
12786 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12787 gen_reserved_instruction(ctx
);
12791 t0
= tcg_temp_new();
12793 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
12794 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
12796 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12802 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
12805 TCGv_i32 t0
= tcg_const_i32(op
);
12806 TCGv t1
= tcg_temp_new();
12807 gen_base_offset_addr(ctx
, t1
, base
, offset
);
12808 gen_helper_cache(cpu_env
, t1
, t0
);
12810 tcg_temp_free_i32(t0
);
12813 #if defined(TARGET_MIPS64)
12814 static void decode_i64_mips16(DisasContext
*ctx
,
12815 int ry
, int funct
, int16_t offset
,
12820 check_insn(ctx
, ISA_MIPS3
);
12821 check_mips_64(ctx
);
12822 offset
= extended
? offset
: offset
<< 3;
12823 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
12826 check_insn(ctx
, ISA_MIPS3
);
12827 check_mips_64(ctx
);
12828 offset
= extended
? offset
: offset
<< 3;
12829 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
12832 check_insn(ctx
, ISA_MIPS3
);
12833 check_mips_64(ctx
);
12834 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
12835 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
12838 check_insn(ctx
, ISA_MIPS3
);
12839 check_mips_64(ctx
);
12840 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
12841 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
12844 check_insn(ctx
, ISA_MIPS3
);
12845 check_mips_64(ctx
);
12846 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12847 gen_reserved_instruction(ctx
);
12849 offset
= extended
? offset
: offset
<< 3;
12850 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
12854 check_insn(ctx
, ISA_MIPS3
);
12855 check_mips_64(ctx
);
12856 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
12857 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
12860 check_insn(ctx
, ISA_MIPS3
);
12861 check_mips_64(ctx
);
12862 offset
= extended
? offset
: offset
<< 2;
12863 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
12866 check_insn(ctx
, ISA_MIPS3
);
12867 check_mips_64(ctx
);
12868 offset
= extended
? offset
: offset
<< 2;
12869 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
12875 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
12877 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
12878 int op
, rx
, ry
, funct
, sa
;
12879 int16_t imm
, offset
;
12881 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
12882 op
= (ctx
->opcode
>> 11) & 0x1f;
12883 sa
= (ctx
->opcode
>> 22) & 0x1f;
12884 funct
= (ctx
->opcode
>> 8) & 0x7;
12885 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
12886 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
12887 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
12888 | ((ctx
->opcode
>> 21) & 0x3f) << 5
12889 | (ctx
->opcode
& 0x1f));
12892 * The extended opcodes cleverly reuse the opcodes from their 16-bit
12896 case M16_OPC_ADDIUSP
:
12897 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
12899 case M16_OPC_ADDIUPC
:
12900 gen_addiupc(ctx
, rx
, imm
, 0, 1);
12903 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
12904 /* No delay slot, so just process as a normal instruction */
12907 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
12908 /* No delay slot, so just process as a normal instruction */
12910 case M16_OPC_BNEQZ
:
12911 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
12912 /* No delay slot, so just process as a normal instruction */
12914 case M16_OPC_SHIFT
:
12915 switch (ctx
->opcode
& 0x3) {
12917 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
12920 #if defined(TARGET_MIPS64)
12921 check_mips_64(ctx
);
12922 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
12924 gen_reserved_instruction(ctx
);
12928 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
12931 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
12935 #if defined(TARGET_MIPS64)
12937 check_insn(ctx
, ISA_MIPS3
);
12938 check_mips_64(ctx
);
12939 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
12943 imm
= ctx
->opcode
& 0xf;
12944 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
12945 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
12946 imm
= (int16_t) (imm
<< 1) >> 1;
12947 if ((ctx
->opcode
>> 4) & 0x1) {
12948 #if defined(TARGET_MIPS64)
12949 check_mips_64(ctx
);
12950 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12952 gen_reserved_instruction(ctx
);
12955 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12958 case M16_OPC_ADDIU8
:
12959 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12962 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12964 case M16_OPC_SLTIU
:
12965 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12970 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
12973 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
12976 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
12979 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
12982 check_insn(ctx
, ISA_MIPS_R1
);
12984 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
12985 int aregs
= (ctx
->opcode
>> 16) & 0xf;
12986 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
12987 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
12988 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
12989 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
12990 | (ctx
->opcode
& 0xf)) << 3;
12992 if (ctx
->opcode
& (1 << 7)) {
12993 gen_mips16_save(ctx
, xsregs
, aregs
,
12994 do_ra
, do_s0
, do_s1
,
12997 gen_mips16_restore(ctx
, xsregs
, aregs
,
12998 do_ra
, do_s0
, do_s1
,
13004 gen_reserved_instruction(ctx
);
13009 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13012 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13014 #if defined(TARGET_MIPS64)
13016 check_insn(ctx
, ISA_MIPS3
);
13017 check_mips_64(ctx
);
13018 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13022 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13025 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13028 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13031 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13034 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13037 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13040 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13042 #if defined(TARGET_MIPS64)
13044 check_insn(ctx
, ISA_MIPS3
);
13045 check_mips_64(ctx
);
13046 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13050 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13053 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13056 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13059 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13061 #if defined(TARGET_MIPS64)
13063 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13067 gen_reserved_instruction(ctx
);
13074 static inline bool is_uhi(int sdbbp_code
)
13076 #ifdef CONFIG_USER_ONLY
13079 return semihosting_enabled() && sdbbp_code
== 1;
13083 #ifdef CONFIG_USER_ONLY
13084 /* The above should dead-code away any calls to this..*/
13085 static inline void gen_helper_do_semihosting(void *env
)
13087 g_assert_not_reached();
13091 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13095 int op
, cnvt_op
, op1
, offset
;
13099 op
= (ctx
->opcode
>> 11) & 0x1f;
13100 sa
= (ctx
->opcode
>> 2) & 0x7;
13101 sa
= sa
== 0 ? 8 : sa
;
13102 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13103 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13104 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13105 op1
= offset
= ctx
->opcode
& 0x1f;
13110 case M16_OPC_ADDIUSP
:
13112 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13114 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13117 case M16_OPC_ADDIUPC
:
13118 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13121 offset
= (ctx
->opcode
& 0x7ff) << 1;
13122 offset
= (int16_t)(offset
<< 4) >> 4;
13123 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13124 /* No delay slot, so just process as a normal instruction */
13127 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13128 offset
= (((ctx
->opcode
& 0x1f) << 21)
13129 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13131 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13132 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13136 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13137 ((int8_t)ctx
->opcode
) << 1, 0);
13138 /* No delay slot, so just process as a normal instruction */
13140 case M16_OPC_BNEQZ
:
13141 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13142 ((int8_t)ctx
->opcode
) << 1, 0);
13143 /* No delay slot, so just process as a normal instruction */
13145 case M16_OPC_SHIFT
:
13146 switch (ctx
->opcode
& 0x3) {
13148 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13151 #if defined(TARGET_MIPS64)
13152 check_insn(ctx
, ISA_MIPS3
);
13153 check_mips_64(ctx
);
13154 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13156 gen_reserved_instruction(ctx
);
13160 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13163 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13167 #if defined(TARGET_MIPS64)
13169 check_insn(ctx
, ISA_MIPS3
);
13170 check_mips_64(ctx
);
13171 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13176 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13178 if ((ctx
->opcode
>> 4) & 1) {
13179 #if defined(TARGET_MIPS64)
13180 check_insn(ctx
, ISA_MIPS3
);
13181 check_mips_64(ctx
);
13182 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13184 gen_reserved_instruction(ctx
);
13187 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13191 case M16_OPC_ADDIU8
:
13193 int16_t imm
= (int8_t) ctx
->opcode
;
13195 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13200 int16_t imm
= (uint8_t) ctx
->opcode
;
13201 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13204 case M16_OPC_SLTIU
:
13206 int16_t imm
= (uint8_t) ctx
->opcode
;
13207 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13214 funct
= (ctx
->opcode
>> 8) & 0x7;
13217 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13218 ((int8_t)ctx
->opcode
) << 1, 0);
13221 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13222 ((int8_t)ctx
->opcode
) << 1, 0);
13225 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13228 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13229 ((int8_t)ctx
->opcode
) << 3);
13232 check_insn(ctx
, ISA_MIPS_R1
);
13234 int do_ra
= ctx
->opcode
& (1 << 6);
13235 int do_s0
= ctx
->opcode
& (1 << 5);
13236 int do_s1
= ctx
->opcode
& (1 << 4);
13237 int framesize
= ctx
->opcode
& 0xf;
13239 if (framesize
== 0) {
13242 framesize
= framesize
<< 3;
13245 if (ctx
->opcode
& (1 << 7)) {
13246 gen_mips16_save(ctx
, 0, 0,
13247 do_ra
, do_s0
, do_s1
, framesize
);
13249 gen_mips16_restore(ctx
, 0, 0,
13250 do_ra
, do_s0
, do_s1
, framesize
);
13256 int rz
= xlat(ctx
->opcode
& 0x7);
13258 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13259 ((ctx
->opcode
>> 5) & 0x7);
13260 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13264 reg32
= ctx
->opcode
& 0x1f;
13265 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13268 gen_reserved_instruction(ctx
);
13275 int16_t imm
= (uint8_t) ctx
->opcode
;
13277 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13282 int16_t imm
= (uint8_t) ctx
->opcode
;
13283 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13286 #if defined(TARGET_MIPS64)
13288 check_insn(ctx
, ISA_MIPS3
);
13289 check_mips_64(ctx
);
13290 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13294 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13297 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13300 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13303 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13306 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13309 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13312 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13314 #if defined(TARGET_MIPS64)
13316 check_insn(ctx
, ISA_MIPS3
);
13317 check_mips_64(ctx
);
13318 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13322 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13325 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13328 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13331 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13335 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13338 switch (ctx
->opcode
& 0x3) {
13340 mips32_op
= OPC_ADDU
;
13343 mips32_op
= OPC_SUBU
;
13345 #if defined(TARGET_MIPS64)
13347 mips32_op
= OPC_DADDU
;
13348 check_insn(ctx
, ISA_MIPS3
);
13349 check_mips_64(ctx
);
13352 mips32_op
= OPC_DSUBU
;
13353 check_insn(ctx
, ISA_MIPS3
);
13354 check_mips_64(ctx
);
13358 gen_reserved_instruction(ctx
);
13362 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13371 int nd
= (ctx
->opcode
>> 7) & 0x1;
13372 int link
= (ctx
->opcode
>> 6) & 0x1;
13373 int ra
= (ctx
->opcode
>> 5) & 0x1;
13376 check_insn(ctx
, ISA_MIPS_R1
);
13385 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13390 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13391 gen_helper_do_semihosting(cpu_env
);
13394 * XXX: not clear which exception should be raised
13395 * when in debug mode...
13397 check_insn(ctx
, ISA_MIPS_R1
);
13398 generate_exception_end(ctx
, EXCP_DBp
);
13402 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13405 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13408 generate_exception_end(ctx
, EXCP_BREAK
);
13411 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13414 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13417 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13419 #if defined(TARGET_MIPS64)
13421 check_insn(ctx
, ISA_MIPS3
);
13422 check_mips_64(ctx
);
13423 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13427 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13430 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13433 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13436 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13439 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13442 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13445 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13448 check_insn(ctx
, ISA_MIPS_R1
);
13450 case RR_RY_CNVT_ZEB
:
13451 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13453 case RR_RY_CNVT_ZEH
:
13454 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13456 case RR_RY_CNVT_SEB
:
13457 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13459 case RR_RY_CNVT_SEH
:
13460 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13462 #if defined(TARGET_MIPS64)
13463 case RR_RY_CNVT_ZEW
:
13464 check_insn(ctx
, ISA_MIPS_R1
);
13465 check_mips_64(ctx
);
13466 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13468 case RR_RY_CNVT_SEW
:
13469 check_insn(ctx
, ISA_MIPS_R1
);
13470 check_mips_64(ctx
);
13471 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13475 gen_reserved_instruction(ctx
);
13480 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13482 #if defined(TARGET_MIPS64)
13484 check_insn(ctx
, ISA_MIPS3
);
13485 check_mips_64(ctx
);
13486 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13489 check_insn(ctx
, ISA_MIPS3
);
13490 check_mips_64(ctx
);
13491 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13494 check_insn(ctx
, ISA_MIPS3
);
13495 check_mips_64(ctx
);
13496 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13499 check_insn(ctx
, ISA_MIPS3
);
13500 check_mips_64(ctx
);
13501 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13505 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13508 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13511 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13514 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13516 #if defined(TARGET_MIPS64)
13518 check_insn(ctx
, ISA_MIPS3
);
13519 check_mips_64(ctx
);
13520 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13523 check_insn(ctx
, ISA_MIPS3
);
13524 check_mips_64(ctx
);
13525 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13528 check_insn(ctx
, ISA_MIPS3
);
13529 check_mips_64(ctx
);
13530 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13533 check_insn(ctx
, ISA_MIPS3
);
13534 check_mips_64(ctx
);
13535 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13539 gen_reserved_instruction(ctx
);
13543 case M16_OPC_EXTEND
:
13544 decode_extended_mips16_opc(env
, ctx
);
13547 #if defined(TARGET_MIPS64)
13549 funct
= (ctx
->opcode
>> 8) & 0x7;
13550 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13554 gen_reserved_instruction(ctx
);
13561 /* microMIPS extension to MIPS32/MIPS64 */
13564 * microMIPS32/microMIPS64 major opcodes
13566 * 1. MIPS Architecture for Programmers Volume II-B:
13567 * The microMIPS32 Instruction Set (Revision 3.05)
13569 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13571 * 2. MIPS Architecture For Programmers Volume II-A:
13572 * The MIPS64 Instruction Set (Revision 3.51)
13602 POOL32S
= 0x16, /* MIPS64 */
13603 DADDIU32
= 0x17, /* MIPS64 */
13632 /* 0x29 is reserved */
13645 /* 0x31 is reserved */
13658 SD32
= 0x36, /* MIPS64 */
13659 LD32
= 0x37, /* MIPS64 */
13661 /* 0x39 is reserved */
13677 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13699 /* POOL32A encoding of minor opcode field */
13703 * These opcodes are distinguished only by bits 9..6; those bits are
13704 * what are recorded below.
13742 /* The following can be distinguished by their lower 6 bits. */
13752 /* POOL32AXF encoding of minor opcode field extension */
13755 * 1. MIPS Architecture for Programmers Volume II-B:
13756 * The microMIPS32 Instruction Set (Revision 3.05)
13758 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13760 * 2. MIPS Architecture for Programmers VolumeIV-e:
13761 * The MIPS DSP Application-Specific Extension
13762 * to the microMIPS32 Architecture (Revision 2.34)
13764 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13779 /* begin of microMIPS32 DSP */
13781 /* bits 13..12 for 0x01 */
13787 /* bits 13..12 for 0x2a */
13793 /* bits 13..12 for 0x32 */
13797 /* end of microMIPS32 DSP */
13799 /* bits 15..12 for 0x2c */
13816 /* bits 15..12 for 0x34 */
13824 /* bits 15..12 for 0x3c */
13826 JR
= 0x0, /* alias */
13834 /* bits 15..12 for 0x05 */
13838 /* bits 15..12 for 0x0d */
13850 /* bits 15..12 for 0x15 */
13856 /* bits 15..12 for 0x1d */
13860 /* bits 15..12 for 0x2d */
13865 /* bits 15..12 for 0x35 */
13872 /* POOL32B encoding of minor opcode field (bits 15..12) */
13888 /* POOL32C encoding of minor opcode field (bits 15..12) */
13909 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13922 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13935 /* POOL32F encoding of minor opcode field (bits 5..0) */
13938 /* These are the bit 7..6 values */
13947 /* These are the bit 8..6 values */
13972 MOVZ_FMT_05
= 0x05,
14006 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14013 /* POOL32Fxf encoding of minor opcode extension field */
14051 /* POOL32I encoding of minor opcode field (bits 25..21) */
14081 /* These overlap and are distinguished by bit16 of the instruction */
14090 /* POOL16A encoding of minor opcode field */
14097 /* POOL16B encoding of minor opcode field */
14104 /* POOL16C encoding of minor opcode field */
14124 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14148 /* POOL16D encoding of minor opcode field */
14155 /* POOL16E encoding of minor opcode field */
14162 static int mmreg(int r
)
14164 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14169 /* Used for 16-bit store instructions. */
14170 static int mmreg2(int r
)
14172 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14177 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14178 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14179 #define uMIPS_RS2(op) uMIPS_RS(op)
14180 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14181 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14182 #define uMIPS_RS5(op) (op & 0x1f)
14184 /* Signed immediate */
14185 #define SIMM(op, start, width) \
14186 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14189 /* Zero-extended immediate */
14190 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14192 static void gen_addiur1sp(DisasContext
*ctx
)
14194 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14196 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14199 static void gen_addiur2(DisasContext
*ctx
)
14201 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14202 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14203 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14205 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14208 static void gen_addiusp(DisasContext
*ctx
)
14210 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14213 if (encoded
<= 1) {
14214 decoded
= 256 + encoded
;
14215 } else if (encoded
<= 255) {
14217 } else if (encoded
<= 509) {
14218 decoded
= encoded
- 512;
14220 decoded
= encoded
- 768;
14223 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14226 static void gen_addius5(DisasContext
*ctx
)
14228 int imm
= SIMM(ctx
->opcode
, 1, 4);
14229 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14231 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14234 static void gen_andi16(DisasContext
*ctx
)
14236 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14237 31, 32, 63, 64, 255, 32768, 65535 };
14238 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14239 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14240 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14242 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14245 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14246 int base
, int16_t offset
)
14251 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14252 gen_reserved_instruction(ctx
);
14256 t0
= tcg_temp_new();
14258 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14260 t1
= tcg_const_tl(reglist
);
14261 t2
= tcg_const_i32(ctx
->mem_idx
);
14263 save_cpu_state(ctx
, 1);
14266 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14269 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14271 #ifdef TARGET_MIPS64
14273 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14276 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14282 tcg_temp_free_i32(t2
);
14286 static void gen_pool16c_insn(DisasContext
*ctx
)
14288 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14289 int rs
= mmreg(ctx
->opcode
& 0x7);
14291 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14296 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14302 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14308 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14314 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14321 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14322 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14324 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14333 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14334 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14336 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14343 int reg
= ctx
->opcode
& 0x1f;
14345 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14351 int reg
= ctx
->opcode
& 0x1f;
14352 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14354 * Let normal delay slot handling in our caller take us
14355 * to the branch target.
14361 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14362 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14366 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14367 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14371 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14375 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14378 generate_exception_end(ctx
, EXCP_BREAK
);
14381 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14382 gen_helper_do_semihosting(cpu_env
);
14385 * XXX: not clear which exception should be raised
14386 * when in debug mode...
14388 check_insn(ctx
, ISA_MIPS_R1
);
14389 generate_exception_end(ctx
, EXCP_DBp
);
14392 case JRADDIUSP
+ 0:
14393 case JRADDIUSP
+ 1:
14395 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14396 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14397 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14399 * Let normal delay slot handling in our caller take us
14400 * to the branch target.
14405 gen_reserved_instruction(ctx
);
14410 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14414 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14415 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14416 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14418 rd
= rd_enc
[enc_dest
];
14419 re
= re_enc
[enc_dest
];
14420 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14421 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14424 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14426 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14427 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14429 switch (ctx
->opcode
& 0xf) {
14431 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14434 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14438 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14439 int offset
= extract32(ctx
->opcode
, 4, 4);
14440 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14443 case R6_JRC16
: /* JRCADDIUSP */
14444 if ((ctx
->opcode
>> 4) & 1) {
14446 int imm
= extract32(ctx
->opcode
, 5, 5);
14447 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14448 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14451 rs
= extract32(ctx
->opcode
, 5, 5);
14452 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14464 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14465 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14466 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14467 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14471 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14474 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14478 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14479 int offset
= extract32(ctx
->opcode
, 4, 4);
14480 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14483 case JALRC16
: /* BREAK16, SDBBP16 */
14484 switch (ctx
->opcode
& 0x3f) {
14486 case JALRC16
+ 0x20:
14488 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14493 generate_exception(ctx
, EXCP_BREAK
);
14497 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14498 gen_helper_do_semihosting(cpu_env
);
14500 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14501 generate_exception(ctx
, EXCP_RI
);
14503 generate_exception(ctx
, EXCP_DBp
);
14510 generate_exception(ctx
, EXCP_RI
);
14515 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14517 TCGv t0
= tcg_temp_new();
14518 TCGv t1
= tcg_temp_new();
14520 gen_load_gpr(t0
, base
);
14523 gen_load_gpr(t1
, index
);
14524 tcg_gen_shli_tl(t1
, t1
, 2);
14525 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14528 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14529 gen_store_gpr(t1
, rd
);
14535 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14536 int base
, int16_t offset
)
14540 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14541 gen_reserved_instruction(ctx
);
14545 t0
= tcg_temp_new();
14546 t1
= tcg_temp_new();
14548 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14553 gen_reserved_instruction(ctx
);
14556 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14557 gen_store_gpr(t1
, rd
);
14558 tcg_gen_movi_tl(t1
, 4);
14559 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14560 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14561 gen_store_gpr(t1
, rd
+ 1);
14564 gen_load_gpr(t1
, rd
);
14565 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14566 tcg_gen_movi_tl(t1
, 4);
14567 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14568 gen_load_gpr(t1
, rd
+ 1);
14569 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14571 #ifdef TARGET_MIPS64
14574 gen_reserved_instruction(ctx
);
14577 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14578 gen_store_gpr(t1
, rd
);
14579 tcg_gen_movi_tl(t1
, 8);
14580 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14581 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14582 gen_store_gpr(t1
, rd
+ 1);
14585 gen_load_gpr(t1
, rd
);
14586 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14587 tcg_gen_movi_tl(t1
, 8);
14588 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14589 gen_load_gpr(t1
, rd
+ 1);
14590 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14598 static void gen_sync(int stype
)
14600 TCGBar tcg_mo
= TCG_BAR_SC
;
14603 case 0x4: /* SYNC_WMB */
14604 tcg_mo
|= TCG_MO_ST_ST
;
14606 case 0x10: /* SYNC_MB */
14607 tcg_mo
|= TCG_MO_ALL
;
14609 case 0x11: /* SYNC_ACQUIRE */
14610 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14612 case 0x12: /* SYNC_RELEASE */
14613 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14615 case 0x13: /* SYNC_RMB */
14616 tcg_mo
|= TCG_MO_LD_LD
;
14619 tcg_mo
|= TCG_MO_ALL
;
14623 tcg_gen_mb(tcg_mo
);
14626 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14628 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14629 int minor
= (ctx
->opcode
>> 12) & 0xf;
14630 uint32_t mips32_op
;
14632 switch (extension
) {
14634 mips32_op
= OPC_TEQ
;
14637 mips32_op
= OPC_TGE
;
14640 mips32_op
= OPC_TGEU
;
14643 mips32_op
= OPC_TLT
;
14646 mips32_op
= OPC_TLTU
;
14649 mips32_op
= OPC_TNE
;
14651 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
14653 #ifndef CONFIG_USER_ONLY
14656 check_cp0_enabled(ctx
);
14658 /* Treat as NOP. */
14661 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
14665 check_cp0_enabled(ctx
);
14667 TCGv t0
= tcg_temp_new();
14669 gen_load_gpr(t0
, rt
);
14670 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
14676 switch (minor
& 3) {
14678 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14681 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14684 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14687 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14690 goto pool32axf_invalid
;
14694 switch (minor
& 3) {
14696 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14699 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14702 goto pool32axf_invalid
;
14708 check_insn(ctx
, ISA_MIPS_R6
);
14709 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
14712 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
14715 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
14718 mips32_op
= OPC_CLO
;
14721 mips32_op
= OPC_CLZ
;
14723 check_insn(ctx
, ISA_MIPS_R1
);
14724 gen_cl(ctx
, mips32_op
, rt
, rs
);
14727 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14728 gen_rdhwr(ctx
, rt
, rs
, 0);
14731 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
14734 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14735 mips32_op
= OPC_MULT
;
14738 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14739 mips32_op
= OPC_MULTU
;
14742 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14743 mips32_op
= OPC_DIV
;
14746 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14747 mips32_op
= OPC_DIVU
;
14750 check_insn(ctx
, ISA_MIPS_R1
);
14751 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14754 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14755 mips32_op
= OPC_MADD
;
14758 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14759 mips32_op
= OPC_MADDU
;
14762 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14763 mips32_op
= OPC_MSUB
;
14766 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14767 mips32_op
= OPC_MSUBU
;
14769 check_insn(ctx
, ISA_MIPS_R1
);
14770 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14773 goto pool32axf_invalid
;
14784 generate_exception_err(ctx
, EXCP_CpU
, 2);
14787 goto pool32axf_invalid
;
14792 case JALR
: /* JALRC */
14793 case JALR_HB
: /* JALRC_HB */
14794 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
14795 /* JALRC, JALRC_HB */
14796 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
14798 /* JALR, JALR_HB */
14799 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
14800 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14805 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14806 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
14807 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14810 goto pool32axf_invalid
;
14816 check_cp0_enabled(ctx
);
14817 check_insn(ctx
, ISA_MIPS_R2
);
14818 gen_load_srsgpr(rs
, rt
);
14821 check_cp0_enabled(ctx
);
14822 check_insn(ctx
, ISA_MIPS_R2
);
14823 gen_store_srsgpr(rs
, rt
);
14826 goto pool32axf_invalid
;
14829 #ifndef CONFIG_USER_ONLY
14833 mips32_op
= OPC_TLBP
;
14836 mips32_op
= OPC_TLBR
;
14839 mips32_op
= OPC_TLBWI
;
14842 mips32_op
= OPC_TLBWR
;
14845 mips32_op
= OPC_TLBINV
;
14848 mips32_op
= OPC_TLBINVF
;
14851 mips32_op
= OPC_WAIT
;
14854 mips32_op
= OPC_DERET
;
14857 mips32_op
= OPC_ERET
;
14859 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
14862 goto pool32axf_invalid
;
14868 check_cp0_enabled(ctx
);
14870 TCGv t0
= tcg_temp_new();
14872 save_cpu_state(ctx
, 1);
14873 gen_helper_di(t0
, cpu_env
);
14874 gen_store_gpr(t0
, rs
);
14876 * Stop translation as we may have switched the execution
14879 ctx
->base
.is_jmp
= DISAS_STOP
;
14884 check_cp0_enabled(ctx
);
14886 TCGv t0
= tcg_temp_new();
14888 save_cpu_state(ctx
, 1);
14889 gen_helper_ei(t0
, cpu_env
);
14890 gen_store_gpr(t0
, rs
);
14892 * DISAS_STOP isn't sufficient, we need to ensure we break out
14893 * of translated code to check for pending interrupts.
14895 gen_save_pc(ctx
->base
.pc_next
+ 4);
14896 ctx
->base
.is_jmp
= DISAS_EXIT
;
14901 goto pool32axf_invalid
;
14908 gen_sync(extract32(ctx
->opcode
, 16, 5));
14911 generate_exception_end(ctx
, EXCP_SYSCALL
);
14914 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
14915 gen_helper_do_semihosting(cpu_env
);
14917 check_insn(ctx
, ISA_MIPS_R1
);
14918 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14919 gen_reserved_instruction(ctx
);
14921 generate_exception_end(ctx
, EXCP_DBp
);
14926 goto pool32axf_invalid
;
14930 switch (minor
& 3) {
14932 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
14935 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
14938 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
14941 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
14944 goto pool32axf_invalid
;
14948 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14951 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
14954 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
14957 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
14960 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
14963 goto pool32axf_invalid
;
14968 MIPS_INVAL("pool32axf");
14969 gen_reserved_instruction(ctx
);
14975 * Values for microMIPS fmt field. Variable-width, depending on which
14976 * formats the instruction supports.
14995 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
14997 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
14998 uint32_t mips32_op
;
15000 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15001 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15002 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15004 switch (extension
) {
15005 case FLOAT_1BIT_FMT(CFC1
, 0):
15006 mips32_op
= OPC_CFC1
;
15008 case FLOAT_1BIT_FMT(CTC1
, 0):
15009 mips32_op
= OPC_CTC1
;
15011 case FLOAT_1BIT_FMT(MFC1
, 0):
15012 mips32_op
= OPC_MFC1
;
15014 case FLOAT_1BIT_FMT(MTC1
, 0):
15015 mips32_op
= OPC_MTC1
;
15017 case FLOAT_1BIT_FMT(MFHC1
, 0):
15018 mips32_op
= OPC_MFHC1
;
15020 case FLOAT_1BIT_FMT(MTHC1
, 0):
15021 mips32_op
= OPC_MTHC1
;
15023 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15026 /* Reciprocal square root */
15027 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15028 mips32_op
= OPC_RSQRT_S
;
15030 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15031 mips32_op
= OPC_RSQRT_D
;
15035 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15036 mips32_op
= OPC_SQRT_S
;
15038 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15039 mips32_op
= OPC_SQRT_D
;
15043 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15044 mips32_op
= OPC_RECIP_S
;
15046 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15047 mips32_op
= OPC_RECIP_D
;
15051 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15052 mips32_op
= OPC_FLOOR_L_S
;
15054 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15055 mips32_op
= OPC_FLOOR_L_D
;
15057 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15058 mips32_op
= OPC_FLOOR_W_S
;
15060 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15061 mips32_op
= OPC_FLOOR_W_D
;
15065 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15066 mips32_op
= OPC_CEIL_L_S
;
15068 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15069 mips32_op
= OPC_CEIL_L_D
;
15071 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15072 mips32_op
= OPC_CEIL_W_S
;
15074 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15075 mips32_op
= OPC_CEIL_W_D
;
15079 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15080 mips32_op
= OPC_TRUNC_L_S
;
15082 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15083 mips32_op
= OPC_TRUNC_L_D
;
15085 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15086 mips32_op
= OPC_TRUNC_W_S
;
15088 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15089 mips32_op
= OPC_TRUNC_W_D
;
15093 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15094 mips32_op
= OPC_ROUND_L_S
;
15096 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15097 mips32_op
= OPC_ROUND_L_D
;
15099 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15100 mips32_op
= OPC_ROUND_W_S
;
15102 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15103 mips32_op
= OPC_ROUND_W_D
;
15106 /* Integer to floating-point conversion */
15107 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15108 mips32_op
= OPC_CVT_L_S
;
15110 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15111 mips32_op
= OPC_CVT_L_D
;
15113 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15114 mips32_op
= OPC_CVT_W_S
;
15116 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15117 mips32_op
= OPC_CVT_W_D
;
15120 /* Paired-foo conversions */
15121 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15122 mips32_op
= OPC_CVT_S_PL
;
15124 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15125 mips32_op
= OPC_CVT_S_PU
;
15127 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15128 mips32_op
= OPC_CVT_PW_PS
;
15130 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15131 mips32_op
= OPC_CVT_PS_PW
;
15134 /* Floating-point moves */
15135 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15136 mips32_op
= OPC_MOV_S
;
15138 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15139 mips32_op
= OPC_MOV_D
;
15141 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15142 mips32_op
= OPC_MOV_PS
;
15145 /* Absolute value */
15146 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15147 mips32_op
= OPC_ABS_S
;
15149 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15150 mips32_op
= OPC_ABS_D
;
15152 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15153 mips32_op
= OPC_ABS_PS
;
15157 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15158 mips32_op
= OPC_NEG_S
;
15160 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15161 mips32_op
= OPC_NEG_D
;
15163 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15164 mips32_op
= OPC_NEG_PS
;
15167 /* Reciprocal square root step */
15168 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15169 mips32_op
= OPC_RSQRT1_S
;
15171 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15172 mips32_op
= OPC_RSQRT1_D
;
15174 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15175 mips32_op
= OPC_RSQRT1_PS
;
15178 /* Reciprocal step */
15179 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15180 mips32_op
= OPC_RECIP1_S
;
15182 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15183 mips32_op
= OPC_RECIP1_S
;
15185 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15186 mips32_op
= OPC_RECIP1_PS
;
15189 /* Conversions from double */
15190 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15191 mips32_op
= OPC_CVT_D_S
;
15193 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15194 mips32_op
= OPC_CVT_D_W
;
15196 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15197 mips32_op
= OPC_CVT_D_L
;
15200 /* Conversions from single */
15201 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15202 mips32_op
= OPC_CVT_S_D
;
15204 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15205 mips32_op
= OPC_CVT_S_W
;
15207 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15208 mips32_op
= OPC_CVT_S_L
;
15210 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15213 /* Conditional moves on floating-point codes */
15214 case COND_FLOAT_MOV(MOVT
, 0):
15215 case COND_FLOAT_MOV(MOVT
, 1):
15216 case COND_FLOAT_MOV(MOVT
, 2):
15217 case COND_FLOAT_MOV(MOVT
, 3):
15218 case COND_FLOAT_MOV(MOVT
, 4):
15219 case COND_FLOAT_MOV(MOVT
, 5):
15220 case COND_FLOAT_MOV(MOVT
, 6):
15221 case COND_FLOAT_MOV(MOVT
, 7):
15222 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15223 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15225 case COND_FLOAT_MOV(MOVF
, 0):
15226 case COND_FLOAT_MOV(MOVF
, 1):
15227 case COND_FLOAT_MOV(MOVF
, 2):
15228 case COND_FLOAT_MOV(MOVF
, 3):
15229 case COND_FLOAT_MOV(MOVF
, 4):
15230 case COND_FLOAT_MOV(MOVF
, 5):
15231 case COND_FLOAT_MOV(MOVF
, 6):
15232 case COND_FLOAT_MOV(MOVF
, 7):
15233 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15234 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15237 MIPS_INVAL("pool32fxf");
15238 gen_reserved_instruction(ctx
);
15243 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15247 int rt
, rs
, rd
, rr
;
15249 uint32_t op
, minor
, minor2
, mips32_op
;
15250 uint32_t cond
, fmt
, cc
;
15252 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15253 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15255 rt
= (ctx
->opcode
>> 21) & 0x1f;
15256 rs
= (ctx
->opcode
>> 16) & 0x1f;
15257 rd
= (ctx
->opcode
>> 11) & 0x1f;
15258 rr
= (ctx
->opcode
>> 6) & 0x1f;
15259 imm
= (int16_t) ctx
->opcode
;
15261 op
= (ctx
->opcode
>> 26) & 0x3f;
15264 minor
= ctx
->opcode
& 0x3f;
15267 minor
= (ctx
->opcode
>> 6) & 0xf;
15270 mips32_op
= OPC_SLL
;
15273 mips32_op
= OPC_SRA
;
15276 mips32_op
= OPC_SRL
;
15279 mips32_op
= OPC_ROTR
;
15281 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15284 check_insn(ctx
, ISA_MIPS_R6
);
15285 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15288 check_insn(ctx
, ISA_MIPS_R6
);
15289 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15292 check_insn(ctx
, ISA_MIPS_R6
);
15293 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15296 goto pool32a_invalid
;
15300 minor
= (ctx
->opcode
>> 6) & 0xf;
15304 mips32_op
= OPC_ADD
;
15307 mips32_op
= OPC_ADDU
;
15310 mips32_op
= OPC_SUB
;
15313 mips32_op
= OPC_SUBU
;
15316 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15317 mips32_op
= OPC_MUL
;
15319 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15323 mips32_op
= OPC_SLLV
;
15326 mips32_op
= OPC_SRLV
;
15329 mips32_op
= OPC_SRAV
;
15332 mips32_op
= OPC_ROTRV
;
15334 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15336 /* Logical operations */
15338 mips32_op
= OPC_AND
;
15341 mips32_op
= OPC_OR
;
15344 mips32_op
= OPC_NOR
;
15347 mips32_op
= OPC_XOR
;
15349 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15351 /* Set less than */
15353 mips32_op
= OPC_SLT
;
15356 mips32_op
= OPC_SLTU
;
15358 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15361 goto pool32a_invalid
;
15365 minor
= (ctx
->opcode
>> 6) & 0xf;
15367 /* Conditional moves */
15368 case MOVN
: /* MUL */
15369 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15371 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15374 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15377 case MOVZ
: /* MUH */
15378 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15380 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15383 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15387 check_insn(ctx
, ISA_MIPS_R6
);
15388 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15391 check_insn(ctx
, ISA_MIPS_R6
);
15392 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15394 case LWXS
: /* DIV */
15395 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15397 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15400 gen_ldxs(ctx
, rs
, rt
, rd
);
15404 check_insn(ctx
, ISA_MIPS_R6
);
15405 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15408 check_insn(ctx
, ISA_MIPS_R6
);
15409 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15412 check_insn(ctx
, ISA_MIPS_R6
);
15413 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15416 goto pool32a_invalid
;
15420 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15423 check_insn(ctx
, ISA_MIPS_R6
);
15424 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15427 check_insn(ctx
, ISA_MIPS_R6
);
15428 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15431 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15434 gen_pool32axf(env
, ctx
, rt
, rs
);
15437 generate_exception_end(ctx
, EXCP_BREAK
);
15440 check_insn(ctx
, ISA_MIPS_R6
);
15441 gen_reserved_instruction(ctx
);
15445 MIPS_INVAL("pool32a");
15446 gen_reserved_instruction(ctx
);
15451 minor
= (ctx
->opcode
>> 12) & 0xf;
15454 check_cp0_enabled(ctx
);
15455 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15456 gen_cache_operation(ctx
, rt
, rs
, imm
);
15461 /* COP2: Not implemented. */
15462 generate_exception_err(ctx
, EXCP_CpU
, 2);
15464 #ifdef TARGET_MIPS64
15467 check_insn(ctx
, ISA_MIPS3
);
15468 check_mips_64(ctx
);
15473 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15475 #ifdef TARGET_MIPS64
15478 check_insn(ctx
, ISA_MIPS3
);
15479 check_mips_64(ctx
);
15484 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15487 MIPS_INVAL("pool32b");
15488 gen_reserved_instruction(ctx
);
15493 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15494 minor
= ctx
->opcode
& 0x3f;
15495 check_cp1_enabled(ctx
);
15498 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15499 mips32_op
= OPC_ALNV_PS
;
15502 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15503 mips32_op
= OPC_MADD_S
;
15506 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15507 mips32_op
= OPC_MADD_D
;
15510 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15511 mips32_op
= OPC_MADD_PS
;
15514 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15515 mips32_op
= OPC_MSUB_S
;
15518 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15519 mips32_op
= OPC_MSUB_D
;
15522 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15523 mips32_op
= OPC_MSUB_PS
;
15526 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15527 mips32_op
= OPC_NMADD_S
;
15530 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15531 mips32_op
= OPC_NMADD_D
;
15534 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15535 mips32_op
= OPC_NMADD_PS
;
15538 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15539 mips32_op
= OPC_NMSUB_S
;
15542 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15543 mips32_op
= OPC_NMSUB_D
;
15546 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15547 mips32_op
= OPC_NMSUB_PS
;
15549 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15551 case CABS_COND_FMT
:
15552 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15553 cond
= (ctx
->opcode
>> 6) & 0xf;
15554 cc
= (ctx
->opcode
>> 13) & 0x7;
15555 fmt
= (ctx
->opcode
>> 10) & 0x3;
15558 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15561 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15564 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15567 goto pool32f_invalid
;
15571 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15572 cond
= (ctx
->opcode
>> 6) & 0xf;
15573 cc
= (ctx
->opcode
>> 13) & 0x7;
15574 fmt
= (ctx
->opcode
>> 10) & 0x3;
15577 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15580 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15583 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15586 goto pool32f_invalid
;
15590 check_insn(ctx
, ISA_MIPS_R6
);
15591 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15594 check_insn(ctx
, ISA_MIPS_R6
);
15595 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15598 gen_pool32fxf(ctx
, rt
, rs
);
15602 switch ((ctx
->opcode
>> 6) & 0x7) {
15604 mips32_op
= OPC_PLL_PS
;
15607 mips32_op
= OPC_PLU_PS
;
15610 mips32_op
= OPC_PUL_PS
;
15613 mips32_op
= OPC_PUU_PS
;
15616 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15617 mips32_op
= OPC_CVT_PS_S
;
15619 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15622 goto pool32f_invalid
;
15626 check_insn(ctx
, ISA_MIPS_R6
);
15627 switch ((ctx
->opcode
>> 9) & 0x3) {
15629 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15632 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15635 goto pool32f_invalid
;
15640 switch ((ctx
->opcode
>> 6) & 0x7) {
15642 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15643 mips32_op
= OPC_LWXC1
;
15646 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15647 mips32_op
= OPC_SWXC1
;
15650 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15651 mips32_op
= OPC_LDXC1
;
15654 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15655 mips32_op
= OPC_SDXC1
;
15658 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15659 mips32_op
= OPC_LUXC1
;
15662 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15663 mips32_op
= OPC_SUXC1
;
15665 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
15668 goto pool32f_invalid
;
15672 check_insn(ctx
, ISA_MIPS_R6
);
15673 switch ((ctx
->opcode
>> 9) & 0x3) {
15675 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
15678 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
15681 goto pool32f_invalid
;
15686 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15687 fmt
= (ctx
->opcode
>> 9) & 0x3;
15688 switch ((ctx
->opcode
>> 6) & 0x7) {
15692 mips32_op
= OPC_RSQRT2_S
;
15695 mips32_op
= OPC_RSQRT2_D
;
15698 mips32_op
= OPC_RSQRT2_PS
;
15701 goto pool32f_invalid
;
15707 mips32_op
= OPC_RECIP2_S
;
15710 mips32_op
= OPC_RECIP2_D
;
15713 mips32_op
= OPC_RECIP2_PS
;
15716 goto pool32f_invalid
;
15720 mips32_op
= OPC_ADDR_PS
;
15723 mips32_op
= OPC_MULR_PS
;
15725 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15728 goto pool32f_invalid
;
15732 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15733 cc
= (ctx
->opcode
>> 13) & 0x7;
15734 fmt
= (ctx
->opcode
>> 9) & 0x3;
15735 switch ((ctx
->opcode
>> 6) & 0x7) {
15736 case MOVF_FMT
: /* RINT_FMT */
15737 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15741 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
15744 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
15747 goto pool32f_invalid
;
15753 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
15756 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
15760 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
15763 goto pool32f_invalid
;
15767 case MOVT_FMT
: /* CLASS_FMT */
15768 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15772 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
15775 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
15778 goto pool32f_invalid
;
15784 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
15787 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
15791 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
15794 goto pool32f_invalid
;
15799 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15802 goto pool32f_invalid
;
15805 #define FINSN_3ARG_SDPS(prfx) \
15806 switch ((ctx->opcode >> 8) & 0x3) { \
15808 mips32_op = OPC_##prfx##_S; \
15811 mips32_op = OPC_##prfx##_D; \
15813 case FMT_SDPS_PS: \
15815 mips32_op = OPC_##prfx##_PS; \
15818 goto pool32f_invalid; \
15821 check_insn(ctx
, ISA_MIPS_R6
);
15822 switch ((ctx
->opcode
>> 9) & 0x3) {
15824 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
15827 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
15830 goto pool32f_invalid
;
15834 check_insn(ctx
, ISA_MIPS_R6
);
15835 switch ((ctx
->opcode
>> 9) & 0x3) {
15837 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
15840 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
15843 goto pool32f_invalid
;
15847 /* regular FP ops */
15848 switch ((ctx
->opcode
>> 6) & 0x3) {
15850 FINSN_3ARG_SDPS(ADD
);
15853 FINSN_3ARG_SDPS(SUB
);
15856 FINSN_3ARG_SDPS(MUL
);
15859 fmt
= (ctx
->opcode
>> 8) & 0x3;
15861 mips32_op
= OPC_DIV_D
;
15862 } else if (fmt
== 0) {
15863 mips32_op
= OPC_DIV_S
;
15865 goto pool32f_invalid
;
15869 goto pool32f_invalid
;
15874 switch ((ctx
->opcode
>> 6) & 0x7) {
15875 case MOVN_FMT
: /* SELEQZ_FMT */
15876 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15878 switch ((ctx
->opcode
>> 9) & 0x3) {
15880 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
15883 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
15886 goto pool32f_invalid
;
15890 FINSN_3ARG_SDPS(MOVN
);
15894 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15895 FINSN_3ARG_SDPS(MOVN
);
15897 case MOVZ_FMT
: /* SELNEZ_FMT */
15898 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15900 switch ((ctx
->opcode
>> 9) & 0x3) {
15902 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
15905 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
15908 goto pool32f_invalid
;
15912 FINSN_3ARG_SDPS(MOVZ
);
15916 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15917 FINSN_3ARG_SDPS(MOVZ
);
15920 check_insn(ctx
, ISA_MIPS_R6
);
15921 switch ((ctx
->opcode
>> 9) & 0x3) {
15923 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
15926 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
15929 goto pool32f_invalid
;
15933 check_insn(ctx
, ISA_MIPS_R6
);
15934 switch ((ctx
->opcode
>> 9) & 0x3) {
15936 mips32_op
= OPC_MADDF_S
;
15939 mips32_op
= OPC_MADDF_D
;
15942 goto pool32f_invalid
;
15946 check_insn(ctx
, ISA_MIPS_R6
);
15947 switch ((ctx
->opcode
>> 9) & 0x3) {
15949 mips32_op
= OPC_MSUBF_S
;
15952 mips32_op
= OPC_MSUBF_D
;
15955 goto pool32f_invalid
;
15959 goto pool32f_invalid
;
15963 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15967 MIPS_INVAL("pool32f");
15968 gen_reserved_instruction(ctx
);
15972 generate_exception_err(ctx
, EXCP_CpU
, 1);
15976 minor
= (ctx
->opcode
>> 21) & 0x1f;
15979 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15980 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
15983 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15984 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
15985 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15988 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15989 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
15990 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15993 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15994 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
15997 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15998 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
15999 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16002 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16003 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16004 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16007 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16008 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16011 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16012 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16016 case TLTI
: /* BC1EQZC */
16017 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16019 check_cp1_enabled(ctx
);
16020 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16023 mips32_op
= OPC_TLTI
;
16027 case TGEI
: /* BC1NEZC */
16028 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16030 check_cp1_enabled(ctx
);
16031 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16034 mips32_op
= OPC_TGEI
;
16039 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16040 mips32_op
= OPC_TLTIU
;
16043 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16044 mips32_op
= OPC_TGEIU
;
16046 case TNEI
: /* SYNCI */
16047 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16050 * Break the TB to be able to sync copied instructions
16053 ctx
->base
.is_jmp
= DISAS_STOP
;
16056 mips32_op
= OPC_TNEI
;
16061 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16062 mips32_op
= OPC_TEQI
;
16064 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16069 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16070 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16071 4, rs
, 0, imm
<< 1, 0);
16073 * Compact branches don't have a delay slot, so just let
16074 * the normal delay slot handling take us to the branch
16079 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16080 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16083 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16085 * Break the TB to be able to sync copied instructions
16088 ctx
->base
.is_jmp
= DISAS_STOP
;
16092 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16093 /* COP2: Not implemented. */
16094 generate_exception_err(ctx
, EXCP_CpU
, 2);
16097 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16098 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16101 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16102 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16105 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16106 mips32_op
= OPC_BC1FANY4
;
16109 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16110 mips32_op
= OPC_BC1TANY4
;
16113 check_insn(ctx
, ASE_MIPS3D
);
16116 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16117 check_cp1_enabled(ctx
);
16118 gen_compute_branch1(ctx
, mips32_op
,
16119 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16121 generate_exception_err(ctx
, EXCP_CpU
, 1);
16126 /* MIPS DSP: not implemented */
16129 MIPS_INVAL("pool32i");
16130 gen_reserved_instruction(ctx
);
16135 minor
= (ctx
->opcode
>> 12) & 0xf;
16136 offset
= sextract32(ctx
->opcode
, 0,
16137 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16140 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16141 mips32_op
= OPC_LWL
;
16144 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16145 mips32_op
= OPC_SWL
;
16148 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16149 mips32_op
= OPC_LWR
;
16152 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16153 mips32_op
= OPC_SWR
;
16155 #if defined(TARGET_MIPS64)
16157 check_insn(ctx
, ISA_MIPS3
);
16158 check_mips_64(ctx
);
16159 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16160 mips32_op
= OPC_LDL
;
16163 check_insn(ctx
, ISA_MIPS3
);
16164 check_mips_64(ctx
);
16165 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16166 mips32_op
= OPC_SDL
;
16169 check_insn(ctx
, ISA_MIPS3
);
16170 check_mips_64(ctx
);
16171 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16172 mips32_op
= OPC_LDR
;
16175 check_insn(ctx
, ISA_MIPS3
);
16176 check_mips_64(ctx
);
16177 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16178 mips32_op
= OPC_SDR
;
16181 check_insn(ctx
, ISA_MIPS3
);
16182 check_mips_64(ctx
);
16183 mips32_op
= OPC_LWU
;
16186 check_insn(ctx
, ISA_MIPS3
);
16187 check_mips_64(ctx
);
16188 mips32_op
= OPC_LLD
;
16192 mips32_op
= OPC_LL
;
16195 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16198 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16201 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16203 #if defined(TARGET_MIPS64)
16205 check_insn(ctx
, ISA_MIPS3
);
16206 check_mips_64(ctx
);
16207 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16212 MIPS_INVAL("pool32c ld-eva");
16213 gen_reserved_instruction(ctx
);
16216 check_cp0_enabled(ctx
);
16218 minor2
= (ctx
->opcode
>> 9) & 0x7;
16219 offset
= sextract32(ctx
->opcode
, 0, 9);
16222 mips32_op
= OPC_LBUE
;
16225 mips32_op
= OPC_LHUE
;
16228 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16229 mips32_op
= OPC_LWLE
;
16232 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16233 mips32_op
= OPC_LWRE
;
16236 mips32_op
= OPC_LBE
;
16239 mips32_op
= OPC_LHE
;
16242 mips32_op
= OPC_LLE
;
16245 mips32_op
= OPC_LWE
;
16251 MIPS_INVAL("pool32c st-eva");
16252 gen_reserved_instruction(ctx
);
16255 check_cp0_enabled(ctx
);
16257 minor2
= (ctx
->opcode
>> 9) & 0x7;
16258 offset
= sextract32(ctx
->opcode
, 0, 9);
16261 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16262 mips32_op
= OPC_SWLE
;
16265 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16266 mips32_op
= OPC_SWRE
;
16269 /* Treat as no-op */
16270 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16271 /* hint codes 24-31 are reserved and signal RI */
16272 generate_exception(ctx
, EXCP_RI
);
16276 /* Treat as no-op */
16277 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16278 gen_cache_operation(ctx
, rt
, rs
, offset
);
16282 mips32_op
= OPC_SBE
;
16285 mips32_op
= OPC_SHE
;
16288 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16291 mips32_op
= OPC_SWE
;
16296 /* Treat as no-op */
16297 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16298 /* hint codes 24-31 are reserved and signal RI */
16299 generate_exception(ctx
, EXCP_RI
);
16303 MIPS_INVAL("pool32c");
16304 gen_reserved_instruction(ctx
);
16308 case ADDI32
: /* AUI, LUI */
16309 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16311 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16314 mips32_op
= OPC_ADDI
;
16319 mips32_op
= OPC_ADDIU
;
16321 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16324 /* Logical operations */
16326 mips32_op
= OPC_ORI
;
16329 mips32_op
= OPC_XORI
;
16332 mips32_op
= OPC_ANDI
;
16334 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16337 /* Set less than immediate */
16339 mips32_op
= OPC_SLTI
;
16342 mips32_op
= OPC_SLTIU
;
16344 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16347 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16348 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16349 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16350 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16352 case JALS32
: /* BOVC, BEQC, BEQZALC */
16353 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16356 mips32_op
= OPC_BOVC
;
16357 } else if (rs
< rt
&& rs
== 0) {
16359 mips32_op
= OPC_BEQZALC
;
16362 mips32_op
= OPC_BEQC
;
16364 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16367 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16368 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16369 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16372 case BEQ32
: /* BC */
16373 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16375 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16376 sextract32(ctx
->opcode
<< 1, 0, 27));
16379 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16382 case BNE32
: /* BALC */
16383 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16385 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16386 sextract32(ctx
->opcode
<< 1, 0, 27));
16389 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16392 case J32
: /* BGTZC, BLTZC, BLTC */
16393 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16394 if (rs
== 0 && rt
!= 0) {
16396 mips32_op
= OPC_BGTZC
;
16397 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16399 mips32_op
= OPC_BLTZC
;
16402 mips32_op
= OPC_BLTC
;
16404 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16407 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16408 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16411 case JAL32
: /* BLEZC, BGEZC, BGEC */
16412 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16413 if (rs
== 0 && rt
!= 0) {
16415 mips32_op
= OPC_BLEZC
;
16416 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16418 mips32_op
= OPC_BGEZC
;
16421 mips32_op
= OPC_BGEC
;
16423 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16426 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16427 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16428 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16431 /* Floating point (COP1) */
16433 mips32_op
= OPC_LWC1
;
16436 mips32_op
= OPC_LDC1
;
16439 mips32_op
= OPC_SWC1
;
16442 mips32_op
= OPC_SDC1
;
16444 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16446 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16447 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16448 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16449 switch ((ctx
->opcode
>> 16) & 0x1f) {
16458 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16461 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16464 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16474 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16477 generate_exception(ctx
, EXCP_RI
);
16482 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16483 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16485 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16488 case BNVC
: /* BNEC, BNEZALC */
16489 check_insn(ctx
, ISA_MIPS_R6
);
16492 mips32_op
= OPC_BNVC
;
16493 } else if (rs
< rt
&& rs
== 0) {
16495 mips32_op
= OPC_BNEZALC
;
16498 mips32_op
= OPC_BNEC
;
16500 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16502 case R6_BNEZC
: /* JIALC */
16503 check_insn(ctx
, ISA_MIPS_R6
);
16506 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16507 sextract32(ctx
->opcode
<< 1, 0, 22));
16510 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16513 case R6_BEQZC
: /* JIC */
16514 check_insn(ctx
, ISA_MIPS_R6
);
16517 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16518 sextract32(ctx
->opcode
<< 1, 0, 22));
16521 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16524 case BLEZALC
: /* BGEZALC, BGEUC */
16525 check_insn(ctx
, ISA_MIPS_R6
);
16526 if (rs
== 0 && rt
!= 0) {
16528 mips32_op
= OPC_BLEZALC
;
16529 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16531 mips32_op
= OPC_BGEZALC
;
16534 mips32_op
= OPC_BGEUC
;
16536 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16538 case BGTZALC
: /* BLTZALC, BLTUC */
16539 check_insn(ctx
, ISA_MIPS_R6
);
16540 if (rs
== 0 && rt
!= 0) {
16542 mips32_op
= OPC_BGTZALC
;
16543 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16545 mips32_op
= OPC_BLTZALC
;
16548 mips32_op
= OPC_BLTUC
;
16550 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16552 /* Loads and stores */
16554 mips32_op
= OPC_LB
;
16557 mips32_op
= OPC_LBU
;
16560 mips32_op
= OPC_LH
;
16563 mips32_op
= OPC_LHU
;
16566 mips32_op
= OPC_LW
;
16568 #ifdef TARGET_MIPS64
16570 check_insn(ctx
, ISA_MIPS3
);
16571 check_mips_64(ctx
);
16572 mips32_op
= OPC_LD
;
16575 check_insn(ctx
, ISA_MIPS3
);
16576 check_mips_64(ctx
);
16577 mips32_op
= OPC_SD
;
16581 mips32_op
= OPC_SB
;
16584 mips32_op
= OPC_SH
;
16587 mips32_op
= OPC_SW
;
16590 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16593 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16596 gen_reserved_instruction(ctx
);
16601 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16605 /* make sure instructions are on a halfword boundary */
16606 if (ctx
->base
.pc_next
& 0x1) {
16607 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16608 generate_exception_end(ctx
, EXCP_AdEL
);
16612 op
= (ctx
->opcode
>> 10) & 0x3f;
16613 /* Enforce properly-sized instructions in a delay slot */
16614 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16615 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16617 /* POOL32A, POOL32B, POOL32I, POOL32C */
16619 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16621 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16623 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16625 /* LB32, LH32, LWC132, LDC132, LW32 */
16626 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16627 gen_reserved_instruction(ctx
);
16632 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16634 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16636 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16637 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16638 gen_reserved_instruction(ctx
);
16648 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16649 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
16650 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
16653 switch (ctx
->opcode
& 0x1) {
16661 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16663 * In the Release 6, the register number location in
16664 * the instruction encoding has changed.
16666 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
16668 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
16674 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16675 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
16676 int amount
= (ctx
->opcode
>> 1) & 0x7;
16678 amount
= amount
== 0 ? 8 : amount
;
16680 switch (ctx
->opcode
& 0x1) {
16689 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
16693 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16694 gen_pool16c_r6_insn(ctx
);
16696 gen_pool16c_insn(ctx
);
16701 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16702 int rb
= 28; /* GP */
16703 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
16705 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16709 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16710 if (ctx
->opcode
& 1) {
16711 gen_reserved_instruction(ctx
);
16714 int enc_dest
= uMIPS_RD(ctx
->opcode
);
16715 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
16716 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
16717 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
16722 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16723 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16724 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16725 offset
= (offset
== 0xf ? -1 : offset
);
16727 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
16732 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16733 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16734 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16736 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
16741 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16742 int rb
= 29; /* SP */
16743 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16745 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16750 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16751 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16752 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16754 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16759 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16760 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16761 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16763 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
16768 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16769 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16770 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16772 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
16777 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16778 int rb
= 29; /* SP */
16779 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16781 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16786 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16787 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16788 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16790 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16795 int rd
= uMIPS_RD5(ctx
->opcode
);
16796 int rs
= uMIPS_RS5(ctx
->opcode
);
16798 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
16805 switch (ctx
->opcode
& 0x1) {
16815 switch (ctx
->opcode
& 0x1) {
16820 gen_addiur1sp(ctx
);
16824 case B16
: /* BC16 */
16825 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
16826 sextract32(ctx
->opcode
, 0, 10) << 1,
16827 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16829 case BNEZ16
: /* BNEZC16 */
16830 case BEQZ16
: /* BEQZC16 */
16831 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
16832 mmreg(uMIPS_RD(ctx
->opcode
)),
16833 0, sextract32(ctx
->opcode
, 0, 7) << 1,
16834 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16839 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
16840 int imm
= ZIMM(ctx
->opcode
, 0, 7);
16842 imm
= (imm
== 0x7f ? -1 : imm
);
16843 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
16849 gen_reserved_instruction(ctx
);
16852 decode_micromips32_opc(env
, ctx
);
16865 /* MAJOR, P16, and P32 pools opcodes */
16869 NM_MOVE_BALC
= 0x02,
16877 NM_P16_SHIFT
= 0x0c,
16895 NM_P_LS_U12
= 0x21,
16905 NM_P16_ADDU
= 0x2c,
16919 NM_MOVEPREV
= 0x3f,
16922 /* POOL32A instruction pool */
16924 NM_POOL32A0
= 0x00,
16925 NM_SPECIAL2
= 0x01,
16928 NM_POOL32A5
= 0x05,
16929 NM_POOL32A7
= 0x07,
16932 /* P.GP.W instruction pool */
16934 NM_ADDIUGP_W
= 0x00,
16939 /* P48I instruction pool */
16943 NM_ADDIUGP48
= 0x02,
16944 NM_ADDIUPC48
= 0x03,
16949 /* P.U12 instruction pool */
16958 NM_ADDIUNEG
= 0x08,
16965 /* POOL32F instruction pool */
16967 NM_POOL32F_0
= 0x00,
16968 NM_POOL32F_3
= 0x03,
16969 NM_POOL32F_5
= 0x05,
16972 /* POOL32S instruction pool */
16974 NM_POOL32S_0
= 0x00,
16975 NM_POOL32S_4
= 0x04,
16978 /* P.LUI instruction pool */
16984 /* P.GP.BH instruction pool */
16989 NM_ADDIUGP_B
= 0x03,
16992 NM_P_GP_CP1
= 0x06,
16995 /* P.LS.U12 instruction pool */
17000 NM_P_PREFU12
= 0x03,
17013 /* P.LS.S9 instruction pool */
17019 NM_P_LS_UAWM
= 0x05,
17022 /* P.BAL instruction pool */
17028 /* P.J instruction pool */
17031 NM_JALRC_HB
= 0x01,
17032 NM_P_BALRSC
= 0x08,
17035 /* P.BR1 instruction pool */
17043 /* P.BR2 instruction pool */
17050 /* P.BRI instruction pool */
17062 /* P16.SHIFT instruction pool */
17068 /* POOL16C instruction pool */
17070 NM_POOL16C_0
= 0x00,
17074 /* P16.A1 instruction pool */
17076 NM_ADDIUR1SP
= 0x01,
17079 /* P16.A2 instruction pool */
17082 NM_P_ADDIURS5
= 0x01,
17085 /* P16.ADDU instruction pool */
17091 /* P16.SR instruction pool */
17094 NM_RESTORE_JRC16
= 0x01,
17097 /* P16.4X4 instruction pool */
17103 /* P16.LB instruction pool */
17110 /* P16.LH instruction pool */
17117 /* P.RI instruction pool */
17120 NM_P_SYSCALL
= 0x01,
17125 /* POOL32A0 instruction pool */
17160 NM_D_E_MT_VPE
= 0x56,
17168 /* CRC32 instruction pool */
17178 /* POOL32A5 instruction pool */
17180 NM_CMP_EQ_PH
= 0x00,
17181 NM_CMP_LT_PH
= 0x08,
17182 NM_CMP_LE_PH
= 0x10,
17183 NM_CMPGU_EQ_QB
= 0x18,
17184 NM_CMPGU_LT_QB
= 0x20,
17185 NM_CMPGU_LE_QB
= 0x28,
17186 NM_CMPGDU_EQ_QB
= 0x30,
17187 NM_CMPGDU_LT_QB
= 0x38,
17188 NM_CMPGDU_LE_QB
= 0x40,
17189 NM_CMPU_EQ_QB
= 0x48,
17190 NM_CMPU_LT_QB
= 0x50,
17191 NM_CMPU_LE_QB
= 0x58,
17192 NM_ADDQ_S_W
= 0x60,
17193 NM_SUBQ_S_W
= 0x68,
17197 NM_ADDQ_S_PH
= 0x01,
17198 NM_ADDQH_R_PH
= 0x09,
17199 NM_ADDQH_R_W
= 0x11,
17200 NM_ADDU_S_QB
= 0x19,
17201 NM_ADDU_S_PH
= 0x21,
17202 NM_ADDUH_R_QB
= 0x29,
17203 NM_SHRAV_R_PH
= 0x31,
17204 NM_SHRAV_R_QB
= 0x39,
17205 NM_SUBQ_S_PH
= 0x41,
17206 NM_SUBQH_R_PH
= 0x49,
17207 NM_SUBQH_R_W
= 0x51,
17208 NM_SUBU_S_QB
= 0x59,
17209 NM_SUBU_S_PH
= 0x61,
17210 NM_SUBUH_R_QB
= 0x69,
17211 NM_SHLLV_S_PH
= 0x71,
17212 NM_PRECR_SRA_R_PH_W
= 0x79,
17214 NM_MULEU_S_PH_QBL
= 0x12,
17215 NM_MULEU_S_PH_QBR
= 0x1a,
17216 NM_MULQ_RS_PH
= 0x22,
17217 NM_MULQ_S_PH
= 0x2a,
17218 NM_MULQ_RS_W
= 0x32,
17219 NM_MULQ_S_W
= 0x3a,
17222 NM_SHRAV_R_W
= 0x5a,
17223 NM_SHRLV_PH
= 0x62,
17224 NM_SHRLV_QB
= 0x6a,
17225 NM_SHLLV_QB
= 0x72,
17226 NM_SHLLV_S_W
= 0x7a,
17230 NM_MULEQ_S_W_PHL
= 0x04,
17231 NM_MULEQ_S_W_PHR
= 0x0c,
17233 NM_MUL_S_PH
= 0x05,
17234 NM_PRECR_QB_PH
= 0x0d,
17235 NM_PRECRQ_QB_PH
= 0x15,
17236 NM_PRECRQ_PH_W
= 0x1d,
17237 NM_PRECRQ_RS_PH_W
= 0x25,
17238 NM_PRECRQU_S_QB_PH
= 0x2d,
17239 NM_PACKRL_PH
= 0x35,
17243 NM_SHRA_R_W
= 0x5e,
17244 NM_SHRA_R_PH
= 0x66,
17245 NM_SHLL_S_PH
= 0x76,
17246 NM_SHLL_S_W
= 0x7e,
17251 /* POOL32A7 instruction pool */
17256 NM_POOL32AXF
= 0x07,
17259 /* P.SR instruction pool */
17265 /* P.SHIFT instruction pool */
17273 /* P.ROTX instruction pool */
17278 /* P.INS instruction pool */
17283 /* P.EXT instruction pool */
17288 /* POOL32F_0 (fmt) instruction pool */
17293 NM_SELEQZ_S
= 0x07,
17294 NM_SELEQZ_D
= 0x47,
17298 NM_SELNEZ_S
= 0x0f,
17299 NM_SELNEZ_D
= 0x4f,
17314 /* POOL32F_3 instruction pool */
17318 NM_MINA_FMT
= 0x04,
17319 NM_MAXA_FMT
= 0x05,
17320 NM_POOL32FXF
= 0x07,
17323 /* POOL32F_5 instruction pool */
17325 NM_CMP_CONDN_S
= 0x00,
17326 NM_CMP_CONDN_D
= 0x02,
17329 /* P.GP.LH instruction pool */
17335 /* P.GP.SH instruction pool */
17340 /* P.GP.CP1 instruction pool */
17348 /* P.LS.S0 instruction pool */
17365 NM_P_PREFS9
= 0x03,
17371 /* P.LS.S1 instruction pool */
17373 NM_ASET_ACLR
= 0x02,
17381 /* P.LS.E0 instruction pool */
17397 /* P.PREFE instruction pool */
17403 /* P.LLE instruction pool */
17409 /* P.SCE instruction pool */
17415 /* P.LS.WM instruction pool */
17421 /* P.LS.UAWM instruction pool */
17427 /* P.BR3A instruction pool */
17433 NM_BPOSGE32C
= 0x04,
17436 /* P16.RI instruction pool */
17438 NM_P16_SYSCALL
= 0x01,
17443 /* POOL16C_0 instruction pool */
17445 NM_POOL16C_00
= 0x00,
17448 /* P16.JRC instruction pool */
17454 /* P.SYSCALL instruction pool */
17460 /* P.TRAP instruction pool */
17466 /* P.CMOVE instruction pool */
17472 /* POOL32Axf instruction pool */
17474 NM_POOL32AXF_1
= 0x01,
17475 NM_POOL32AXF_2
= 0x02,
17476 NM_POOL32AXF_4
= 0x04,
17477 NM_POOL32AXF_5
= 0x05,
17478 NM_POOL32AXF_7
= 0x07,
17481 /* POOL32Axf_1 instruction pool */
17483 NM_POOL32AXF_1_0
= 0x00,
17484 NM_POOL32AXF_1_1
= 0x01,
17485 NM_POOL32AXF_1_3
= 0x03,
17486 NM_POOL32AXF_1_4
= 0x04,
17487 NM_POOL32AXF_1_5
= 0x05,
17488 NM_POOL32AXF_1_7
= 0x07,
17491 /* POOL32Axf_2 instruction pool */
17493 NM_POOL32AXF_2_0_7
= 0x00,
17494 NM_POOL32AXF_2_8_15
= 0x01,
17495 NM_POOL32AXF_2_16_23
= 0x02,
17496 NM_POOL32AXF_2_24_31
= 0x03,
17499 /* POOL32Axf_7 instruction pool */
17501 NM_SHRA_R_QB
= 0x0,
17506 /* POOL32Axf_1_0 instruction pool */
17514 /* POOL32Axf_1_1 instruction pool */
17520 /* POOL32Axf_1_3 instruction pool */
17528 /* POOL32Axf_1_4 instruction pool */
17534 /* POOL32Axf_1_5 instruction pool */
17536 NM_MAQ_S_W_PHR
= 0x0,
17537 NM_MAQ_S_W_PHL
= 0x1,
17538 NM_MAQ_SA_W_PHR
= 0x2,
17539 NM_MAQ_SA_W_PHL
= 0x3,
17542 /* POOL32Axf_1_7 instruction pool */
17546 NM_EXTR_RS_W
= 0x2,
17550 /* POOL32Axf_2_0_7 instruction pool */
17553 NM_DPAQ_S_W_PH
= 0x1,
17555 NM_DPSQ_S_W_PH
= 0x3,
17562 /* POOL32Axf_2_8_15 instruction pool */
17564 NM_DPAX_W_PH
= 0x0,
17565 NM_DPAQ_SA_L_W
= 0x1,
17566 NM_DPSX_W_PH
= 0x2,
17567 NM_DPSQ_SA_L_W
= 0x3,
17570 NM_EXTRV_R_W
= 0x7,
17573 /* POOL32Axf_2_16_23 instruction pool */
17575 NM_DPAU_H_QBL
= 0x0,
17576 NM_DPAQX_S_W_PH
= 0x1,
17577 NM_DPSU_H_QBL
= 0x2,
17578 NM_DPSQX_S_W_PH
= 0x3,
17581 NM_MULSA_W_PH
= 0x6,
17582 NM_EXTRV_RS_W
= 0x7,
17585 /* POOL32Axf_2_24_31 instruction pool */
17587 NM_DPAU_H_QBR
= 0x0,
17588 NM_DPAQX_SA_W_PH
= 0x1,
17589 NM_DPSU_H_QBR
= 0x2,
17590 NM_DPSQX_SA_W_PH
= 0x3,
17593 NM_MULSAQ_S_W_PH
= 0x6,
17594 NM_EXTRV_S_H
= 0x7,
17597 /* POOL32Axf_{4, 5} instruction pool */
17616 /* nanoMIPS DSP instructions */
17617 NM_ABSQ_S_QB
= 0x00,
17618 NM_ABSQ_S_PH
= 0x08,
17619 NM_ABSQ_S_W
= 0x10,
17620 NM_PRECEQ_W_PHL
= 0x28,
17621 NM_PRECEQ_W_PHR
= 0x30,
17622 NM_PRECEQU_PH_QBL
= 0x38,
17623 NM_PRECEQU_PH_QBR
= 0x48,
17624 NM_PRECEU_PH_QBL
= 0x58,
17625 NM_PRECEU_PH_QBR
= 0x68,
17626 NM_PRECEQU_PH_QBLA
= 0x39,
17627 NM_PRECEQU_PH_QBRA
= 0x49,
17628 NM_PRECEU_PH_QBLA
= 0x59,
17629 NM_PRECEU_PH_QBRA
= 0x69,
17630 NM_REPLV_PH
= 0x01,
17631 NM_REPLV_QB
= 0x09,
17634 NM_RADDU_W_QB
= 0x78,
17640 /* PP.SR instruction pool */
17644 NM_RESTORE_JRC
= 0x03,
17647 /* P.SR.F instruction pool */
17650 NM_RESTOREF
= 0x01,
17653 /* P16.SYSCALL instruction pool */
17655 NM_SYSCALL16
= 0x00,
17656 NM_HYPCALL16
= 0x01,
17659 /* POOL16C_00 instruction pool */
17667 /* PP.LSX and PP.LSXS instruction pool */
17705 /* ERETx instruction pool */
17711 /* POOL32FxF_{0, 1} insturction pool */
17720 NM_CVT_S_PL
= 0x84,
17721 NM_CVT_S_PU
= 0xa4,
17723 NM_CVT_L_S
= 0x004,
17724 NM_CVT_L_D
= 0x104,
17725 NM_CVT_W_S
= 0x024,
17726 NM_CVT_W_D
= 0x124,
17728 NM_RSQRT_S
= 0x008,
17729 NM_RSQRT_D
= 0x108,
17734 NM_RECIP_S
= 0x048,
17735 NM_RECIP_D
= 0x148,
17737 NM_FLOOR_L_S
= 0x00c,
17738 NM_FLOOR_L_D
= 0x10c,
17740 NM_FLOOR_W_S
= 0x02c,
17741 NM_FLOOR_W_D
= 0x12c,
17743 NM_CEIL_L_S
= 0x04c,
17744 NM_CEIL_L_D
= 0x14c,
17745 NM_CEIL_W_S
= 0x06c,
17746 NM_CEIL_W_D
= 0x16c,
17747 NM_TRUNC_L_S
= 0x08c,
17748 NM_TRUNC_L_D
= 0x18c,
17749 NM_TRUNC_W_S
= 0x0ac,
17750 NM_TRUNC_W_D
= 0x1ac,
17751 NM_ROUND_L_S
= 0x0cc,
17752 NM_ROUND_L_D
= 0x1cc,
17753 NM_ROUND_W_S
= 0x0ec,
17754 NM_ROUND_W_D
= 0x1ec,
17762 NM_CVT_D_S
= 0x04d,
17763 NM_CVT_D_W
= 0x0cd,
17764 NM_CVT_D_L
= 0x14d,
17765 NM_CVT_S_D
= 0x06d,
17766 NM_CVT_S_W
= 0x0ed,
17767 NM_CVT_S_L
= 0x16d,
17770 /* P.LL instruction pool */
17776 /* P.SC instruction pool */
17782 /* P.DVP instruction pool */
17791 * nanoMIPS decoding engine
17796 /* extraction utilities */
17798 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17799 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17800 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17801 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17802 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17804 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17805 static inline int decode_gpr_gpr3(int r
)
17807 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17809 return map
[r
& 0x7];
17812 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17813 static inline int decode_gpr_gpr3_src_store(int r
)
17815 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17817 return map
[r
& 0x7];
17820 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17821 static inline int decode_gpr_gpr4(int r
)
17823 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17824 16, 17, 18, 19, 20, 21, 22, 23 };
17826 return map
[r
& 0xf];
17829 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17830 static inline int decode_gpr_gpr4_zero(int r
)
17832 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17833 16, 17, 18, 19, 20, 21, 22, 23 };
17835 return map
[r
& 0xf];
17839 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
17841 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
17844 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17845 uint8_t gp
, uint16_t u
)
17848 TCGv va
= tcg_temp_new();
17849 TCGv t0
= tcg_temp_new();
17851 while (counter
!= count
) {
17852 bool use_gp
= gp
&& (counter
== count
- 1);
17853 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17854 int this_offset
= -((counter
+ 1) << 2);
17855 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17856 gen_load_gpr(t0
, this_rt
);
17857 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
17858 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
17862 /* adjust stack pointer */
17863 gen_adjust_sp(ctx
, -u
);
17869 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17870 uint8_t gp
, uint16_t u
)
17873 TCGv va
= tcg_temp_new();
17874 TCGv t0
= tcg_temp_new();
17876 while (counter
!= count
) {
17877 bool use_gp
= gp
&& (counter
== count
- 1);
17878 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17879 int this_offset
= u
- ((counter
+ 1) << 2);
17880 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17881 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
17882 ctx
->default_tcg_memop_mask
);
17883 tcg_gen_ext32s_tl(t0
, t0
);
17884 gen_store_gpr(t0
, this_rt
);
17888 /* adjust stack pointer */
17889 gen_adjust_sp(ctx
, u
);
17895 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
17897 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
17898 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
17900 switch (extract32(ctx
->opcode
, 2, 2)) {
17902 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
17905 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
17908 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
17911 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
17916 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
17918 int rt
= extract32(ctx
->opcode
, 21, 5);
17919 int rs
= extract32(ctx
->opcode
, 16, 5);
17920 int rd
= extract32(ctx
->opcode
, 11, 5);
17922 switch (extract32(ctx
->opcode
, 3, 7)) {
17924 switch (extract32(ctx
->opcode
, 10, 1)) {
17927 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
17931 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
17937 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
17941 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
17944 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
17947 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
17950 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
17953 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
17956 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
17959 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
17962 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
17966 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
17969 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
17972 switch (extract32(ctx
->opcode
, 10, 1)) {
17974 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
17977 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
17982 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
17985 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
17988 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
17991 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
17994 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
17999 #ifndef CONFIG_USER_ONLY
18000 TCGv t0
= tcg_temp_new();
18001 switch (extract32(ctx
->opcode
, 10, 1)) {
18004 check_cp0_enabled(ctx
);
18005 gen_helper_dvp(t0
, cpu_env
);
18006 gen_store_gpr(t0
, rt
);
18011 check_cp0_enabled(ctx
);
18012 gen_helper_evp(t0
, cpu_env
);
18013 gen_store_gpr(t0
, rt
);
18020 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18025 TCGv t0
= tcg_temp_new();
18026 TCGv t1
= tcg_temp_new();
18027 TCGv t2
= tcg_temp_new();
18029 gen_load_gpr(t1
, rs
);
18030 gen_load_gpr(t2
, rt
);
18031 tcg_gen_add_tl(t0
, t1
, t2
);
18032 tcg_gen_ext32s_tl(t0
, t0
);
18033 tcg_gen_xor_tl(t1
, t1
, t2
);
18034 tcg_gen_xor_tl(t2
, t0
, t2
);
18035 tcg_gen_andc_tl(t1
, t2
, t1
);
18037 /* operands of same sign, result different sign */
18038 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18039 gen_store_gpr(t0
, rd
);
18047 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18050 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18053 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18056 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18059 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18062 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18065 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18068 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18070 #ifndef CONFIG_USER_ONLY
18072 check_cp0_enabled(ctx
);
18074 /* Treat as NOP. */
18077 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18080 check_cp0_enabled(ctx
);
18082 TCGv t0
= tcg_temp_new();
18084 gen_load_gpr(t0
, rt
);
18085 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18089 case NM_D_E_MT_VPE
:
18091 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18092 TCGv t0
= tcg_temp_new();
18099 gen_helper_dmt(t0
);
18100 gen_store_gpr(t0
, rt
);
18101 } else if (rs
== 0) {
18104 gen_helper_dvpe(t0
, cpu_env
);
18105 gen_store_gpr(t0
, rt
);
18107 gen_reserved_instruction(ctx
);
18114 gen_helper_emt(t0
);
18115 gen_store_gpr(t0
, rt
);
18116 } else if (rs
== 0) {
18119 gen_helper_evpe(t0
, cpu_env
);
18120 gen_store_gpr(t0
, rt
);
18122 gen_reserved_instruction(ctx
);
18133 TCGv t0
= tcg_temp_new();
18134 TCGv t1
= tcg_temp_new();
18136 gen_load_gpr(t0
, rt
);
18137 gen_load_gpr(t1
, rs
);
18138 gen_helper_fork(t0
, t1
);
18145 check_cp0_enabled(ctx
);
18147 /* Treat as NOP. */
18150 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18151 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18155 check_cp0_enabled(ctx
);
18156 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18157 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18162 TCGv t0
= tcg_temp_new();
18164 gen_load_gpr(t0
, rs
);
18165 gen_helper_yield(t0
, cpu_env
, t0
);
18166 gen_store_gpr(t0
, rt
);
18172 gen_reserved_instruction(ctx
);
18178 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18179 int ret
, int v1
, int v2
)
18185 t0
= tcg_temp_new_i32();
18187 v0_t
= tcg_temp_new();
18188 v1_t
= tcg_temp_new();
18190 tcg_gen_movi_i32(t0
, v2
>> 3);
18192 gen_load_gpr(v0_t
, ret
);
18193 gen_load_gpr(v1_t
, v1
);
18196 case NM_MAQ_S_W_PHR
:
18198 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18200 case NM_MAQ_S_W_PHL
:
18202 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18204 case NM_MAQ_SA_W_PHR
:
18206 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18208 case NM_MAQ_SA_W_PHL
:
18210 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18213 gen_reserved_instruction(ctx
);
18217 tcg_temp_free_i32(t0
);
18219 tcg_temp_free(v0_t
);
18220 tcg_temp_free(v1_t
);
18224 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18225 int ret
, int v1
, int v2
)
18228 TCGv t0
= tcg_temp_new();
18229 TCGv t1
= tcg_temp_new();
18230 TCGv v0_t
= tcg_temp_new();
18232 gen_load_gpr(v0_t
, v1
);
18235 case NM_POOL32AXF_1_0
:
18237 switch (extract32(ctx
->opcode
, 12, 2)) {
18239 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18242 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18245 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18248 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18252 case NM_POOL32AXF_1_1
:
18254 switch (extract32(ctx
->opcode
, 12, 2)) {
18256 tcg_gen_movi_tl(t0
, v2
);
18257 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18260 tcg_gen_movi_tl(t0
, v2
>> 3);
18261 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18264 gen_reserved_instruction(ctx
);
18268 case NM_POOL32AXF_1_3
:
18270 imm
= extract32(ctx
->opcode
, 14, 7);
18271 switch (extract32(ctx
->opcode
, 12, 2)) {
18273 tcg_gen_movi_tl(t0
, imm
);
18274 gen_helper_rddsp(t0
, t0
, cpu_env
);
18275 gen_store_gpr(t0
, ret
);
18278 gen_load_gpr(t0
, ret
);
18279 tcg_gen_movi_tl(t1
, imm
);
18280 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18283 tcg_gen_movi_tl(t0
, v2
>> 3);
18284 tcg_gen_movi_tl(t1
, v1
);
18285 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18286 gen_store_gpr(t0
, ret
);
18289 tcg_gen_movi_tl(t0
, v2
>> 3);
18290 tcg_gen_movi_tl(t1
, v1
);
18291 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18292 gen_store_gpr(t0
, ret
);
18296 case NM_POOL32AXF_1_4
:
18298 tcg_gen_movi_tl(t0
, v2
>> 2);
18299 switch (extract32(ctx
->opcode
, 12, 1)) {
18301 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18302 gen_store_gpr(t0
, ret
);
18305 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18306 gen_store_gpr(t0
, ret
);
18310 case NM_POOL32AXF_1_5
:
18311 opc
= extract32(ctx
->opcode
, 12, 2);
18312 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18314 case NM_POOL32AXF_1_7
:
18316 tcg_gen_movi_tl(t0
, v2
>> 3);
18317 tcg_gen_movi_tl(t1
, v1
);
18318 switch (extract32(ctx
->opcode
, 12, 2)) {
18320 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18321 gen_store_gpr(t0
, ret
);
18324 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18325 gen_store_gpr(t0
, ret
);
18328 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18329 gen_store_gpr(t0
, ret
);
18332 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18333 gen_store_gpr(t0
, ret
);
18338 gen_reserved_instruction(ctx
);
18344 tcg_temp_free(v0_t
);
18347 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18348 TCGv v0
, TCGv v1
, int rd
)
18352 t0
= tcg_temp_new_i32();
18354 tcg_gen_movi_i32(t0
, rd
>> 3);
18357 case NM_POOL32AXF_2_0_7
:
18358 switch (extract32(ctx
->opcode
, 9, 3)) {
18361 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18363 case NM_DPAQ_S_W_PH
:
18365 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18369 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18371 case NM_DPSQ_S_W_PH
:
18373 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18376 gen_reserved_instruction(ctx
);
18380 case NM_POOL32AXF_2_8_15
:
18381 switch (extract32(ctx
->opcode
, 9, 3)) {
18384 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18386 case NM_DPAQ_SA_L_W
:
18388 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18392 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18394 case NM_DPSQ_SA_L_W
:
18396 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18399 gen_reserved_instruction(ctx
);
18403 case NM_POOL32AXF_2_16_23
:
18404 switch (extract32(ctx
->opcode
, 9, 3)) {
18405 case NM_DPAU_H_QBL
:
18407 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18409 case NM_DPAQX_S_W_PH
:
18411 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18413 case NM_DPSU_H_QBL
:
18415 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18417 case NM_DPSQX_S_W_PH
:
18419 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18421 case NM_MULSA_W_PH
:
18423 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18426 gen_reserved_instruction(ctx
);
18430 case NM_POOL32AXF_2_24_31
:
18431 switch (extract32(ctx
->opcode
, 9, 3)) {
18432 case NM_DPAU_H_QBR
:
18434 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18436 case NM_DPAQX_SA_W_PH
:
18438 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18440 case NM_DPSU_H_QBR
:
18442 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18444 case NM_DPSQX_SA_W_PH
:
18446 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18448 case NM_MULSAQ_S_W_PH
:
18450 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18453 gen_reserved_instruction(ctx
);
18458 gen_reserved_instruction(ctx
);
18462 tcg_temp_free_i32(t0
);
18465 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18466 int rt
, int rs
, int rd
)
18469 TCGv t0
= tcg_temp_new();
18470 TCGv t1
= tcg_temp_new();
18471 TCGv v0_t
= tcg_temp_new();
18472 TCGv v1_t
= tcg_temp_new();
18474 gen_load_gpr(v0_t
, rt
);
18475 gen_load_gpr(v1_t
, rs
);
18478 case NM_POOL32AXF_2_0_7
:
18479 switch (extract32(ctx
->opcode
, 9, 3)) {
18481 case NM_DPAQ_S_W_PH
:
18483 case NM_DPSQ_S_W_PH
:
18484 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18489 gen_load_gpr(t0
, rs
);
18491 if (rd
!= 0 && rd
!= 2) {
18492 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18493 tcg_gen_ext32u_tl(t0
, t0
);
18494 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18495 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18497 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18503 int acc
= extract32(ctx
->opcode
, 14, 2);
18504 TCGv_i64 t2
= tcg_temp_new_i64();
18505 TCGv_i64 t3
= tcg_temp_new_i64();
18507 gen_load_gpr(t0
, rt
);
18508 gen_load_gpr(t1
, rs
);
18509 tcg_gen_ext_tl_i64(t2
, t0
);
18510 tcg_gen_ext_tl_i64(t3
, t1
);
18511 tcg_gen_mul_i64(t2
, t2
, t3
);
18512 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18513 tcg_gen_add_i64(t2
, t2
, t3
);
18514 tcg_temp_free_i64(t3
);
18515 gen_move_low32(cpu_LO
[acc
], t2
);
18516 gen_move_high32(cpu_HI
[acc
], t2
);
18517 tcg_temp_free_i64(t2
);
18523 int acc
= extract32(ctx
->opcode
, 14, 2);
18524 TCGv_i32 t2
= tcg_temp_new_i32();
18525 TCGv_i32 t3
= tcg_temp_new_i32();
18527 gen_load_gpr(t0
, rs
);
18528 gen_load_gpr(t1
, rt
);
18529 tcg_gen_trunc_tl_i32(t2
, t0
);
18530 tcg_gen_trunc_tl_i32(t3
, t1
);
18531 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18532 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18533 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18534 tcg_temp_free_i32(t2
);
18535 tcg_temp_free_i32(t3
);
18540 gen_load_gpr(v1_t
, rs
);
18541 tcg_gen_movi_tl(t0
, rd
>> 3);
18542 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18543 gen_store_gpr(t0
, ret
);
18547 case NM_POOL32AXF_2_8_15
:
18548 switch (extract32(ctx
->opcode
, 9, 3)) {
18550 case NM_DPAQ_SA_L_W
:
18552 case NM_DPSQ_SA_L_W
:
18553 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18558 int acc
= extract32(ctx
->opcode
, 14, 2);
18559 TCGv_i64 t2
= tcg_temp_new_i64();
18560 TCGv_i64 t3
= tcg_temp_new_i64();
18562 gen_load_gpr(t0
, rs
);
18563 gen_load_gpr(t1
, rt
);
18564 tcg_gen_ext32u_tl(t0
, t0
);
18565 tcg_gen_ext32u_tl(t1
, t1
);
18566 tcg_gen_extu_tl_i64(t2
, t0
);
18567 tcg_gen_extu_tl_i64(t3
, t1
);
18568 tcg_gen_mul_i64(t2
, t2
, t3
);
18569 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18570 tcg_gen_add_i64(t2
, t2
, t3
);
18571 tcg_temp_free_i64(t3
);
18572 gen_move_low32(cpu_LO
[acc
], t2
);
18573 gen_move_high32(cpu_HI
[acc
], t2
);
18574 tcg_temp_free_i64(t2
);
18580 int acc
= extract32(ctx
->opcode
, 14, 2);
18581 TCGv_i32 t2
= tcg_temp_new_i32();
18582 TCGv_i32 t3
= tcg_temp_new_i32();
18584 gen_load_gpr(t0
, rs
);
18585 gen_load_gpr(t1
, rt
);
18586 tcg_gen_trunc_tl_i32(t2
, t0
);
18587 tcg_gen_trunc_tl_i32(t3
, t1
);
18588 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18589 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18590 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18591 tcg_temp_free_i32(t2
);
18592 tcg_temp_free_i32(t3
);
18597 tcg_gen_movi_tl(t0
, rd
>> 3);
18598 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18599 gen_store_gpr(t0
, ret
);
18602 gen_reserved_instruction(ctx
);
18606 case NM_POOL32AXF_2_16_23
:
18607 switch (extract32(ctx
->opcode
, 9, 3)) {
18608 case NM_DPAU_H_QBL
:
18609 case NM_DPAQX_S_W_PH
:
18610 case NM_DPSU_H_QBL
:
18611 case NM_DPSQX_S_W_PH
:
18612 case NM_MULSA_W_PH
:
18613 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18617 tcg_gen_movi_tl(t0
, rd
>> 3);
18618 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18619 gen_store_gpr(t0
, ret
);
18624 int acc
= extract32(ctx
->opcode
, 14, 2);
18625 TCGv_i64 t2
= tcg_temp_new_i64();
18626 TCGv_i64 t3
= tcg_temp_new_i64();
18628 gen_load_gpr(t0
, rs
);
18629 gen_load_gpr(t1
, rt
);
18630 tcg_gen_ext_tl_i64(t2
, t0
);
18631 tcg_gen_ext_tl_i64(t3
, t1
);
18632 tcg_gen_mul_i64(t2
, t2
, t3
);
18633 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18634 tcg_gen_sub_i64(t2
, t3
, t2
);
18635 tcg_temp_free_i64(t3
);
18636 gen_move_low32(cpu_LO
[acc
], t2
);
18637 gen_move_high32(cpu_HI
[acc
], t2
);
18638 tcg_temp_free_i64(t2
);
18641 case NM_EXTRV_RS_W
:
18643 tcg_gen_movi_tl(t0
, rd
>> 3);
18644 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18645 gen_store_gpr(t0
, ret
);
18649 case NM_POOL32AXF_2_24_31
:
18650 switch (extract32(ctx
->opcode
, 9, 3)) {
18651 case NM_DPAU_H_QBR
:
18652 case NM_DPAQX_SA_W_PH
:
18653 case NM_DPSU_H_QBR
:
18654 case NM_DPSQX_SA_W_PH
:
18655 case NM_MULSAQ_S_W_PH
:
18656 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18660 tcg_gen_movi_tl(t0
, rd
>> 3);
18661 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
18662 gen_store_gpr(t0
, ret
);
18667 int acc
= extract32(ctx
->opcode
, 14, 2);
18668 TCGv_i64 t2
= tcg_temp_new_i64();
18669 TCGv_i64 t3
= tcg_temp_new_i64();
18671 gen_load_gpr(t0
, rs
);
18672 gen_load_gpr(t1
, rt
);
18673 tcg_gen_ext32u_tl(t0
, t0
);
18674 tcg_gen_ext32u_tl(t1
, t1
);
18675 tcg_gen_extu_tl_i64(t2
, t0
);
18676 tcg_gen_extu_tl_i64(t3
, t1
);
18677 tcg_gen_mul_i64(t2
, t2
, t3
);
18678 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18679 tcg_gen_sub_i64(t2
, t3
, t2
);
18680 tcg_temp_free_i64(t3
);
18681 gen_move_low32(cpu_LO
[acc
], t2
);
18682 gen_move_high32(cpu_HI
[acc
], t2
);
18683 tcg_temp_free_i64(t2
);
18688 tcg_gen_movi_tl(t0
, rd
>> 3);
18689 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
18690 gen_store_gpr(t0
, ret
);
18695 gen_reserved_instruction(ctx
);
18702 tcg_temp_free(v0_t
);
18703 tcg_temp_free(v1_t
);
18706 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18710 TCGv t0
= tcg_temp_new();
18711 TCGv v0_t
= tcg_temp_new();
18713 gen_load_gpr(v0_t
, rs
);
18718 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
18719 gen_store_gpr(v0_t
, ret
);
18723 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
18724 gen_store_gpr(v0_t
, ret
);
18728 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
18729 gen_store_gpr(v0_t
, ret
);
18731 case NM_PRECEQ_W_PHL
:
18733 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
18734 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18735 gen_store_gpr(v0_t
, ret
);
18737 case NM_PRECEQ_W_PHR
:
18739 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
18740 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
18741 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18742 gen_store_gpr(v0_t
, ret
);
18744 case NM_PRECEQU_PH_QBL
:
18746 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
18747 gen_store_gpr(v0_t
, ret
);
18749 case NM_PRECEQU_PH_QBR
:
18751 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
18752 gen_store_gpr(v0_t
, ret
);
18754 case NM_PRECEQU_PH_QBLA
:
18756 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
18757 gen_store_gpr(v0_t
, ret
);
18759 case NM_PRECEQU_PH_QBRA
:
18761 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
18762 gen_store_gpr(v0_t
, ret
);
18764 case NM_PRECEU_PH_QBL
:
18766 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
18767 gen_store_gpr(v0_t
, ret
);
18769 case NM_PRECEU_PH_QBR
:
18771 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
18772 gen_store_gpr(v0_t
, ret
);
18774 case NM_PRECEU_PH_QBLA
:
18776 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
18777 gen_store_gpr(v0_t
, ret
);
18779 case NM_PRECEU_PH_QBRA
:
18781 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
18782 gen_store_gpr(v0_t
, ret
);
18786 tcg_gen_ext16u_tl(v0_t
, v0_t
);
18787 tcg_gen_shli_tl(t0
, v0_t
, 16);
18788 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18789 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18790 gen_store_gpr(v0_t
, ret
);
18794 tcg_gen_ext8u_tl(v0_t
, v0_t
);
18795 tcg_gen_shli_tl(t0
, v0_t
, 8);
18796 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18797 tcg_gen_shli_tl(t0
, v0_t
, 16);
18798 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18799 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18800 gen_store_gpr(v0_t
, ret
);
18804 gen_helper_bitrev(v0_t
, v0_t
);
18805 gen_store_gpr(v0_t
, ret
);
18810 TCGv tv0
= tcg_temp_new();
18812 gen_load_gpr(tv0
, rt
);
18813 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
18814 gen_store_gpr(v0_t
, ret
);
18815 tcg_temp_free(tv0
);
18818 case NM_RADDU_W_QB
:
18820 gen_helper_raddu_w_qb(v0_t
, v0_t
);
18821 gen_store_gpr(v0_t
, ret
);
18824 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
18828 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
18832 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
18835 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
18838 gen_reserved_instruction(ctx
);
18842 tcg_temp_free(v0_t
);
18846 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18847 int rt
, int rs
, int rd
)
18849 TCGv t0
= tcg_temp_new();
18850 TCGv rs_t
= tcg_temp_new();
18852 gen_load_gpr(rs_t
, rs
);
18857 tcg_gen_movi_tl(t0
, rd
>> 2);
18858 switch (extract32(ctx
->opcode
, 12, 1)) {
18861 gen_helper_shra_qb(t0
, t0
, rs_t
);
18862 gen_store_gpr(t0
, rt
);
18866 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
18867 gen_store_gpr(t0
, rt
);
18873 tcg_gen_movi_tl(t0
, rd
>> 1);
18874 gen_helper_shrl_ph(t0
, t0
, rs_t
);
18875 gen_store_gpr(t0
, rt
);
18881 target_long result
;
18882 imm
= extract32(ctx
->opcode
, 13, 8);
18883 result
= (uint32_t)imm
<< 24 |
18884 (uint32_t)imm
<< 16 |
18885 (uint32_t)imm
<< 8 |
18887 result
= (int32_t)result
;
18888 tcg_gen_movi_tl(t0
, result
);
18889 gen_store_gpr(t0
, rt
);
18893 gen_reserved_instruction(ctx
);
18897 tcg_temp_free(rs_t
);
18901 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18903 int rt
= extract32(ctx
->opcode
, 21, 5);
18904 int rs
= extract32(ctx
->opcode
, 16, 5);
18905 int rd
= extract32(ctx
->opcode
, 11, 5);
18907 switch (extract32(ctx
->opcode
, 6, 3)) {
18908 case NM_POOL32AXF_1
:
18910 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18911 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18914 case NM_POOL32AXF_2
:
18916 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
18917 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18920 case NM_POOL32AXF_4
:
18922 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
18923 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
18926 case NM_POOL32AXF_5
:
18927 switch (extract32(ctx
->opcode
, 9, 7)) {
18928 #ifndef CONFIG_USER_ONLY
18930 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
18933 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
18936 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
18939 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
18942 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
18945 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
18948 check_cp0_enabled(ctx
);
18950 TCGv t0
= tcg_temp_new();
18952 save_cpu_state(ctx
, 1);
18953 gen_helper_di(t0
, cpu_env
);
18954 gen_store_gpr(t0
, rt
);
18955 /* Stop translation as we may have switched the execution mode */
18956 ctx
->base
.is_jmp
= DISAS_STOP
;
18961 check_cp0_enabled(ctx
);
18963 TCGv t0
= tcg_temp_new();
18965 save_cpu_state(ctx
, 1);
18966 gen_helper_ei(t0
, cpu_env
);
18967 gen_store_gpr(t0
, rt
);
18968 /* Stop translation as we may have switched the execution mode */
18969 ctx
->base
.is_jmp
= DISAS_STOP
;
18974 check_cp0_enabled(ctx
);
18975 gen_load_srsgpr(rs
, rt
);
18978 check_cp0_enabled(ctx
);
18979 gen_store_srsgpr(rs
, rt
);
18982 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
18985 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
18988 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
18992 gen_reserved_instruction(ctx
);
18996 case NM_POOL32AXF_7
:
18998 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18999 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19003 gen_reserved_instruction(ctx
);
19008 /* Immediate Value Compact Branches */
19009 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19010 int rt
, int32_t imm
, int32_t offset
)
19012 TCGCond cond
= TCG_COND_ALWAYS
;
19013 TCGv t0
= tcg_temp_new();
19014 TCGv t1
= tcg_temp_new();
19016 gen_load_gpr(t0
, rt
);
19017 tcg_gen_movi_tl(t1
, imm
);
19018 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19020 /* Load needed operands and calculate btarget */
19023 if (rt
== 0 && imm
== 0) {
19024 /* Unconditional branch */
19025 } else if (rt
== 0 && imm
!= 0) {
19029 cond
= TCG_COND_EQ
;
19035 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19036 gen_reserved_instruction(ctx
);
19038 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19039 /* Unconditional branch */
19040 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19044 tcg_gen_shri_tl(t0
, t0
, imm
);
19045 tcg_gen_andi_tl(t0
, t0
, 1);
19046 tcg_gen_movi_tl(t1
, 0);
19047 if (opc
== NM_BBEQZC
) {
19048 cond
= TCG_COND_EQ
;
19050 cond
= TCG_COND_NE
;
19055 if (rt
== 0 && imm
== 0) {
19058 } else if (rt
== 0 && imm
!= 0) {
19059 /* Unconditional branch */
19061 cond
= TCG_COND_NE
;
19065 if (rt
== 0 && imm
== 0) {
19066 /* Unconditional branch */
19068 cond
= TCG_COND_GE
;
19072 cond
= TCG_COND_LT
;
19075 if (rt
== 0 && imm
== 0) {
19076 /* Unconditional branch */
19078 cond
= TCG_COND_GEU
;
19082 cond
= TCG_COND_LTU
;
19085 MIPS_INVAL("Immediate Value Compact branch");
19086 gen_reserved_instruction(ctx
);
19090 /* branch completion */
19091 clear_branch_hflags(ctx
);
19092 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19094 if (cond
== TCG_COND_ALWAYS
) {
19095 /* Unconditional compact branch */
19096 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19098 /* Conditional compact branch */
19099 TCGLabel
*fs
= gen_new_label();
19101 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19103 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19106 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19114 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19115 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19118 TCGv t0
= tcg_temp_new();
19119 TCGv t1
= tcg_temp_new();
19122 gen_load_gpr(t0
, rs
);
19126 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19129 /* calculate btarget */
19130 tcg_gen_shli_tl(t0
, t0
, 1);
19131 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19132 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19134 /* branch completion */
19135 clear_branch_hflags(ctx
);
19136 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19138 /* unconditional branch to register */
19139 tcg_gen_mov_tl(cpu_PC
, btarget
);
19140 tcg_gen_lookup_and_goto_ptr();
19146 /* nanoMIPS Branches */
19147 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19148 int rs
, int rt
, int32_t offset
)
19150 int bcond_compute
= 0;
19151 TCGv t0
= tcg_temp_new();
19152 TCGv t1
= tcg_temp_new();
19154 /* Load needed operands and calculate btarget */
19156 /* compact branch */
19159 gen_load_gpr(t0
, rs
);
19160 gen_load_gpr(t1
, rt
);
19162 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19166 if (rs
== 0 || rs
== rt
) {
19167 /* OPC_BLEZALC, OPC_BGEZALC */
19168 /* OPC_BGTZALC, OPC_BLTZALC */
19169 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19171 gen_load_gpr(t0
, rs
);
19172 gen_load_gpr(t1
, rt
);
19174 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19177 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19181 /* OPC_BEQZC, OPC_BNEZC */
19182 gen_load_gpr(t0
, rs
);
19184 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19186 /* OPC_JIC, OPC_JIALC */
19187 TCGv tbase
= tcg_temp_new();
19188 TCGv toffset
= tcg_temp_new();
19190 gen_load_gpr(tbase
, rt
);
19191 tcg_gen_movi_tl(toffset
, offset
);
19192 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19193 tcg_temp_free(tbase
);
19194 tcg_temp_free(toffset
);
19198 MIPS_INVAL("Compact branch/jump");
19199 gen_reserved_instruction(ctx
);
19203 if (bcond_compute
== 0) {
19204 /* Unconditional compact branch */
19207 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19210 MIPS_INVAL("Compact branch/jump");
19211 gen_reserved_instruction(ctx
);
19215 /* Conditional compact branch */
19216 TCGLabel
*fs
= gen_new_label();
19220 if (rs
== 0 && rt
!= 0) {
19222 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19223 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19225 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19228 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19232 if (rs
== 0 && rt
!= 0) {
19234 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19235 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19237 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19240 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19244 if (rs
== 0 && rt
!= 0) {
19246 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19247 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19249 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19252 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19256 if (rs
== 0 && rt
!= 0) {
19258 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19259 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19261 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19264 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19268 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19271 MIPS_INVAL("Compact conditional branch/jump");
19272 gen_reserved_instruction(ctx
);
19276 /* branch completion */
19277 clear_branch_hflags(ctx
);
19278 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19280 /* Generating branch here as compact branches don't have delay slot */
19281 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19284 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19293 /* nanoMIPS CP1 Branches */
19294 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19295 int32_t ft
, int32_t offset
)
19297 target_ulong btarget
;
19298 TCGv_i64 t0
= tcg_temp_new_i64();
19300 gen_load_fpr64(ctx
, t0
, ft
);
19301 tcg_gen_andi_i64(t0
, t0
, 1);
19303 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19307 tcg_gen_xori_i64(t0
, t0
, 1);
19308 ctx
->hflags
|= MIPS_HFLAG_BC
;
19311 /* t0 already set */
19312 ctx
->hflags
|= MIPS_HFLAG_BC
;
19315 MIPS_INVAL("cp1 cond branch");
19316 gen_reserved_instruction(ctx
);
19320 tcg_gen_trunc_i64_tl(bcond
, t0
);
19322 ctx
->btarget
= btarget
;
19325 tcg_temp_free_i64(t0
);
19329 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19332 t0
= tcg_temp_new();
19333 t1
= tcg_temp_new();
19335 gen_load_gpr(t0
, rs
);
19336 gen_load_gpr(t1
, rt
);
19338 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19339 /* PP.LSXS instructions require shifting */
19340 switch (extract32(ctx
->opcode
, 7, 4)) {
19346 tcg_gen_shli_tl(t0
, t0
, 1);
19354 tcg_gen_shli_tl(t0
, t0
, 2);
19358 tcg_gen_shli_tl(t0
, t0
, 3);
19362 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19364 switch (extract32(ctx
->opcode
, 7, 4)) {
19366 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19368 gen_store_gpr(t0
, rd
);
19372 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19374 gen_store_gpr(t0
, rd
);
19378 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19380 gen_store_gpr(t0
, rd
);
19383 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19385 gen_store_gpr(t0
, rd
);
19389 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19391 gen_store_gpr(t0
, rd
);
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
,
19409 gen_load_gpr(t1
, rd
);
19410 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19414 /*case NM_LWC1XS:*/
19416 /*case NM_LDC1XS:*/
19418 /*case NM_SWC1XS:*/
19420 /*case NM_SDC1XS:*/
19421 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19422 check_cp1_enabled(ctx
);
19423 switch (extract32(ctx
->opcode
, 7, 4)) {
19425 /*case NM_LWC1XS:*/
19426 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19429 /*case NM_LDC1XS:*/
19430 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19433 /*case NM_SWC1XS:*/
19434 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19437 /*case NM_SDC1XS:*/
19438 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19442 generate_exception_err(ctx
, EXCP_CpU
, 1);
19446 gen_reserved_instruction(ctx
);
19454 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19458 rt
= extract32(ctx
->opcode
, 21, 5);
19459 rs
= extract32(ctx
->opcode
, 16, 5);
19460 rd
= extract32(ctx
->opcode
, 11, 5);
19462 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19463 gen_reserved_instruction(ctx
);
19466 check_cp1_enabled(ctx
);
19467 switch (extract32(ctx
->opcode
, 0, 3)) {
19469 switch (extract32(ctx
->opcode
, 3, 7)) {
19471 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19474 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19477 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19480 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19483 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19486 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19489 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19492 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19495 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19498 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19501 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19504 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19507 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19510 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19513 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19516 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19519 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19522 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19525 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19528 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19531 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19534 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19537 gen_reserved_instruction(ctx
);
19542 switch (extract32(ctx
->opcode
, 3, 3)) {
19544 switch (extract32(ctx
->opcode
, 9, 1)) {
19546 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19549 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19554 switch (extract32(ctx
->opcode
, 9, 1)) {
19556 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19559 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19564 switch (extract32(ctx
->opcode
, 9, 1)) {
19566 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19569 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19574 switch (extract32(ctx
->opcode
, 9, 1)) {
19576 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19579 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19584 switch (extract32(ctx
->opcode
, 6, 8)) {
19586 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19589 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19592 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19595 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19598 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19601 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19604 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19607 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19610 switch (extract32(ctx
->opcode
, 6, 9)) {
19612 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19615 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19618 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19621 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19624 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19627 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19630 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19633 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19636 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19639 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19642 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19645 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19648 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
19651 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
19654 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
19657 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
19660 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
19663 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
19666 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
19669 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
19672 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
19675 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
19678 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
19681 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
19684 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
19687 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
19690 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
19693 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
19696 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
19699 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
19702 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
19705 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
19708 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
19711 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
19714 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
19717 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
19720 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
19723 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
19726 gen_reserved_instruction(ctx
);
19735 switch (extract32(ctx
->opcode
, 3, 3)) {
19736 case NM_CMP_CONDN_S
:
19737 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19739 case NM_CMP_CONDN_D
:
19740 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19743 gen_reserved_instruction(ctx
);
19748 gen_reserved_instruction(ctx
);
19753 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
19754 int rd
, int rs
, int rt
)
19757 TCGv t0
= tcg_temp_new();
19758 TCGv v1_t
= tcg_temp_new();
19759 TCGv v2_t
= tcg_temp_new();
19761 gen_load_gpr(v1_t
, rs
);
19762 gen_load_gpr(v2_t
, rt
);
19767 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
19771 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
19775 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
19777 case NM_CMPU_EQ_QB
:
19779 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
19781 case NM_CMPU_LT_QB
:
19783 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
19785 case NM_CMPU_LE_QB
:
19787 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
19789 case NM_CMPGU_EQ_QB
:
19791 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19792 gen_store_gpr(v1_t
, ret
);
19794 case NM_CMPGU_LT_QB
:
19796 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19797 gen_store_gpr(v1_t
, ret
);
19799 case NM_CMPGU_LE_QB
:
19801 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19802 gen_store_gpr(v1_t
, ret
);
19804 case NM_CMPGDU_EQ_QB
:
19806 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19807 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19808 gen_store_gpr(v1_t
, ret
);
19810 case NM_CMPGDU_LT_QB
:
19812 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19813 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19814 gen_store_gpr(v1_t
, ret
);
19816 case NM_CMPGDU_LE_QB
:
19818 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19819 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19820 gen_store_gpr(v1_t
, ret
);
19824 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
19825 gen_store_gpr(v1_t
, ret
);
19829 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19830 gen_store_gpr(v1_t
, ret
);
19834 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19835 gen_store_gpr(v1_t
, ret
);
19839 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19840 gen_store_gpr(v1_t
, ret
);
19844 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19845 gen_store_gpr(v1_t
, ret
);
19849 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
19850 gen_store_gpr(v1_t
, ret
);
19854 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
19855 gen_store_gpr(v1_t
, ret
);
19859 switch (extract32(ctx
->opcode
, 10, 1)) {
19862 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19863 gen_store_gpr(v1_t
, ret
);
19867 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19868 gen_store_gpr(v1_t
, ret
);
19872 case NM_ADDQH_R_PH
:
19874 switch (extract32(ctx
->opcode
, 10, 1)) {
19877 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
19878 gen_store_gpr(v1_t
, ret
);
19882 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
19883 gen_store_gpr(v1_t
, ret
);
19889 switch (extract32(ctx
->opcode
, 10, 1)) {
19892 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
19893 gen_store_gpr(v1_t
, ret
);
19897 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
19898 gen_store_gpr(v1_t
, ret
);
19904 switch (extract32(ctx
->opcode
, 10, 1)) {
19907 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19908 gen_store_gpr(v1_t
, ret
);
19912 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19913 gen_store_gpr(v1_t
, ret
);
19919 switch (extract32(ctx
->opcode
, 10, 1)) {
19922 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19923 gen_store_gpr(v1_t
, ret
);
19927 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19928 gen_store_gpr(v1_t
, ret
);
19932 case NM_ADDUH_R_QB
:
19934 switch (extract32(ctx
->opcode
, 10, 1)) {
19937 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
19938 gen_store_gpr(v1_t
, ret
);
19942 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
19943 gen_store_gpr(v1_t
, ret
);
19947 case NM_SHRAV_R_PH
:
19949 switch (extract32(ctx
->opcode
, 10, 1)) {
19952 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
19953 gen_store_gpr(v1_t
, ret
);
19957 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
19958 gen_store_gpr(v1_t
, ret
);
19962 case NM_SHRAV_R_QB
:
19964 switch (extract32(ctx
->opcode
, 10, 1)) {
19967 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
19968 gen_store_gpr(v1_t
, ret
);
19972 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
19973 gen_store_gpr(v1_t
, ret
);
19979 switch (extract32(ctx
->opcode
, 10, 1)) {
19982 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19983 gen_store_gpr(v1_t
, ret
);
19987 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19988 gen_store_gpr(v1_t
, ret
);
19992 case NM_SUBQH_R_PH
:
19994 switch (extract32(ctx
->opcode
, 10, 1)) {
19997 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
19998 gen_store_gpr(v1_t
, ret
);
20002 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
20003 gen_store_gpr(v1_t
, ret
);
20009 switch (extract32(ctx
->opcode
, 10, 1)) {
20012 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20013 gen_store_gpr(v1_t
, ret
);
20017 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20018 gen_store_gpr(v1_t
, ret
);
20024 switch (extract32(ctx
->opcode
, 10, 1)) {
20027 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20028 gen_store_gpr(v1_t
, ret
);
20032 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20033 gen_store_gpr(v1_t
, ret
);
20039 switch (extract32(ctx
->opcode
, 10, 1)) {
20042 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20043 gen_store_gpr(v1_t
, ret
);
20047 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20048 gen_store_gpr(v1_t
, ret
);
20052 case NM_SUBUH_R_QB
:
20054 switch (extract32(ctx
->opcode
, 10, 1)) {
20057 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20058 gen_store_gpr(v1_t
, ret
);
20062 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20063 gen_store_gpr(v1_t
, ret
);
20067 case NM_SHLLV_S_PH
:
20069 switch (extract32(ctx
->opcode
, 10, 1)) {
20072 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20073 gen_store_gpr(v1_t
, ret
);
20077 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20078 gen_store_gpr(v1_t
, ret
);
20082 case NM_PRECR_SRA_R_PH_W
:
20084 switch (extract32(ctx
->opcode
, 10, 1)) {
20086 /* PRECR_SRA_PH_W */
20088 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20089 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20091 gen_store_gpr(v1_t
, rt
);
20092 tcg_temp_free_i32(sa_t
);
20096 /* PRECR_SRA_R_PH_W */
20098 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20099 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20101 gen_store_gpr(v1_t
, rt
);
20102 tcg_temp_free_i32(sa_t
);
20107 case NM_MULEU_S_PH_QBL
:
20109 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20110 gen_store_gpr(v1_t
, ret
);
20112 case NM_MULEU_S_PH_QBR
:
20114 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20115 gen_store_gpr(v1_t
, ret
);
20117 case NM_MULQ_RS_PH
:
20119 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20120 gen_store_gpr(v1_t
, ret
);
20124 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20125 gen_store_gpr(v1_t
, ret
);
20129 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20130 gen_store_gpr(v1_t
, ret
);
20134 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20135 gen_store_gpr(v1_t
, ret
);
20139 gen_load_gpr(t0
, rs
);
20141 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20143 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20147 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20148 gen_store_gpr(v1_t
, ret
);
20152 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20153 gen_store_gpr(v1_t
, ret
);
20157 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20158 gen_store_gpr(v1_t
, ret
);
20162 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20163 gen_store_gpr(v1_t
, ret
);
20167 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20168 gen_store_gpr(v1_t
, ret
);
20172 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20173 gen_store_gpr(v1_t
, ret
);
20178 TCGv tv0
= tcg_temp_new();
20179 TCGv tv1
= tcg_temp_new();
20180 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20182 tcg_gen_movi_tl(tv0
, rd
>> 3);
20183 tcg_gen_movi_tl(tv1
, imm
);
20184 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20187 case NM_MULEQ_S_W_PHL
:
20189 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20190 gen_store_gpr(v1_t
, ret
);
20192 case NM_MULEQ_S_W_PHR
:
20194 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20195 gen_store_gpr(v1_t
, ret
);
20199 switch (extract32(ctx
->opcode
, 10, 1)) {
20202 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20203 gen_store_gpr(v1_t
, ret
);
20207 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20208 gen_store_gpr(v1_t
, ret
);
20212 case NM_PRECR_QB_PH
:
20214 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20215 gen_store_gpr(v1_t
, ret
);
20217 case NM_PRECRQ_QB_PH
:
20219 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20220 gen_store_gpr(v1_t
, ret
);
20222 case NM_PRECRQ_PH_W
:
20224 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20225 gen_store_gpr(v1_t
, ret
);
20227 case NM_PRECRQ_RS_PH_W
:
20229 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20230 gen_store_gpr(v1_t
, ret
);
20232 case NM_PRECRQU_S_QB_PH
:
20234 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20235 gen_store_gpr(v1_t
, ret
);
20239 tcg_gen_movi_tl(t0
, rd
);
20240 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20241 gen_store_gpr(v1_t
, rt
);
20245 tcg_gen_movi_tl(t0
, rd
>> 1);
20246 switch (extract32(ctx
->opcode
, 10, 1)) {
20249 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20250 gen_store_gpr(v1_t
, rt
);
20254 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20255 gen_store_gpr(v1_t
, rt
);
20261 tcg_gen_movi_tl(t0
, rd
>> 1);
20262 switch (extract32(ctx
->opcode
, 10, 2)) {
20265 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20266 gen_store_gpr(v1_t
, rt
);
20270 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20271 gen_store_gpr(v1_t
, rt
);
20274 gen_reserved_instruction(ctx
);
20280 tcg_gen_movi_tl(t0
, rd
);
20281 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20282 gen_store_gpr(v1_t
, rt
);
20288 imm
= sextract32(ctx
->opcode
, 11, 11);
20289 imm
= (int16_t)(imm
<< 6) >> 6;
20291 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20296 gen_reserved_instruction(ctx
);
20301 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20309 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20310 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20312 rt
= extract32(ctx
->opcode
, 21, 5);
20313 rs
= extract32(ctx
->opcode
, 16, 5);
20314 rd
= extract32(ctx
->opcode
, 11, 5);
20316 op
= extract32(ctx
->opcode
, 26, 6);
20321 switch (extract32(ctx
->opcode
, 19, 2)) {
20324 gen_reserved_instruction(ctx
);
20327 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20328 generate_exception_end(ctx
, EXCP_SYSCALL
);
20330 gen_reserved_instruction(ctx
);
20334 generate_exception_end(ctx
, EXCP_BREAK
);
20337 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20338 gen_helper_do_semihosting(cpu_env
);
20340 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20341 gen_reserved_instruction(ctx
);
20343 generate_exception_end(ctx
, EXCP_DBp
);
20350 imm
= extract32(ctx
->opcode
, 0, 16);
20352 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20354 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20356 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20361 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20362 extract32(ctx
->opcode
, 1, 20) << 1;
20363 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20364 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20368 switch (ctx
->opcode
& 0x07) {
20370 gen_pool32a0_nanomips_insn(env
, ctx
);
20374 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20375 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20379 switch (extract32(ctx
->opcode
, 3, 3)) {
20381 gen_p_lsx(ctx
, rd
, rs
, rt
);
20385 * In nanoMIPS, the shift field directly encodes the shift
20386 * amount, meaning that the supported shift values are in
20387 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20389 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20392 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20395 gen_pool32axf_nanomips_insn(env
, ctx
);
20398 gen_reserved_instruction(ctx
);
20403 gen_reserved_instruction(ctx
);
20408 switch (ctx
->opcode
& 0x03) {
20411 offset
= extract32(ctx
->opcode
, 0, 21);
20412 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20416 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20419 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20422 gen_reserved_instruction(ctx
);
20428 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20429 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20430 switch (extract32(ctx
->opcode
, 16, 5)) {
20434 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20440 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20441 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20447 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20453 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20456 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20463 t0
= tcg_temp_new();
20465 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20468 tcg_gen_movi_tl(t0
, addr
);
20469 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20477 t0
= tcg_temp_new();
20478 t1
= tcg_temp_new();
20480 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20483 tcg_gen_movi_tl(t0
, addr
);
20484 gen_load_gpr(t1
, rt
);
20486 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20493 gen_reserved_instruction(ctx
);
20499 switch (extract32(ctx
->opcode
, 12, 4)) {
20501 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20504 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20507 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20510 switch (extract32(ctx
->opcode
, 20, 1)) {
20512 switch (ctx
->opcode
& 3) {
20514 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20515 extract32(ctx
->opcode
, 2, 1),
20516 extract32(ctx
->opcode
, 3, 9) << 3);
20519 case NM_RESTORE_JRC
:
20520 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20521 extract32(ctx
->opcode
, 2, 1),
20522 extract32(ctx
->opcode
, 3, 9) << 3);
20523 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20524 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20528 gen_reserved_instruction(ctx
);
20533 gen_reserved_instruction(ctx
);
20538 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20541 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20545 TCGv t0
= tcg_temp_new();
20547 imm
= extract32(ctx
->opcode
, 0, 12);
20548 gen_load_gpr(t0
, rs
);
20549 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20550 gen_store_gpr(t0
, rt
);
20556 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20557 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20561 int shift
= extract32(ctx
->opcode
, 0, 5);
20562 switch (extract32(ctx
->opcode
, 5, 4)) {
20564 if (rt
== 0 && shift
== 0) {
20566 } else if (rt
== 0 && shift
== 3) {
20567 /* EHB - treat as NOP */
20568 } else if (rt
== 0 && shift
== 5) {
20569 /* PAUSE - treat as NOP */
20570 } else if (rt
== 0 && shift
== 6) {
20572 gen_sync(extract32(ctx
->opcode
, 16, 5));
20575 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20576 extract32(ctx
->opcode
, 0, 5));
20580 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20581 extract32(ctx
->opcode
, 0, 5));
20584 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20585 extract32(ctx
->opcode
, 0, 5));
20588 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20589 extract32(ctx
->opcode
, 0, 5));
20597 TCGv t0
= tcg_temp_new();
20598 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20599 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20601 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20603 gen_load_gpr(t0
, rs
);
20604 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20607 tcg_temp_free_i32(shift
);
20608 tcg_temp_free_i32(shiftx
);
20609 tcg_temp_free_i32(stripe
);
20613 switch (((ctx
->opcode
>> 10) & 2) |
20614 (extract32(ctx
->opcode
, 5, 1))) {
20617 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20618 extract32(ctx
->opcode
, 6, 5));
20621 gen_reserved_instruction(ctx
);
20626 switch (((ctx
->opcode
>> 10) & 2) |
20627 (extract32(ctx
->opcode
, 5, 1))) {
20630 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20631 extract32(ctx
->opcode
, 6, 5));
20634 gen_reserved_instruction(ctx
);
20639 gen_reserved_instruction(ctx
);
20644 gen_pool32f_nanomips_insn(ctx
);
20649 switch (extract32(ctx
->opcode
, 1, 1)) {
20652 tcg_gen_movi_tl(cpu_gpr
[rt
],
20653 sextract32(ctx
->opcode
, 0, 1) << 31 |
20654 extract32(ctx
->opcode
, 2, 10) << 21 |
20655 extract32(ctx
->opcode
, 12, 9) << 12);
20660 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
20661 extract32(ctx
->opcode
, 2, 10) << 21 |
20662 extract32(ctx
->opcode
, 12, 9) << 12;
20664 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20665 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20672 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
20674 switch (extract32(ctx
->opcode
, 18, 3)) {
20676 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
20679 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
20682 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
20686 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
20691 switch (ctx
->opcode
& 1) {
20693 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
20696 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
20702 switch (ctx
->opcode
& 1) {
20704 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
20707 gen_reserved_instruction(ctx
);
20713 switch (ctx
->opcode
& 0x3) {
20715 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
20718 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
20721 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
20724 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
20729 gen_reserved_instruction(ctx
);
20736 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
20738 switch (extract32(ctx
->opcode
, 12, 4)) {
20743 * Break the TB to be able to sync copied instructions
20746 ctx
->base
.is_jmp
= DISAS_STOP
;
20749 /* Treat as NOP. */
20753 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
20756 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
20759 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
20762 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
20765 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
20768 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
20771 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
20774 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
20777 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
20780 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
20783 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
20786 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
20789 gen_reserved_instruction(ctx
);
20796 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
20797 extract32(ctx
->opcode
, 0, 8);
20799 switch (extract32(ctx
->opcode
, 8, 3)) {
20801 switch (extract32(ctx
->opcode
, 11, 4)) {
20803 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
20806 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
20809 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
20812 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
20815 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
20818 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
20821 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
20824 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
20827 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
20830 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
20833 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
20836 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
20842 * Break the TB to be able to sync copied instructions
20845 ctx
->base
.is_jmp
= DISAS_STOP
;
20848 /* Treat as NOP. */
20852 gen_reserved_instruction(ctx
);
20857 switch (extract32(ctx
->opcode
, 11, 4)) {
20862 TCGv t0
= tcg_temp_new();
20863 TCGv t1
= tcg_temp_new();
20865 gen_base_offset_addr(ctx
, t0
, rs
, s
);
20867 switch (extract32(ctx
->opcode
, 11, 4)) {
20869 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
20871 gen_store_gpr(t0
, rt
);
20874 gen_load_gpr(t1
, rt
);
20875 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
20884 switch (ctx
->opcode
& 0x03) {
20886 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
20890 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20895 switch (ctx
->opcode
& 0x03) {
20897 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
20901 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
20907 check_cp0_enabled(ctx
);
20908 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
20909 gen_cache_operation(ctx
, rt
, rs
, s
);
20915 switch (extract32(ctx
->opcode
, 11, 4)) {
20918 check_cp0_enabled(ctx
);
20919 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
20923 check_cp0_enabled(ctx
);
20924 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
20928 check_cp0_enabled(ctx
);
20929 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
20933 /* case NM_SYNCIE */
20935 check_cp0_enabled(ctx
);
20937 * Break the TB to be able to sync copied instructions
20940 ctx
->base
.is_jmp
= DISAS_STOP
;
20942 /* case NM_PREFE */
20944 check_cp0_enabled(ctx
);
20945 /* Treat as NOP. */
20950 check_cp0_enabled(ctx
);
20951 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
20955 check_cp0_enabled(ctx
);
20956 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
20960 check_cp0_enabled(ctx
);
20961 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
20965 check_cp0_enabled(ctx
);
20966 check_nms_dl_il_sl_tl_l2c(ctx
);
20967 gen_cache_operation(ctx
, rt
, rs
, s
);
20971 check_cp0_enabled(ctx
);
20972 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
20976 check_cp0_enabled(ctx
);
20977 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
20980 switch (extract32(ctx
->opcode
, 2, 2)) {
20984 check_cp0_enabled(ctx
);
20985 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
20990 check_cp0_enabled(ctx
);
20991 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20994 gen_reserved_instruction(ctx
);
20999 switch (extract32(ctx
->opcode
, 2, 2)) {
21003 check_cp0_enabled(ctx
);
21004 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21009 check_cp0_enabled(ctx
);
21010 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21014 gen_reserved_instruction(ctx
);
21024 int count
= extract32(ctx
->opcode
, 12, 3);
21027 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21028 extract32(ctx
->opcode
, 0, 8);
21029 TCGv va
= tcg_temp_new();
21030 TCGv t1
= tcg_temp_new();
21031 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21032 NM_P_LS_UAWM
? MO_UNALN
: 0;
21034 count
= (count
== 0) ? 8 : count
;
21035 while (counter
!= count
) {
21036 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21037 int this_offset
= offset
+ (counter
<< 2);
21039 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21041 switch (extract32(ctx
->opcode
, 11, 1)) {
21043 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21045 gen_store_gpr(t1
, this_rt
);
21046 if ((this_rt
== rs
) &&
21047 (counter
!= (count
- 1))) {
21048 /* UNPREDICTABLE */
21052 this_rt
= (rt
== 0) ? 0 : this_rt
;
21053 gen_load_gpr(t1
, this_rt
);
21054 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21065 gen_reserved_instruction(ctx
);
21073 TCGv t0
= tcg_temp_new();
21074 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21075 extract32(ctx
->opcode
, 1, 20) << 1;
21076 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21077 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21078 extract32(ctx
->opcode
, 21, 3));
21079 gen_load_gpr(t0
, rt
);
21080 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21081 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21087 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21088 extract32(ctx
->opcode
, 1, 24) << 1;
21090 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21092 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21095 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21100 switch (extract32(ctx
->opcode
, 12, 4)) {
21103 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21106 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21109 gen_reserved_instruction(ctx
);
21115 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21116 extract32(ctx
->opcode
, 1, 13) << 1;
21117 switch (extract32(ctx
->opcode
, 14, 2)) {
21120 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21123 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21124 extract32(ctx
->opcode
, 1, 13) << 1;
21125 check_cp1_enabled(ctx
);
21126 switch (extract32(ctx
->opcode
, 16, 5)) {
21128 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21131 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21136 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21137 extract32(ctx
->opcode
, 0, 1) << 13;
21139 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21144 gen_reserved_instruction(ctx
);
21150 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21152 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21156 if (rs
== rt
|| rt
== 0) {
21157 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21158 } else if (rs
== 0) {
21159 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21161 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21169 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21170 extract32(ctx
->opcode
, 1, 13) << 1;
21171 switch (extract32(ctx
->opcode
, 14, 2)) {
21174 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21177 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21179 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21181 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21185 if (rs
== 0 || rs
== rt
) {
21187 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21189 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21193 gen_reserved_instruction(ctx
);
21200 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21201 extract32(ctx
->opcode
, 1, 10) << 1;
21202 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21204 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21209 gen_reserved_instruction(ctx
);
21215 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21218 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21219 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21220 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21224 /* make sure instructions are on a halfword boundary */
21225 if (ctx
->base
.pc_next
& 0x1) {
21226 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21227 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21228 tcg_temp_free(tmp
);
21229 generate_exception_end(ctx
, EXCP_AdEL
);
21233 op
= extract32(ctx
->opcode
, 10, 6);
21236 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21239 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21240 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21243 switch (extract32(ctx
->opcode
, 3, 2)) {
21244 case NM_P16_SYSCALL
:
21245 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21246 generate_exception_end(ctx
, EXCP_SYSCALL
);
21248 gen_reserved_instruction(ctx
);
21252 generate_exception_end(ctx
, EXCP_BREAK
);
21255 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21256 gen_helper_do_semihosting(cpu_env
);
21258 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21259 gen_reserved_instruction(ctx
);
21261 generate_exception_end(ctx
, EXCP_DBp
);
21266 gen_reserved_instruction(ctx
);
21273 int shift
= extract32(ctx
->opcode
, 0, 3);
21275 shift
= (shift
== 0) ? 8 : shift
;
21277 switch (extract32(ctx
->opcode
, 3, 1)) {
21285 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21289 switch (ctx
->opcode
& 1) {
21291 gen_pool16c_nanomips_insn(ctx
);
21294 gen_ldxs(ctx
, rt
, rs
, rd
);
21299 switch (extract32(ctx
->opcode
, 6, 1)) {
21301 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21302 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21305 gen_reserved_instruction(ctx
);
21310 switch (extract32(ctx
->opcode
, 3, 1)) {
21312 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21313 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21315 case NM_P_ADDIURS5
:
21316 rt
= extract32(ctx
->opcode
, 5, 5);
21318 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21319 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21320 (extract32(ctx
->opcode
, 0, 3));
21321 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21327 switch (ctx
->opcode
& 0x1) {
21329 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21332 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21337 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21338 extract32(ctx
->opcode
, 5, 3);
21339 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21340 extract32(ctx
->opcode
, 0, 3);
21341 rt
= decode_gpr_gpr4(rt
);
21342 rs
= decode_gpr_gpr4(rs
);
21343 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21344 (extract32(ctx
->opcode
, 3, 1))) {
21347 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21351 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21354 gen_reserved_instruction(ctx
);
21360 int imm
= extract32(ctx
->opcode
, 0, 7);
21361 imm
= (imm
== 0x7f ? -1 : imm
);
21363 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21369 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21370 u
= (u
== 12) ? 0xff :
21371 (u
== 13) ? 0xffff : u
;
21372 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21376 offset
= extract32(ctx
->opcode
, 0, 2);
21377 switch (extract32(ctx
->opcode
, 2, 2)) {
21379 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21382 rt
= decode_gpr_gpr3_src_store(
21383 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21384 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21387 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21390 gen_reserved_instruction(ctx
);
21395 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21396 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21398 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21401 rt
= decode_gpr_gpr3_src_store(
21402 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21403 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21406 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21409 gen_reserved_instruction(ctx
);
21414 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21415 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21418 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21419 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21420 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21424 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21425 extract32(ctx
->opcode
, 5, 3);
21426 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21427 extract32(ctx
->opcode
, 0, 3);
21428 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21429 (extract32(ctx
->opcode
, 8, 1) << 2);
21430 rt
= decode_gpr_gpr4(rt
);
21431 rs
= decode_gpr_gpr4(rs
);
21432 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21436 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21437 extract32(ctx
->opcode
, 5, 3);
21438 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21439 extract32(ctx
->opcode
, 0, 3);
21440 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21441 (extract32(ctx
->opcode
, 8, 1) << 2);
21442 rt
= decode_gpr_gpr4_zero(rt
);
21443 rs
= decode_gpr_gpr4(rs
);
21444 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21447 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21448 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21451 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21452 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21453 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21456 rt
= decode_gpr_gpr3_src_store(
21457 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21458 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21459 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21460 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21463 rt
= decode_gpr_gpr3_src_store(
21464 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21465 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21466 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21469 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21470 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21471 (extract32(ctx
->opcode
, 1, 9) << 1));
21474 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21475 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21476 (extract32(ctx
->opcode
, 1, 9) << 1));
21479 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21480 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21481 (extract32(ctx
->opcode
, 1, 6) << 1));
21484 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21485 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21486 (extract32(ctx
->opcode
, 1, 6) << 1));
21489 switch (ctx
->opcode
& 0xf) {
21492 switch (extract32(ctx
->opcode
, 4, 1)) {
21494 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21495 extract32(ctx
->opcode
, 5, 5), 0, 0);
21498 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21499 extract32(ctx
->opcode
, 5, 5), 31, 0);
21506 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21507 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21508 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21509 extract32(ctx
->opcode
, 0, 4) << 1);
21516 int count
= extract32(ctx
->opcode
, 0, 4);
21517 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21519 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21520 switch (extract32(ctx
->opcode
, 8, 1)) {
21522 gen_save(ctx
, rt
, count
, 0, u
);
21524 case NM_RESTORE_JRC16
:
21525 gen_restore(ctx
, rt
, count
, 0, u
);
21526 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21535 static const int gpr2reg1
[] = {4, 5, 6, 7};
21536 static const int gpr2reg2
[] = {5, 6, 7, 8};
21538 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21539 extract32(ctx
->opcode
, 8, 1);
21540 int r1
= gpr2reg1
[rd2
];
21541 int r2
= gpr2reg2
[rd2
];
21542 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21543 extract32(ctx
->opcode
, 0, 3);
21544 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21545 extract32(ctx
->opcode
, 5, 3);
21546 TCGv t0
= tcg_temp_new();
21547 TCGv t1
= tcg_temp_new();
21548 if (op
== NM_MOVEP
) {
21551 rs
= decode_gpr_gpr4_zero(r3
);
21552 rt
= decode_gpr_gpr4_zero(r4
);
21554 rd
= decode_gpr_gpr4(r3
);
21555 re
= decode_gpr_gpr4(r4
);
21559 gen_load_gpr(t0
, rs
);
21560 gen_load_gpr(t1
, rt
);
21561 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21562 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21568 return decode_nanomips_32_48_opc(env
, ctx
);
21575 /* SmartMIPS extension to MIPS32 */
21577 #if defined(TARGET_MIPS64)
21579 /* MDMX extension to MIPS64 */
21583 /* MIPSDSP functions. */
21584 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21585 int rd
, int base
, int offset
)
21590 t0
= tcg_temp_new();
21593 gen_load_gpr(t0
, offset
);
21594 } else if (offset
== 0) {
21595 gen_load_gpr(t0
, base
);
21597 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21602 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21603 gen_store_gpr(t0
, rd
);
21606 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21607 gen_store_gpr(t0
, rd
);
21610 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21611 gen_store_gpr(t0
, rd
);
21613 #if defined(TARGET_MIPS64)
21615 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21616 gen_store_gpr(t0
, rd
);
21623 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21624 int ret
, int v1
, int v2
)
21630 /* Treat as NOP. */
21634 v1_t
= tcg_temp_new();
21635 v2_t
= tcg_temp_new();
21637 gen_load_gpr(v1_t
, v1
);
21638 gen_load_gpr(v2_t
, v2
);
21641 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21642 case OPC_MULT_G_2E
:
21646 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21648 case OPC_ADDUH_R_QB
:
21649 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21652 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21654 case OPC_ADDQH_R_PH
:
21655 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21658 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21660 case OPC_ADDQH_R_W
:
21661 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21664 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21666 case OPC_SUBUH_R_QB
:
21667 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21670 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21672 case OPC_SUBQH_R_PH
:
21673 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21676 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21678 case OPC_SUBQH_R_W
:
21679 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21683 case OPC_ABSQ_S_PH_DSP
:
21685 case OPC_ABSQ_S_QB
:
21687 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
21689 case OPC_ABSQ_S_PH
:
21691 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
21695 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
21697 case OPC_PRECEQ_W_PHL
:
21699 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
21700 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21702 case OPC_PRECEQ_W_PHR
:
21704 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
21705 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
21706 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21708 case OPC_PRECEQU_PH_QBL
:
21710 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
21712 case OPC_PRECEQU_PH_QBR
:
21714 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
21716 case OPC_PRECEQU_PH_QBLA
:
21718 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
21720 case OPC_PRECEQU_PH_QBRA
:
21722 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
21724 case OPC_PRECEU_PH_QBL
:
21726 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
21728 case OPC_PRECEU_PH_QBR
:
21730 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
21732 case OPC_PRECEU_PH_QBLA
:
21734 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
21736 case OPC_PRECEU_PH_QBRA
:
21738 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
21742 case OPC_ADDU_QB_DSP
:
21746 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21748 case OPC_ADDQ_S_PH
:
21750 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21754 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21758 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21760 case OPC_ADDU_S_QB
:
21762 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21766 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21768 case OPC_ADDU_S_PH
:
21770 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21774 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21776 case OPC_SUBQ_S_PH
:
21778 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21782 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21786 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21788 case OPC_SUBU_S_QB
:
21790 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21794 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21796 case OPC_SUBU_S_PH
:
21798 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21802 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21806 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21810 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
21812 case OPC_RADDU_W_QB
:
21814 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
21818 case OPC_CMPU_EQ_QB_DSP
:
21820 case OPC_PRECR_QB_PH
:
21822 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21824 case OPC_PRECRQ_QB_PH
:
21826 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21828 case OPC_PRECR_SRA_PH_W
:
21831 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21832 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21834 tcg_temp_free_i32(sa_t
);
21837 case OPC_PRECR_SRA_R_PH_W
:
21840 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21841 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21843 tcg_temp_free_i32(sa_t
);
21846 case OPC_PRECRQ_PH_W
:
21848 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21850 case OPC_PRECRQ_RS_PH_W
:
21852 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21854 case OPC_PRECRQU_S_QB_PH
:
21856 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21860 #ifdef TARGET_MIPS64
21861 case OPC_ABSQ_S_QH_DSP
:
21863 case OPC_PRECEQ_L_PWL
:
21865 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
21867 case OPC_PRECEQ_L_PWR
:
21869 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
21871 case OPC_PRECEQ_PW_QHL
:
21873 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
21875 case OPC_PRECEQ_PW_QHR
:
21877 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
21879 case OPC_PRECEQ_PW_QHLA
:
21881 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
21883 case OPC_PRECEQ_PW_QHRA
:
21885 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
21887 case OPC_PRECEQU_QH_OBL
:
21889 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
21891 case OPC_PRECEQU_QH_OBR
:
21893 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
21895 case OPC_PRECEQU_QH_OBLA
:
21897 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
21899 case OPC_PRECEQU_QH_OBRA
:
21901 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
21903 case OPC_PRECEU_QH_OBL
:
21905 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
21907 case OPC_PRECEU_QH_OBR
:
21909 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
21911 case OPC_PRECEU_QH_OBLA
:
21913 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
21915 case OPC_PRECEU_QH_OBRA
:
21917 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
21919 case OPC_ABSQ_S_OB
:
21921 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
21923 case OPC_ABSQ_S_PW
:
21925 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
21927 case OPC_ABSQ_S_QH
:
21929 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
21933 case OPC_ADDU_OB_DSP
:
21935 case OPC_RADDU_L_OB
:
21937 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
21941 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21943 case OPC_SUBQ_S_PW
:
21945 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21949 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21951 case OPC_SUBQ_S_QH
:
21953 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21957 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21959 case OPC_SUBU_S_OB
:
21961 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21965 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21967 case OPC_SUBU_S_QH
:
21969 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21973 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21975 case OPC_SUBUH_R_OB
:
21977 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21981 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21983 case OPC_ADDQ_S_PW
:
21985 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21989 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21991 case OPC_ADDQ_S_QH
:
21993 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21997 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21999 case OPC_ADDU_S_OB
:
22001 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22005 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22007 case OPC_ADDU_S_QH
:
22009 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22013 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22015 case OPC_ADDUH_R_OB
:
22017 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22021 case OPC_CMPU_EQ_OB_DSP
:
22023 case OPC_PRECR_OB_QH
:
22025 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22027 case OPC_PRECR_SRA_QH_PW
:
22030 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22031 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22032 tcg_temp_free_i32(ret_t
);
22035 case OPC_PRECR_SRA_R_QH_PW
:
22038 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22039 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22040 tcg_temp_free_i32(sa_v
);
22043 case OPC_PRECRQ_OB_QH
:
22045 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22047 case OPC_PRECRQ_PW_L
:
22049 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22051 case OPC_PRECRQ_QH_PW
:
22053 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22055 case OPC_PRECRQ_RS_QH_PW
:
22057 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22059 case OPC_PRECRQU_S_OB_QH
:
22061 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22068 tcg_temp_free(v1_t
);
22069 tcg_temp_free(v2_t
);
22072 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22073 int ret
, int v1
, int v2
)
22081 /* Treat as NOP. */
22085 t0
= tcg_temp_new();
22086 v1_t
= tcg_temp_new();
22087 v2_t
= tcg_temp_new();
22089 tcg_gen_movi_tl(t0
, v1
);
22090 gen_load_gpr(v1_t
, v1
);
22091 gen_load_gpr(v2_t
, v2
);
22094 case OPC_SHLL_QB_DSP
:
22096 op2
= MASK_SHLL_QB(ctx
->opcode
);
22100 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22104 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22108 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22112 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22114 case OPC_SHLL_S_PH
:
22116 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22118 case OPC_SHLLV_S_PH
:
22120 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22124 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22126 case OPC_SHLLV_S_W
:
22128 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22132 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22136 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22140 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22144 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22148 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22150 case OPC_SHRA_R_QB
:
22152 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22156 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22158 case OPC_SHRAV_R_QB
:
22160 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22164 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22166 case OPC_SHRA_R_PH
:
22168 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22172 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22174 case OPC_SHRAV_R_PH
:
22176 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22180 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22182 case OPC_SHRAV_R_W
:
22184 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22186 default: /* Invalid */
22187 MIPS_INVAL("MASK SHLL.QB");
22188 gen_reserved_instruction(ctx
);
22193 #ifdef TARGET_MIPS64
22194 case OPC_SHLL_OB_DSP
:
22195 op2
= MASK_SHLL_OB(ctx
->opcode
);
22199 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22203 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22205 case OPC_SHLL_S_PW
:
22207 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22209 case OPC_SHLLV_S_PW
:
22211 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22215 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22219 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22223 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22227 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22229 case OPC_SHLL_S_QH
:
22231 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22233 case OPC_SHLLV_S_QH
:
22235 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22239 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22243 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22245 case OPC_SHRA_R_OB
:
22247 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22249 case OPC_SHRAV_R_OB
:
22251 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22255 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22259 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22261 case OPC_SHRA_R_PW
:
22263 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22265 case OPC_SHRAV_R_PW
:
22267 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22271 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22275 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22277 case OPC_SHRA_R_QH
:
22279 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22281 case OPC_SHRAV_R_QH
:
22283 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22287 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22291 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22295 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22299 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22301 default: /* Invalid */
22302 MIPS_INVAL("MASK SHLL.OB");
22303 gen_reserved_instruction(ctx
);
22311 tcg_temp_free(v1_t
);
22312 tcg_temp_free(v2_t
);
22315 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22316 int ret
, int v1
, int v2
, int check_ret
)
22322 if ((ret
== 0) && (check_ret
== 1)) {
22323 /* Treat as NOP. */
22327 t0
= tcg_temp_new_i32();
22328 v1_t
= tcg_temp_new();
22329 v2_t
= tcg_temp_new();
22331 tcg_gen_movi_i32(t0
, ret
);
22332 gen_load_gpr(v1_t
, v1
);
22333 gen_load_gpr(v2_t
, v2
);
22337 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22338 * the same mask and op1.
22340 case OPC_MULT_G_2E
:
22344 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22347 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22350 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22352 case OPC_MULQ_RS_W
:
22353 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22357 case OPC_DPA_W_PH_DSP
:
22359 case OPC_DPAU_H_QBL
:
22361 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22363 case OPC_DPAU_H_QBR
:
22365 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22367 case OPC_DPSU_H_QBL
:
22369 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22371 case OPC_DPSU_H_QBR
:
22373 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22377 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22379 case OPC_DPAX_W_PH
:
22381 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22383 case OPC_DPAQ_S_W_PH
:
22385 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22387 case OPC_DPAQX_S_W_PH
:
22389 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22391 case OPC_DPAQX_SA_W_PH
:
22393 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22397 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22399 case OPC_DPSX_W_PH
:
22401 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22403 case OPC_DPSQ_S_W_PH
:
22405 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22407 case OPC_DPSQX_S_W_PH
:
22409 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22411 case OPC_DPSQX_SA_W_PH
:
22413 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22415 case OPC_MULSAQ_S_W_PH
:
22417 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22419 case OPC_DPAQ_SA_L_W
:
22421 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22423 case OPC_DPSQ_SA_L_W
:
22425 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22427 case OPC_MAQ_S_W_PHL
:
22429 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22431 case OPC_MAQ_S_W_PHR
:
22433 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22435 case OPC_MAQ_SA_W_PHL
:
22437 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22439 case OPC_MAQ_SA_W_PHR
:
22441 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22443 case OPC_MULSA_W_PH
:
22445 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22449 #ifdef TARGET_MIPS64
22450 case OPC_DPAQ_W_QH_DSP
:
22452 int ac
= ret
& 0x03;
22453 tcg_gen_movi_i32(t0
, ac
);
22458 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22462 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22466 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22470 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22474 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22476 case OPC_DPAQ_S_W_QH
:
22478 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22480 case OPC_DPAQ_SA_L_PW
:
22482 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22484 case OPC_DPAU_H_OBL
:
22486 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22488 case OPC_DPAU_H_OBR
:
22490 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22494 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22496 case OPC_DPSQ_S_W_QH
:
22498 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22500 case OPC_DPSQ_SA_L_PW
:
22502 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22504 case OPC_DPSU_H_OBL
:
22506 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22508 case OPC_DPSU_H_OBR
:
22510 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22512 case OPC_MAQ_S_L_PWL
:
22514 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22516 case OPC_MAQ_S_L_PWR
:
22518 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22520 case OPC_MAQ_S_W_QHLL
:
22522 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22524 case OPC_MAQ_SA_W_QHLL
:
22526 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22528 case OPC_MAQ_S_W_QHLR
:
22530 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22532 case OPC_MAQ_SA_W_QHLR
:
22534 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22536 case OPC_MAQ_S_W_QHRL
:
22538 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22540 case OPC_MAQ_SA_W_QHRL
:
22542 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22544 case OPC_MAQ_S_W_QHRR
:
22546 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22548 case OPC_MAQ_SA_W_QHRR
:
22550 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22552 case OPC_MULSAQ_S_L_PW
:
22554 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22556 case OPC_MULSAQ_S_W_QH
:
22558 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22564 case OPC_ADDU_QB_DSP
:
22566 case OPC_MULEU_S_PH_QBL
:
22568 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22570 case OPC_MULEU_S_PH_QBR
:
22572 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22574 case OPC_MULQ_RS_PH
:
22576 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22578 case OPC_MULEQ_S_W_PHL
:
22580 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22582 case OPC_MULEQ_S_W_PHR
:
22584 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22586 case OPC_MULQ_S_PH
:
22588 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22592 #ifdef TARGET_MIPS64
22593 case OPC_ADDU_OB_DSP
:
22595 case OPC_MULEQ_S_PW_QHL
:
22597 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22599 case OPC_MULEQ_S_PW_QHR
:
22601 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22603 case OPC_MULEU_S_QH_OBL
:
22605 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22607 case OPC_MULEU_S_QH_OBR
:
22609 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22611 case OPC_MULQ_RS_QH
:
22613 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22620 tcg_temp_free_i32(t0
);
22621 tcg_temp_free(v1_t
);
22622 tcg_temp_free(v2_t
);
22625 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22633 /* Treat as NOP. */
22637 t0
= tcg_temp_new();
22638 val_t
= tcg_temp_new();
22639 gen_load_gpr(val_t
, val
);
22642 case OPC_ABSQ_S_PH_DSP
:
22646 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22651 target_long result
;
22652 imm
= (ctx
->opcode
>> 16) & 0xFF;
22653 result
= (uint32_t)imm
<< 24 |
22654 (uint32_t)imm
<< 16 |
22655 (uint32_t)imm
<< 8 |
22657 result
= (int32_t)result
;
22658 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
22663 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22664 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22665 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22666 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22667 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22668 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22673 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22674 imm
= (int16_t)(imm
<< 6) >> 6;
22675 tcg_gen_movi_tl(cpu_gpr
[ret
], \
22676 (target_long
)((int32_t)imm
<< 16 | \
22682 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22683 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22684 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22685 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22689 #ifdef TARGET_MIPS64
22690 case OPC_ABSQ_S_QH_DSP
:
22697 imm
= (ctx
->opcode
>> 16) & 0xFF;
22698 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
22699 temp
= (temp
<< 16) | temp
;
22700 temp
= (temp
<< 32) | temp
;
22701 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22709 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22710 imm
= (int16_t)(imm
<< 6) >> 6;
22711 temp
= ((target_long
)imm
<< 32) \
22712 | ((target_long
)imm
& 0xFFFFFFFF);
22713 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22721 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22722 imm
= (int16_t)(imm
<< 6) >> 6;
22724 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
22725 ((uint64_t)(uint16_t)imm
<< 32) |
22726 ((uint64_t)(uint16_t)imm
<< 16) |
22727 (uint64_t)(uint16_t)imm
;
22728 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22733 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22734 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22735 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22736 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22737 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22738 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22739 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22743 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
22744 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22745 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22749 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22750 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22751 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22752 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22753 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22760 tcg_temp_free(val_t
);
22763 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
22764 uint32_t op1
, uint32_t op2
,
22765 int ret
, int v1
, int v2
, int check_ret
)
22771 if ((ret
== 0) && (check_ret
== 1)) {
22772 /* Treat as NOP. */
22776 t1
= tcg_temp_new();
22777 v1_t
= tcg_temp_new();
22778 v2_t
= tcg_temp_new();
22780 gen_load_gpr(v1_t
, v1
);
22781 gen_load_gpr(v2_t
, v2
);
22784 case OPC_CMPU_EQ_QB_DSP
:
22786 case OPC_CMPU_EQ_QB
:
22788 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
22790 case OPC_CMPU_LT_QB
:
22792 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
22794 case OPC_CMPU_LE_QB
:
22796 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
22798 case OPC_CMPGU_EQ_QB
:
22800 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22802 case OPC_CMPGU_LT_QB
:
22804 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22806 case OPC_CMPGU_LE_QB
:
22808 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22810 case OPC_CMPGDU_EQ_QB
:
22812 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
22813 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22814 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22815 tcg_gen_shli_tl(t1
, t1
, 24);
22816 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22818 case OPC_CMPGDU_LT_QB
:
22820 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
22821 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22822 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22823 tcg_gen_shli_tl(t1
, t1
, 24);
22824 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22826 case OPC_CMPGDU_LE_QB
:
22828 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
22829 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22830 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22831 tcg_gen_shli_tl(t1
, t1
, 24);
22832 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22834 case OPC_CMP_EQ_PH
:
22836 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
22838 case OPC_CMP_LT_PH
:
22840 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
22842 case OPC_CMP_LE_PH
:
22844 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
22848 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22852 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22854 case OPC_PACKRL_PH
:
22856 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22860 #ifdef TARGET_MIPS64
22861 case OPC_CMPU_EQ_OB_DSP
:
22863 case OPC_CMP_EQ_PW
:
22865 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
22867 case OPC_CMP_LT_PW
:
22869 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
22871 case OPC_CMP_LE_PW
:
22873 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
22875 case OPC_CMP_EQ_QH
:
22877 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
22879 case OPC_CMP_LT_QH
:
22881 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
22883 case OPC_CMP_LE_QH
:
22885 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
22887 case OPC_CMPGDU_EQ_OB
:
22889 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22891 case OPC_CMPGDU_LT_OB
:
22893 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22895 case OPC_CMPGDU_LE_OB
:
22897 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22899 case OPC_CMPGU_EQ_OB
:
22901 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22903 case OPC_CMPGU_LT_OB
:
22905 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22907 case OPC_CMPGU_LE_OB
:
22909 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22911 case OPC_CMPU_EQ_OB
:
22913 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
22915 case OPC_CMPU_LT_OB
:
22917 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
22919 case OPC_CMPU_LE_OB
:
22921 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
22923 case OPC_PACKRL_PW
:
22925 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22929 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22933 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22937 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22945 tcg_temp_free(v1_t
);
22946 tcg_temp_free(v2_t
);
22949 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
22950 uint32_t op1
, int rt
, int rs
, int sa
)
22957 /* Treat as NOP. */
22961 t0
= tcg_temp_new();
22962 gen_load_gpr(t0
, rs
);
22965 case OPC_APPEND_DSP
:
22966 switch (MASK_APPEND(ctx
->opcode
)) {
22969 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
22971 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22975 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22976 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
22977 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
22978 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22980 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22984 if (sa
!= 0 && sa
!= 2) {
22985 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
22986 tcg_gen_ext32u_tl(t0
, t0
);
22987 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
22988 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22990 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22992 default: /* Invalid */
22993 MIPS_INVAL("MASK APPEND");
22994 gen_reserved_instruction(ctx
);
22998 #ifdef TARGET_MIPS64
22999 case OPC_DAPPEND_DSP
:
23000 switch (MASK_DAPPEND(ctx
->opcode
)) {
23003 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
23007 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23008 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23009 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23013 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23014 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23015 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23020 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23021 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23022 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23023 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23026 default: /* Invalid */
23027 MIPS_INVAL("MASK DAPPEND");
23028 gen_reserved_instruction(ctx
);
23037 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23038 int ret
, int v1
, int v2
, int check_ret
)
23047 if ((ret
== 0) && (check_ret
== 1)) {
23048 /* Treat as NOP. */
23052 t0
= tcg_temp_new();
23053 t1
= tcg_temp_new();
23054 v1_t
= tcg_temp_new();
23055 v2_t
= tcg_temp_new();
23057 gen_load_gpr(v1_t
, v1
);
23058 gen_load_gpr(v2_t
, v2
);
23061 case OPC_EXTR_W_DSP
:
23065 tcg_gen_movi_tl(t0
, v2
);
23066 tcg_gen_movi_tl(t1
, v1
);
23067 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23070 tcg_gen_movi_tl(t0
, v2
);
23071 tcg_gen_movi_tl(t1
, v1
);
23072 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23074 case OPC_EXTR_RS_W
:
23075 tcg_gen_movi_tl(t0
, v2
);
23076 tcg_gen_movi_tl(t1
, v1
);
23077 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23080 tcg_gen_movi_tl(t0
, v2
);
23081 tcg_gen_movi_tl(t1
, v1
);
23082 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23084 case OPC_EXTRV_S_H
:
23085 tcg_gen_movi_tl(t0
, v2
);
23086 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23089 tcg_gen_movi_tl(t0
, v2
);
23090 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23092 case OPC_EXTRV_R_W
:
23093 tcg_gen_movi_tl(t0
, v2
);
23094 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23096 case OPC_EXTRV_RS_W
:
23097 tcg_gen_movi_tl(t0
, v2
);
23098 gen_helper_extr_rs_w(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_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23106 tcg_gen_movi_tl(t0
, v2
);
23107 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23110 tcg_gen_movi_tl(t0
, v2
);
23111 tcg_gen_movi_tl(t1
, v1
);
23112 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23115 tcg_gen_movi_tl(t0
, v2
);
23116 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23119 imm
= (ctx
->opcode
>> 20) & 0x3F;
23120 tcg_gen_movi_tl(t0
, ret
);
23121 tcg_gen_movi_tl(t1
, imm
);
23122 gen_helper_shilo(t0
, t1
, cpu_env
);
23125 tcg_gen_movi_tl(t0
, ret
);
23126 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23129 tcg_gen_movi_tl(t0
, ret
);
23130 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23133 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23134 tcg_gen_movi_tl(t0
, imm
);
23135 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23138 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23139 tcg_gen_movi_tl(t0
, imm
);
23140 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23144 #ifdef TARGET_MIPS64
23145 case OPC_DEXTR_W_DSP
:
23149 tcg_gen_movi_tl(t0
, ret
);
23150 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23154 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23155 int ac
= (ctx
->opcode
>> 11) & 0x03;
23156 tcg_gen_movi_tl(t0
, shift
);
23157 tcg_gen_movi_tl(t1
, ac
);
23158 gen_helper_dshilo(t0
, t1
, cpu_env
);
23163 int ac
= (ctx
->opcode
>> 11) & 0x03;
23164 tcg_gen_movi_tl(t0
, ac
);
23165 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23169 tcg_gen_movi_tl(t0
, v2
);
23170 tcg_gen_movi_tl(t1
, v1
);
23172 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23175 tcg_gen_movi_tl(t0
, v2
);
23176 gen_helper_dextp(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_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23184 tcg_gen_movi_tl(t0
, v2
);
23185 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23188 tcg_gen_movi_tl(t0
, v2
);
23189 tcg_gen_movi_tl(t1
, v1
);
23190 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23192 case OPC_DEXTR_R_L
:
23193 tcg_gen_movi_tl(t0
, v2
);
23194 tcg_gen_movi_tl(t1
, v1
);
23195 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23197 case OPC_DEXTR_RS_L
:
23198 tcg_gen_movi_tl(t0
, v2
);
23199 tcg_gen_movi_tl(t1
, v1
);
23200 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23203 tcg_gen_movi_tl(t0
, v2
);
23204 tcg_gen_movi_tl(t1
, v1
);
23205 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23207 case OPC_DEXTR_R_W
:
23208 tcg_gen_movi_tl(t0
, v2
);
23209 tcg_gen_movi_tl(t1
, v1
);
23210 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23212 case OPC_DEXTR_RS_W
:
23213 tcg_gen_movi_tl(t0
, v2
);
23214 tcg_gen_movi_tl(t1
, v1
);
23215 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23217 case OPC_DEXTR_S_H
:
23218 tcg_gen_movi_tl(t0
, v2
);
23219 tcg_gen_movi_tl(t1
, v1
);
23220 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23222 case OPC_DEXTRV_S_H
:
23223 tcg_gen_movi_tl(t0
, v2
);
23224 tcg_gen_movi_tl(t1
, v1
);
23225 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23228 tcg_gen_movi_tl(t0
, v2
);
23229 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23231 case OPC_DEXTRV_R_L
:
23232 tcg_gen_movi_tl(t0
, v2
);
23233 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23235 case OPC_DEXTRV_RS_L
:
23236 tcg_gen_movi_tl(t0
, v2
);
23237 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23240 tcg_gen_movi_tl(t0
, v2
);
23241 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23243 case OPC_DEXTRV_R_W
:
23244 tcg_gen_movi_tl(t0
, v2
);
23245 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23247 case OPC_DEXTRV_RS_W
:
23248 tcg_gen_movi_tl(t0
, v2
);
23249 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23258 tcg_temp_free(v1_t
);
23259 tcg_temp_free(v2_t
);
23262 /* End MIPSDSP functions. */
23264 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23266 int rs
, rt
, rd
, sa
;
23269 rs
= (ctx
->opcode
>> 21) & 0x1f;
23270 rt
= (ctx
->opcode
>> 16) & 0x1f;
23271 rd
= (ctx
->opcode
>> 11) & 0x1f;
23272 sa
= (ctx
->opcode
>> 6) & 0x1f;
23274 op1
= MASK_SPECIAL(ctx
->opcode
);
23280 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23290 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23293 MIPS_INVAL("special_r6 muldiv");
23294 gen_reserved_instruction(ctx
);
23300 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23304 if (rt
== 0 && sa
== 1) {
23306 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23307 * We need additionally to check other fields.
23309 gen_cl(ctx
, op1
, rd
, rs
);
23311 gen_reserved_instruction(ctx
);
23315 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23316 gen_helper_do_semihosting(cpu_env
);
23318 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23319 gen_reserved_instruction(ctx
);
23321 generate_exception_end(ctx
, EXCP_DBp
);
23325 #if defined(TARGET_MIPS64)
23328 if (rt
== 0 && sa
== 1) {
23330 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23331 * We need additionally to check other fields.
23333 check_mips_64(ctx
);
23334 gen_cl(ctx
, op1
, rd
, rs
);
23336 gen_reserved_instruction(ctx
);
23344 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23354 check_mips_64(ctx
);
23355 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23358 MIPS_INVAL("special_r6 muldiv");
23359 gen_reserved_instruction(ctx
);
23364 default: /* Invalid */
23365 MIPS_INVAL("special_r6");
23366 gen_reserved_instruction(ctx
);
23371 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23373 int rs
= extract32(ctx
->opcode
, 21, 5);
23374 int rt
= extract32(ctx
->opcode
, 16, 5);
23375 int rd
= extract32(ctx
->opcode
, 11, 5);
23376 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23379 case OPC_MOVN
: /* Conditional move */
23381 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23383 case OPC_MFHI
: /* Move from HI/LO */
23385 gen_HILO(ctx
, op1
, 0, rd
);
23388 case OPC_MTLO
: /* Move to HI/LO */
23389 gen_HILO(ctx
, op1
, 0, rs
);
23393 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23397 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23399 #if defined(TARGET_MIPS64)
23404 check_insn_opc_user_only(ctx
, INSN_R5900
);
23405 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23409 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23411 default: /* Invalid */
23412 MIPS_INVAL("special_tx79");
23413 gen_reserved_instruction(ctx
);
23418 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23420 int rs
, rt
, rd
, sa
;
23423 rs
= (ctx
->opcode
>> 21) & 0x1f;
23424 rt
= (ctx
->opcode
>> 16) & 0x1f;
23425 rd
= (ctx
->opcode
>> 11) & 0x1f;
23426 sa
= (ctx
->opcode
>> 6) & 0x1f;
23428 op1
= MASK_SPECIAL(ctx
->opcode
);
23430 case OPC_MOVN
: /* Conditional move */
23432 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23433 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23434 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23436 case OPC_MFHI
: /* Move from HI/LO */
23438 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23441 case OPC_MTLO
: /* Move to HI/LO */
23442 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23445 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23446 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23447 check_cp1_enabled(ctx
);
23448 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23449 (ctx
->opcode
>> 16) & 1);
23451 generate_exception_err(ctx
, EXCP_CpU
, 1);
23457 check_insn(ctx
, INSN_VR54XX
);
23458 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23459 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23461 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23466 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23468 #if defined(TARGET_MIPS64)
23473 check_insn(ctx
, ISA_MIPS3
);
23474 check_mips_64(ctx
);
23475 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23479 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23482 #ifdef MIPS_STRICT_STANDARD
23483 MIPS_INVAL("SPIM");
23484 gen_reserved_instruction(ctx
);
23486 /* Implemented as RI exception for now. */
23487 MIPS_INVAL("spim (unofficial)");
23488 gen_reserved_instruction(ctx
);
23491 default: /* Invalid */
23492 MIPS_INVAL("special_legacy");
23493 gen_reserved_instruction(ctx
);
23498 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23500 int rs
, rt
, rd
, sa
;
23503 rs
= (ctx
->opcode
>> 21) & 0x1f;
23504 rt
= (ctx
->opcode
>> 16) & 0x1f;
23505 rd
= (ctx
->opcode
>> 11) & 0x1f;
23506 sa
= (ctx
->opcode
>> 6) & 0x1f;
23508 op1
= MASK_SPECIAL(ctx
->opcode
);
23510 case OPC_SLL
: /* Shift with immediate */
23511 if (sa
== 5 && rd
== 0 &&
23512 rs
== 0 && rt
== 0) { /* PAUSE */
23513 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23514 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23515 gen_reserved_instruction(ctx
);
23521 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23524 switch ((ctx
->opcode
>> 21) & 0x1f) {
23526 /* rotr is decoded as srl on non-R2 CPUs */
23527 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23532 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23535 gen_reserved_instruction(ctx
);
23543 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23545 case OPC_SLLV
: /* Shifts */
23547 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23550 switch ((ctx
->opcode
>> 6) & 0x1f) {
23552 /* rotrv is decoded as srlv on non-R2 CPUs */
23553 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23558 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23561 gen_reserved_instruction(ctx
);
23565 case OPC_SLT
: /* Set on less than */
23567 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23569 case OPC_AND
: /* Logic*/
23573 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23576 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23578 case OPC_TGE
: /* Traps */
23584 check_insn(ctx
, ISA_MIPS2
);
23585 gen_trap(ctx
, op1
, rs
, rt
, -1);
23588 /* Pmon entry point, also R4010 selsl */
23589 #ifdef MIPS_STRICT_STANDARD
23590 MIPS_INVAL("PMON / selsl");
23591 gen_reserved_instruction(ctx
);
23593 gen_helper_0e0i(pmon
, sa
);
23597 generate_exception_end(ctx
, EXCP_SYSCALL
);
23600 generate_exception_end(ctx
, EXCP_BREAK
);
23603 check_insn(ctx
, ISA_MIPS2
);
23604 gen_sync(extract32(ctx
->opcode
, 6, 5));
23607 #if defined(TARGET_MIPS64)
23608 /* MIPS64 specific opcodes */
23613 check_insn(ctx
, ISA_MIPS3
);
23614 check_mips_64(ctx
);
23615 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23618 switch ((ctx
->opcode
>> 21) & 0x1f) {
23620 /* drotr is decoded as dsrl on non-R2 CPUs */
23621 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23626 check_insn(ctx
, ISA_MIPS3
);
23627 check_mips_64(ctx
);
23628 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23631 gen_reserved_instruction(ctx
);
23636 switch ((ctx
->opcode
>> 21) & 0x1f) {
23638 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23639 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23644 check_insn(ctx
, ISA_MIPS3
);
23645 check_mips_64(ctx
);
23646 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23649 gen_reserved_instruction(ctx
);
23657 check_insn(ctx
, ISA_MIPS3
);
23658 check_mips_64(ctx
);
23659 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23663 check_insn(ctx
, ISA_MIPS3
);
23664 check_mips_64(ctx
);
23665 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23668 switch ((ctx
->opcode
>> 6) & 0x1f) {
23670 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23671 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23676 check_insn(ctx
, ISA_MIPS3
);
23677 check_mips_64(ctx
);
23678 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23681 gen_reserved_instruction(ctx
);
23687 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
23688 decode_opc_special_r6(env
, ctx
);
23689 } else if (ctx
->insn_flags
& INSN_R5900
) {
23690 decode_opc_special_tx79(env
, ctx
);
23692 decode_opc_special_legacy(env
, ctx
);
23698 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23703 rs
= (ctx
->opcode
>> 21) & 0x1f;
23704 rt
= (ctx
->opcode
>> 16) & 0x1f;
23705 rd
= (ctx
->opcode
>> 11) & 0x1f;
23707 op1
= MASK_SPECIAL2(ctx
->opcode
);
23709 case OPC_MADD
: /* Multiply and add/sub */
23713 check_insn(ctx
, ISA_MIPS_R1
);
23714 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23717 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23720 case OPC_DIVU_G_2F
:
23721 case OPC_MULT_G_2F
:
23722 case OPC_MULTU_G_2F
:
23724 case OPC_MODU_G_2F
:
23725 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23726 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23730 check_insn(ctx
, ISA_MIPS_R1
);
23731 gen_cl(ctx
, op1
, rd
, rs
);
23734 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23735 gen_helper_do_semihosting(cpu_env
);
23738 * XXX: not clear which exception should be raised
23739 * when in debug mode...
23741 check_insn(ctx
, ISA_MIPS_R1
);
23742 generate_exception_end(ctx
, EXCP_DBp
);
23745 #if defined(TARGET_MIPS64)
23748 check_insn(ctx
, ISA_MIPS_R1
);
23749 check_mips_64(ctx
);
23750 gen_cl(ctx
, op1
, rd
, rs
);
23752 case OPC_DMULT_G_2F
:
23753 case OPC_DMULTU_G_2F
:
23754 case OPC_DDIV_G_2F
:
23755 case OPC_DDIVU_G_2F
:
23756 case OPC_DMOD_G_2F
:
23757 case OPC_DMODU_G_2F
:
23758 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23759 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23762 default: /* Invalid */
23763 MIPS_INVAL("special2_legacy");
23764 gen_reserved_instruction(ctx
);
23769 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23771 int rs
, rt
, rd
, sa
;
23775 rs
= (ctx
->opcode
>> 21) & 0x1f;
23776 rt
= (ctx
->opcode
>> 16) & 0x1f;
23777 rd
= (ctx
->opcode
>> 11) & 0x1f;
23778 sa
= (ctx
->opcode
>> 6) & 0x1f;
23779 imm
= (int16_t)ctx
->opcode
>> 7;
23781 op1
= MASK_SPECIAL3(ctx
->opcode
);
23785 /* hint codes 24-31 are reserved and signal RI */
23786 gen_reserved_instruction(ctx
);
23788 /* Treat as NOP. */
23791 check_cp0_enabled(ctx
);
23792 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
23793 gen_cache_operation(ctx
, rt
, rs
, imm
);
23797 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
23800 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23805 /* Treat as NOP. */
23808 op2
= MASK_BSHFL(ctx
->opcode
);
23814 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
23817 gen_bitswap(ctx
, op2
, rd
, rt
);
23822 #ifndef CONFIG_USER_ONLY
23824 if (unlikely(ctx
->gi
<= 1)) {
23825 gen_reserved_instruction(ctx
);
23827 check_cp0_enabled(ctx
);
23828 switch ((ctx
->opcode
>> 6) & 3) {
23829 case 0: /* GINVI */
23830 /* Treat as NOP. */
23832 case 2: /* GINVT */
23833 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
23836 gen_reserved_instruction(ctx
);
23841 #if defined(TARGET_MIPS64)
23843 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
23846 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23849 check_mips_64(ctx
);
23852 /* Treat as NOP. */
23855 op2
= MASK_DBSHFL(ctx
->opcode
);
23865 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
23868 gen_bitswap(ctx
, op2
, rd
, rt
);
23875 default: /* Invalid */
23876 MIPS_INVAL("special3_r6");
23877 gen_reserved_instruction(ctx
);
23882 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23887 rs
= (ctx
->opcode
>> 21) & 0x1f;
23888 rt
= (ctx
->opcode
>> 16) & 0x1f;
23889 rd
= (ctx
->opcode
>> 11) & 0x1f;
23891 op1
= MASK_SPECIAL3(ctx
->opcode
);
23894 case OPC_DIVU_G_2E
:
23896 case OPC_MODU_G_2E
:
23897 case OPC_MULT_G_2E
:
23898 case OPC_MULTU_G_2E
:
23900 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23901 * the same mask and op1.
23903 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
23904 op2
= MASK_ADDUH_QB(ctx
->opcode
);
23907 case OPC_ADDUH_R_QB
:
23909 case OPC_ADDQH_R_PH
:
23911 case OPC_ADDQH_R_W
:
23913 case OPC_SUBUH_R_QB
:
23915 case OPC_SUBQH_R_PH
:
23917 case OPC_SUBQH_R_W
:
23918 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23923 case OPC_MULQ_RS_W
:
23924 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
23927 MIPS_INVAL("MASK ADDUH.QB");
23928 gen_reserved_instruction(ctx
);
23931 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
23932 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23934 gen_reserved_instruction(ctx
);
23938 op2
= MASK_LX(ctx
->opcode
);
23940 #if defined(TARGET_MIPS64)
23946 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
23948 default: /* Invalid */
23949 MIPS_INVAL("MASK LX");
23950 gen_reserved_instruction(ctx
);
23954 case OPC_ABSQ_S_PH_DSP
:
23955 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
23957 case OPC_ABSQ_S_QB
:
23958 case OPC_ABSQ_S_PH
:
23960 case OPC_PRECEQ_W_PHL
:
23961 case OPC_PRECEQ_W_PHR
:
23962 case OPC_PRECEQU_PH_QBL
:
23963 case OPC_PRECEQU_PH_QBR
:
23964 case OPC_PRECEQU_PH_QBLA
:
23965 case OPC_PRECEQU_PH_QBRA
:
23966 case OPC_PRECEU_PH_QBL
:
23967 case OPC_PRECEU_PH_QBR
:
23968 case OPC_PRECEU_PH_QBLA
:
23969 case OPC_PRECEU_PH_QBRA
:
23970 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23977 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
23980 MIPS_INVAL("MASK ABSQ_S.PH");
23981 gen_reserved_instruction(ctx
);
23985 case OPC_ADDU_QB_DSP
:
23986 op2
= MASK_ADDU_QB(ctx
->opcode
);
23989 case OPC_ADDQ_S_PH
:
23992 case OPC_ADDU_S_QB
:
23994 case OPC_ADDU_S_PH
:
23996 case OPC_SUBQ_S_PH
:
23999 case OPC_SUBU_S_QB
:
24001 case OPC_SUBU_S_PH
:
24005 case OPC_RADDU_W_QB
:
24006 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24008 case OPC_MULEU_S_PH_QBL
:
24009 case OPC_MULEU_S_PH_QBR
:
24010 case OPC_MULQ_RS_PH
:
24011 case OPC_MULEQ_S_W_PHL
:
24012 case OPC_MULEQ_S_W_PHR
:
24013 case OPC_MULQ_S_PH
:
24014 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24016 default: /* Invalid */
24017 MIPS_INVAL("MASK ADDU.QB");
24018 gen_reserved_instruction(ctx
);
24023 case OPC_CMPU_EQ_QB_DSP
:
24024 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24026 case OPC_PRECR_SRA_PH_W
:
24027 case OPC_PRECR_SRA_R_PH_W
:
24028 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24030 case OPC_PRECR_QB_PH
:
24031 case OPC_PRECRQ_QB_PH
:
24032 case OPC_PRECRQ_PH_W
:
24033 case OPC_PRECRQ_RS_PH_W
:
24034 case OPC_PRECRQU_S_QB_PH
:
24035 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24037 case OPC_CMPU_EQ_QB
:
24038 case OPC_CMPU_LT_QB
:
24039 case OPC_CMPU_LE_QB
:
24040 case OPC_CMP_EQ_PH
:
24041 case OPC_CMP_LT_PH
:
24042 case OPC_CMP_LE_PH
:
24043 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24045 case OPC_CMPGU_EQ_QB
:
24046 case OPC_CMPGU_LT_QB
:
24047 case OPC_CMPGU_LE_QB
:
24048 case OPC_CMPGDU_EQ_QB
:
24049 case OPC_CMPGDU_LT_QB
:
24050 case OPC_CMPGDU_LE_QB
:
24053 case OPC_PACKRL_PH
:
24054 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24056 default: /* Invalid */
24057 MIPS_INVAL("MASK CMPU.EQ.QB");
24058 gen_reserved_instruction(ctx
);
24062 case OPC_SHLL_QB_DSP
:
24063 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24065 case OPC_DPA_W_PH_DSP
:
24066 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24068 case OPC_DPAU_H_QBL
:
24069 case OPC_DPAU_H_QBR
:
24070 case OPC_DPSU_H_QBL
:
24071 case OPC_DPSU_H_QBR
:
24073 case OPC_DPAX_W_PH
:
24074 case OPC_DPAQ_S_W_PH
:
24075 case OPC_DPAQX_S_W_PH
:
24076 case OPC_DPAQX_SA_W_PH
:
24078 case OPC_DPSX_W_PH
:
24079 case OPC_DPSQ_S_W_PH
:
24080 case OPC_DPSQX_S_W_PH
:
24081 case OPC_DPSQX_SA_W_PH
:
24082 case OPC_MULSAQ_S_W_PH
:
24083 case OPC_DPAQ_SA_L_W
:
24084 case OPC_DPSQ_SA_L_W
:
24085 case OPC_MAQ_S_W_PHL
:
24086 case OPC_MAQ_S_W_PHR
:
24087 case OPC_MAQ_SA_W_PHL
:
24088 case OPC_MAQ_SA_W_PHR
:
24089 case OPC_MULSA_W_PH
:
24090 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24092 default: /* Invalid */
24093 MIPS_INVAL("MASK DPAW.PH");
24094 gen_reserved_instruction(ctx
);
24099 op2
= MASK_INSV(ctx
->opcode
);
24110 t0
= tcg_temp_new();
24111 t1
= tcg_temp_new();
24113 gen_load_gpr(t0
, rt
);
24114 gen_load_gpr(t1
, rs
);
24116 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24122 default: /* Invalid */
24123 MIPS_INVAL("MASK INSV");
24124 gen_reserved_instruction(ctx
);
24128 case OPC_APPEND_DSP
:
24129 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24131 case OPC_EXTR_W_DSP
:
24132 op2
= MASK_EXTR_W(ctx
->opcode
);
24136 case OPC_EXTR_RS_W
:
24138 case OPC_EXTRV_S_H
:
24140 case OPC_EXTRV_R_W
:
24141 case OPC_EXTRV_RS_W
:
24146 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24149 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24155 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24157 default: /* Invalid */
24158 MIPS_INVAL("MASK EXTR.W");
24159 gen_reserved_instruction(ctx
);
24163 #if defined(TARGET_MIPS64)
24164 case OPC_DDIV_G_2E
:
24165 case OPC_DDIVU_G_2E
:
24166 case OPC_DMULT_G_2E
:
24167 case OPC_DMULTU_G_2E
:
24168 case OPC_DMOD_G_2E
:
24169 case OPC_DMODU_G_2E
:
24170 check_insn(ctx
, INSN_LOONGSON2E
);
24171 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24173 case OPC_ABSQ_S_QH_DSP
:
24174 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24176 case OPC_PRECEQ_L_PWL
:
24177 case OPC_PRECEQ_L_PWR
:
24178 case OPC_PRECEQ_PW_QHL
:
24179 case OPC_PRECEQ_PW_QHR
:
24180 case OPC_PRECEQ_PW_QHLA
:
24181 case OPC_PRECEQ_PW_QHRA
:
24182 case OPC_PRECEQU_QH_OBL
:
24183 case OPC_PRECEQU_QH_OBR
:
24184 case OPC_PRECEQU_QH_OBLA
:
24185 case OPC_PRECEQU_QH_OBRA
:
24186 case OPC_PRECEU_QH_OBL
:
24187 case OPC_PRECEU_QH_OBR
:
24188 case OPC_PRECEU_QH_OBLA
:
24189 case OPC_PRECEU_QH_OBRA
:
24190 case OPC_ABSQ_S_OB
:
24191 case OPC_ABSQ_S_PW
:
24192 case OPC_ABSQ_S_QH
:
24193 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24201 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24203 default: /* Invalid */
24204 MIPS_INVAL("MASK ABSQ_S.QH");
24205 gen_reserved_instruction(ctx
);
24209 case OPC_ADDU_OB_DSP
:
24210 op2
= MASK_ADDU_OB(ctx
->opcode
);
24212 case OPC_RADDU_L_OB
:
24214 case OPC_SUBQ_S_PW
:
24216 case OPC_SUBQ_S_QH
:
24218 case OPC_SUBU_S_OB
:
24220 case OPC_SUBU_S_QH
:
24222 case OPC_SUBUH_R_OB
:
24224 case OPC_ADDQ_S_PW
:
24226 case OPC_ADDQ_S_QH
:
24228 case OPC_ADDU_S_OB
:
24230 case OPC_ADDU_S_QH
:
24232 case OPC_ADDUH_R_OB
:
24233 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24235 case OPC_MULEQ_S_PW_QHL
:
24236 case OPC_MULEQ_S_PW_QHR
:
24237 case OPC_MULEU_S_QH_OBL
:
24238 case OPC_MULEU_S_QH_OBR
:
24239 case OPC_MULQ_RS_QH
:
24240 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24242 default: /* Invalid */
24243 MIPS_INVAL("MASK ADDU.OB");
24244 gen_reserved_instruction(ctx
);
24248 case OPC_CMPU_EQ_OB_DSP
:
24249 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24251 case OPC_PRECR_SRA_QH_PW
:
24252 case OPC_PRECR_SRA_R_QH_PW
:
24253 /* Return value is rt. */
24254 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24256 case OPC_PRECR_OB_QH
:
24257 case OPC_PRECRQ_OB_QH
:
24258 case OPC_PRECRQ_PW_L
:
24259 case OPC_PRECRQ_QH_PW
:
24260 case OPC_PRECRQ_RS_QH_PW
:
24261 case OPC_PRECRQU_S_OB_QH
:
24262 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24264 case OPC_CMPU_EQ_OB
:
24265 case OPC_CMPU_LT_OB
:
24266 case OPC_CMPU_LE_OB
:
24267 case OPC_CMP_EQ_QH
:
24268 case OPC_CMP_LT_QH
:
24269 case OPC_CMP_LE_QH
:
24270 case OPC_CMP_EQ_PW
:
24271 case OPC_CMP_LT_PW
:
24272 case OPC_CMP_LE_PW
:
24273 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24275 case OPC_CMPGDU_EQ_OB
:
24276 case OPC_CMPGDU_LT_OB
:
24277 case OPC_CMPGDU_LE_OB
:
24278 case OPC_CMPGU_EQ_OB
:
24279 case OPC_CMPGU_LT_OB
:
24280 case OPC_CMPGU_LE_OB
:
24281 case OPC_PACKRL_PW
:
24285 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24287 default: /* Invalid */
24288 MIPS_INVAL("MASK CMPU_EQ.OB");
24289 gen_reserved_instruction(ctx
);
24293 case OPC_DAPPEND_DSP
:
24294 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24296 case OPC_DEXTR_W_DSP
:
24297 op2
= MASK_DEXTR_W(ctx
->opcode
);
24304 case OPC_DEXTR_R_L
:
24305 case OPC_DEXTR_RS_L
:
24307 case OPC_DEXTR_R_W
:
24308 case OPC_DEXTR_RS_W
:
24309 case OPC_DEXTR_S_H
:
24311 case OPC_DEXTRV_R_L
:
24312 case OPC_DEXTRV_RS_L
:
24313 case OPC_DEXTRV_S_H
:
24315 case OPC_DEXTRV_R_W
:
24316 case OPC_DEXTRV_RS_W
:
24317 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24322 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24324 default: /* Invalid */
24325 MIPS_INVAL("MASK EXTR.W");
24326 gen_reserved_instruction(ctx
);
24330 case OPC_DPAQ_W_QH_DSP
:
24331 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24333 case OPC_DPAU_H_OBL
:
24334 case OPC_DPAU_H_OBR
:
24335 case OPC_DPSU_H_OBL
:
24336 case OPC_DPSU_H_OBR
:
24338 case OPC_DPAQ_S_W_QH
:
24340 case OPC_DPSQ_S_W_QH
:
24341 case OPC_MULSAQ_S_W_QH
:
24342 case OPC_DPAQ_SA_L_PW
:
24343 case OPC_DPSQ_SA_L_PW
:
24344 case OPC_MULSAQ_S_L_PW
:
24345 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24347 case OPC_MAQ_S_W_QHLL
:
24348 case OPC_MAQ_S_W_QHLR
:
24349 case OPC_MAQ_S_W_QHRL
:
24350 case OPC_MAQ_S_W_QHRR
:
24351 case OPC_MAQ_SA_W_QHLL
:
24352 case OPC_MAQ_SA_W_QHLR
:
24353 case OPC_MAQ_SA_W_QHRL
:
24354 case OPC_MAQ_SA_W_QHRR
:
24355 case OPC_MAQ_S_L_PWL
:
24356 case OPC_MAQ_S_L_PWR
:
24361 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24363 default: /* Invalid */
24364 MIPS_INVAL("MASK DPAQ.W.QH");
24365 gen_reserved_instruction(ctx
);
24369 case OPC_DINSV_DSP
:
24370 op2
= MASK_INSV(ctx
->opcode
);
24381 t0
= tcg_temp_new();
24382 t1
= tcg_temp_new();
24384 gen_load_gpr(t0
, rt
);
24385 gen_load_gpr(t1
, rs
);
24387 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24393 default: /* Invalid */
24394 MIPS_INVAL("MASK DINSV");
24395 gen_reserved_instruction(ctx
);
24399 case OPC_SHLL_OB_DSP
:
24400 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24403 default: /* Invalid */
24404 MIPS_INVAL("special3_legacy");
24405 gen_reserved_instruction(ctx
);
24411 #if defined(TARGET_MIPS64)
24413 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24415 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24416 int rs
= extract32(ctx
->opcode
, 21, 5);
24417 int rt
= extract32(ctx
->opcode
, 16, 5);
24418 int rd
= extract32(ctx
->opcode
, 11, 5);
24421 case MMI_OPC_MULT1
:
24422 case MMI_OPC_MULTU1
:
24424 case MMI_OPC_MADDU
:
24425 case MMI_OPC_MADD1
:
24426 case MMI_OPC_MADDU1
:
24427 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24430 case MMI_OPC_DIVU1
:
24431 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24434 MIPS_INVAL("TX79 MMI class");
24435 gen_reserved_instruction(ctx
);
24440 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24442 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24445 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24447 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24451 * The TX79-specific instruction Store Quadword
24453 * +--------+-------+-------+------------------------+
24454 * | 011111 | base | rt | offset | SQ
24455 * +--------+-------+-------+------------------------+
24458 * has the same opcode as the Read Hardware Register instruction
24460 * +--------+-------+-------+-------+-------+--------+
24461 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24462 * +--------+-------+-------+-------+-------+--------+
24465 * that is required, trapped and emulated by the Linux kernel. However, all
24466 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24467 * offset is odd. Therefore all valid SQ instructions can execute normally.
24468 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24469 * between SQ and RDHWR, as the Linux kernel does.
24471 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24473 int base
= extract32(ctx
->opcode
, 21, 5);
24474 int rt
= extract32(ctx
->opcode
, 16, 5);
24475 int offset
= extract32(ctx
->opcode
, 0, 16);
24477 #ifdef CONFIG_USER_ONLY
24478 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
24479 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
24481 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
24482 int rd
= extract32(ctx
->opcode
, 11, 5);
24484 gen_rdhwr(ctx
, rt
, rd
, 0);
24489 gen_mmi_sq(ctx
, base
, rt
, offset
);
24494 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
24496 int rs
, rt
, rd
, sa
;
24500 rs
= (ctx
->opcode
>> 21) & 0x1f;
24501 rt
= (ctx
->opcode
>> 16) & 0x1f;
24502 rd
= (ctx
->opcode
>> 11) & 0x1f;
24503 sa
= (ctx
->opcode
>> 6) & 0x1f;
24504 imm
= sextract32(ctx
->opcode
, 7, 9);
24506 op1
= MASK_SPECIAL3(ctx
->opcode
);
24509 * EVA loads and stores overlap Loongson 2E instructions decoded by
24510 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24523 check_cp0_enabled(ctx
);
24524 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24531 check_cp0_enabled(ctx
);
24532 gen_st(ctx
, op1
, rt
, rs
, imm
);
24535 check_cp0_enabled(ctx
);
24536 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
24540 check_cp0_enabled(ctx
);
24541 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24542 gen_cache_operation(ctx
, rt
, rs
, imm
);
24546 check_cp0_enabled(ctx
);
24547 /* Treat as NOP. */
24555 check_insn(ctx
, ISA_MIPS_R2
);
24556 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24559 op2
= MASK_BSHFL(ctx
->opcode
);
24566 check_insn(ctx
, ISA_MIPS_R6
);
24567 decode_opc_special3_r6(env
, ctx
);
24570 check_insn(ctx
, ISA_MIPS_R2
);
24571 gen_bshfl(ctx
, op2
, rt
, rd
);
24575 #if defined(TARGET_MIPS64)
24582 check_insn(ctx
, ISA_MIPS_R2
);
24583 check_mips_64(ctx
);
24584 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24587 op2
= MASK_DBSHFL(ctx
->opcode
);
24598 check_insn(ctx
, ISA_MIPS_R6
);
24599 decode_opc_special3_r6(env
, ctx
);
24602 check_insn(ctx
, ISA_MIPS_R2
);
24603 check_mips_64(ctx
);
24604 op2
= MASK_DBSHFL(ctx
->opcode
);
24605 gen_bshfl(ctx
, op2
, rt
, rd
);
24611 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
24616 TCGv t0
= tcg_temp_new();
24617 TCGv t1
= tcg_temp_new();
24619 gen_load_gpr(t0
, rt
);
24620 gen_load_gpr(t1
, rs
);
24621 gen_helper_fork(t0
, t1
);
24629 TCGv t0
= tcg_temp_new();
24631 gen_load_gpr(t0
, rs
);
24632 gen_helper_yield(t0
, cpu_env
, t0
);
24633 gen_store_gpr(t0
, rd
);
24638 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24639 decode_opc_special3_r6(env
, ctx
);
24641 decode_opc_special3_legacy(env
, ctx
);
24646 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24649 int rs
, rt
, rd
, sa
;
24653 op
= MASK_OP_MAJOR(ctx
->opcode
);
24654 rs
= (ctx
->opcode
>> 21) & 0x1f;
24655 rt
= (ctx
->opcode
>> 16) & 0x1f;
24656 rd
= (ctx
->opcode
>> 11) & 0x1f;
24657 sa
= (ctx
->opcode
>> 6) & 0x1f;
24658 imm
= (int16_t)ctx
->opcode
;
24661 decode_opc_special(env
, ctx
);
24664 #if defined(TARGET_MIPS64)
24665 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
24666 decode_mmi(env
, ctx
);
24670 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
24671 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
24672 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
24674 decode_ase_mxu(ctx
, ctx
->opcode
);
24678 decode_opc_special2_legacy(env
, ctx
);
24681 #if defined(TARGET_MIPS64)
24682 if (ctx
->insn_flags
& INSN_R5900
) {
24683 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
24685 decode_opc_special3(env
, ctx
);
24688 decode_opc_special3(env
, ctx
);
24692 op1
= MASK_REGIMM(ctx
->opcode
);
24694 case OPC_BLTZL
: /* REGIMM branches */
24698 check_insn(ctx
, ISA_MIPS2
);
24699 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24703 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24707 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24709 /* OPC_NAL, OPC_BAL */
24710 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
24712 gen_reserved_instruction(ctx
);
24715 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24718 case OPC_TGEI
: /* REGIMM traps */
24725 check_insn(ctx
, ISA_MIPS2
);
24726 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24727 gen_trap(ctx
, op1
, rs
, -1, imm
);
24730 check_insn(ctx
, ISA_MIPS_R6
);
24731 gen_reserved_instruction(ctx
);
24734 check_insn(ctx
, ISA_MIPS_R2
);
24736 * Break the TB to be able to sync copied instructions
24739 ctx
->base
.is_jmp
= DISAS_STOP
;
24741 case OPC_BPOSGE32
: /* MIPS DSP branch */
24742 #if defined(TARGET_MIPS64)
24746 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
24748 #if defined(TARGET_MIPS64)
24750 check_insn(ctx
, ISA_MIPS_R6
);
24751 check_mips_64(ctx
);
24753 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
24757 check_insn(ctx
, ISA_MIPS_R6
);
24758 check_mips_64(ctx
);
24760 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
24764 default: /* Invalid */
24765 MIPS_INVAL("regimm");
24766 gen_reserved_instruction(ctx
);
24771 check_cp0_enabled(ctx
);
24772 op1
= MASK_CP0(ctx
->opcode
);
24780 #if defined(TARGET_MIPS64)
24784 #ifndef CONFIG_USER_ONLY
24785 gen_cp0(env
, ctx
, op1
, rt
, rd
);
24786 #endif /* !CONFIG_USER_ONLY */
24804 #ifndef CONFIG_USER_ONLY
24805 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
24806 #endif /* !CONFIG_USER_ONLY */
24809 #ifndef CONFIG_USER_ONLY
24812 TCGv t0
= tcg_temp_new();
24814 op2
= MASK_MFMC0(ctx
->opcode
);
24818 gen_helper_dmt(t0
);
24819 gen_store_gpr(t0
, rt
);
24823 gen_helper_emt(t0
);
24824 gen_store_gpr(t0
, rt
);
24828 gen_helper_dvpe(t0
, cpu_env
);
24829 gen_store_gpr(t0
, rt
);
24833 gen_helper_evpe(t0
, cpu_env
);
24834 gen_store_gpr(t0
, rt
);
24837 check_insn(ctx
, ISA_MIPS_R6
);
24839 gen_helper_dvp(t0
, cpu_env
);
24840 gen_store_gpr(t0
, rt
);
24844 check_insn(ctx
, ISA_MIPS_R6
);
24846 gen_helper_evp(t0
, cpu_env
);
24847 gen_store_gpr(t0
, rt
);
24851 check_insn(ctx
, ISA_MIPS_R2
);
24852 save_cpu_state(ctx
, 1);
24853 gen_helper_di(t0
, cpu_env
);
24854 gen_store_gpr(t0
, rt
);
24856 * Stop translation as we may have switched
24857 * the execution mode.
24859 ctx
->base
.is_jmp
= DISAS_STOP
;
24862 check_insn(ctx
, ISA_MIPS_R2
);
24863 save_cpu_state(ctx
, 1);
24864 gen_helper_ei(t0
, cpu_env
);
24865 gen_store_gpr(t0
, rt
);
24867 * DISAS_STOP isn't sufficient, we need to ensure we break
24868 * out of translated code to check for pending interrupts.
24870 gen_save_pc(ctx
->base
.pc_next
+ 4);
24871 ctx
->base
.is_jmp
= DISAS_EXIT
;
24873 default: /* Invalid */
24874 MIPS_INVAL("mfmc0");
24875 gen_reserved_instruction(ctx
);
24880 #endif /* !CONFIG_USER_ONLY */
24883 check_insn(ctx
, ISA_MIPS_R2
);
24884 gen_load_srsgpr(rt
, rd
);
24887 check_insn(ctx
, ISA_MIPS_R2
);
24888 gen_store_srsgpr(rt
, rd
);
24892 gen_reserved_instruction(ctx
);
24896 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
24897 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24898 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
24899 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24902 /* Arithmetic with immediate opcode */
24903 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24907 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24909 case OPC_SLTI
: /* Set on less than with immediate opcode */
24911 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
24913 case OPC_ANDI
: /* Arithmetic with immediate opcode */
24914 case OPC_LUI
: /* OPC_AUI */
24917 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
24919 case OPC_J
: /* Jump */
24921 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
24922 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
24925 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
24926 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24928 gen_reserved_instruction(ctx
);
24931 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
24932 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24935 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24938 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
24939 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24941 gen_reserved_instruction(ctx
);
24944 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
24945 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24948 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24951 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
24954 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24956 check_insn(ctx
, ISA_MIPS_R6
);
24957 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
24958 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24961 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
24964 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24966 check_insn(ctx
, ISA_MIPS_R6
);
24967 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
24968 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24973 check_insn(ctx
, ISA_MIPS2
);
24974 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24978 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24980 case OPC_LL
: /* Load and stores */
24981 check_insn(ctx
, ISA_MIPS2
);
24982 if (ctx
->insn_flags
& INSN_R5900
) {
24983 check_insn_opc_user_only(ctx
, INSN_R5900
);
24994 gen_ld(ctx
, op
, rt
, rs
, imm
);
25001 gen_st(ctx
, op
, rt
, rs
, imm
);
25004 check_insn(ctx
, ISA_MIPS2
);
25005 if (ctx
->insn_flags
& INSN_R5900
) {
25006 check_insn_opc_user_only(ctx
, INSN_R5900
);
25008 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25011 check_cp0_enabled(ctx
);
25012 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25013 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25014 gen_cache_operation(ctx
, rt
, rs
, imm
);
25016 /* Treat as NOP. */
25019 if (ctx
->insn_flags
& INSN_R5900
) {
25020 /* Treat as NOP. */
25022 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25023 /* Treat as NOP. */
25027 /* Floating point (COP1). */
25032 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25036 op1
= MASK_CP1(ctx
->opcode
);
25041 check_cp1_enabled(ctx
);
25042 check_insn(ctx
, ISA_MIPS_R2
);
25048 check_cp1_enabled(ctx
);
25049 gen_cp1(ctx
, op1
, rt
, rd
);
25051 #if defined(TARGET_MIPS64)
25054 check_cp1_enabled(ctx
);
25055 check_insn(ctx
, ISA_MIPS3
);
25056 check_mips_64(ctx
);
25057 gen_cp1(ctx
, op1
, rt
, rd
);
25060 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25061 check_cp1_enabled(ctx
);
25062 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25064 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25069 check_insn(ctx
, ASE_MIPS3D
);
25070 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25071 (rt
>> 2) & 0x7, imm
<< 2);
25075 check_cp1_enabled(ctx
);
25076 check_insn(ctx
, ISA_MIPS_R6
);
25077 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25081 check_cp1_enabled(ctx
);
25082 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25084 check_insn(ctx
, ASE_MIPS3D
);
25087 check_cp1_enabled(ctx
);
25088 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25089 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25090 (rt
>> 2) & 0x7, imm
<< 2);
25097 check_cp1_enabled(ctx
);
25098 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25104 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25105 check_cp1_enabled(ctx
);
25106 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25108 case R6_OPC_CMP_AF_S
:
25109 case R6_OPC_CMP_UN_S
:
25110 case R6_OPC_CMP_EQ_S
:
25111 case R6_OPC_CMP_UEQ_S
:
25112 case R6_OPC_CMP_LT_S
:
25113 case R6_OPC_CMP_ULT_S
:
25114 case R6_OPC_CMP_LE_S
:
25115 case R6_OPC_CMP_ULE_S
:
25116 case R6_OPC_CMP_SAF_S
:
25117 case R6_OPC_CMP_SUN_S
:
25118 case R6_OPC_CMP_SEQ_S
:
25119 case R6_OPC_CMP_SEUQ_S
:
25120 case R6_OPC_CMP_SLT_S
:
25121 case R6_OPC_CMP_SULT_S
:
25122 case R6_OPC_CMP_SLE_S
:
25123 case R6_OPC_CMP_SULE_S
:
25124 case R6_OPC_CMP_OR_S
:
25125 case R6_OPC_CMP_UNE_S
:
25126 case R6_OPC_CMP_NE_S
:
25127 case R6_OPC_CMP_SOR_S
:
25128 case R6_OPC_CMP_SUNE_S
:
25129 case R6_OPC_CMP_SNE_S
:
25130 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25132 case R6_OPC_CMP_AF_D
:
25133 case R6_OPC_CMP_UN_D
:
25134 case R6_OPC_CMP_EQ_D
:
25135 case R6_OPC_CMP_UEQ_D
:
25136 case R6_OPC_CMP_LT_D
:
25137 case R6_OPC_CMP_ULT_D
:
25138 case R6_OPC_CMP_LE_D
:
25139 case R6_OPC_CMP_ULE_D
:
25140 case R6_OPC_CMP_SAF_D
:
25141 case R6_OPC_CMP_SUN_D
:
25142 case R6_OPC_CMP_SEQ_D
:
25143 case R6_OPC_CMP_SEUQ_D
:
25144 case R6_OPC_CMP_SLT_D
:
25145 case R6_OPC_CMP_SULT_D
:
25146 case R6_OPC_CMP_SLE_D
:
25147 case R6_OPC_CMP_SULE_D
:
25148 case R6_OPC_CMP_OR_D
:
25149 case R6_OPC_CMP_UNE_D
:
25150 case R6_OPC_CMP_NE_D
:
25151 case R6_OPC_CMP_SOR_D
:
25152 case R6_OPC_CMP_SUNE_D
:
25153 case R6_OPC_CMP_SNE_D
:
25154 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25157 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25158 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25163 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25170 gen_reserved_instruction(ctx
);
25175 /* Compact branches [R6] and COP2 [non-R6] */
25176 case OPC_BC
: /* OPC_LWC2 */
25177 case OPC_BALC
: /* OPC_SWC2 */
25178 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25179 /* OPC_BC, OPC_BALC */
25180 gen_compute_compact_branch(ctx
, op
, 0, 0,
25181 sextract32(ctx
->opcode
<< 2, 0, 28));
25182 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25183 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25185 /* OPC_LWC2, OPC_SWC2 */
25186 /* COP2: Not implemented. */
25187 generate_exception_err(ctx
, EXCP_CpU
, 2);
25190 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25191 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25192 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25194 /* OPC_BEQZC, OPC_BNEZC */
25195 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25196 sextract32(ctx
->opcode
<< 2, 0, 23));
25198 /* OPC_JIC, OPC_JIALC */
25199 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25201 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25202 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25204 /* OPC_LWC2, OPC_SWC2 */
25205 /* COP2: Not implemented. */
25206 generate_exception_err(ctx
, EXCP_CpU
, 2);
25210 check_insn(ctx
, ASE_LMMI
);
25211 /* Note that these instructions use different fields. */
25212 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25216 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25217 check_cp1_enabled(ctx
);
25218 op1
= MASK_CP3(ctx
->opcode
);
25222 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25228 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25229 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25232 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25233 /* Treat as NOP. */
25236 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25250 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25251 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25255 gen_reserved_instruction(ctx
);
25259 generate_exception_err(ctx
, EXCP_CpU
, 1);
25263 #if defined(TARGET_MIPS64)
25264 /* MIPS64 opcodes */
25266 if (ctx
->insn_flags
& INSN_R5900
) {
25267 check_insn_opc_user_only(ctx
, INSN_R5900
);
25274 check_insn(ctx
, ISA_MIPS3
);
25275 check_mips_64(ctx
);
25276 gen_ld(ctx
, op
, rt
, rs
, imm
);
25281 check_insn(ctx
, ISA_MIPS3
);
25282 check_mips_64(ctx
);
25283 gen_st(ctx
, op
, rt
, rs
, imm
);
25286 check_insn(ctx
, ISA_MIPS3
);
25287 if (ctx
->insn_flags
& INSN_R5900
) {
25288 check_insn_opc_user_only(ctx
, INSN_R5900
);
25290 check_mips_64(ctx
);
25291 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25293 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25294 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25295 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25296 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25299 check_insn(ctx
, ISA_MIPS3
);
25300 check_mips_64(ctx
);
25301 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25305 check_insn(ctx
, ISA_MIPS3
);
25306 check_mips_64(ctx
);
25307 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25310 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25311 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25312 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25314 MIPS_INVAL("major opcode");
25315 gen_reserved_instruction(ctx
);
25319 case OPC_DAUI
: /* OPC_JALX */
25320 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25321 #if defined(TARGET_MIPS64)
25323 check_mips_64(ctx
);
25325 generate_exception(ctx
, EXCP_RI
);
25326 } else if (rt
!= 0) {
25327 TCGv t0
= tcg_temp_new();
25328 gen_load_gpr(t0
, rs
);
25329 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25333 gen_reserved_instruction(ctx
);
25334 MIPS_INVAL("major opcode");
25338 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25339 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25340 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25343 case OPC_MDMX
: /* MMI_OPC_LQ */
25344 if (ctx
->insn_flags
& INSN_R5900
) {
25345 #if defined(TARGET_MIPS64)
25346 gen_mmi_lq(env
, ctx
);
25349 /* MDMX: Not implemented. */
25353 check_insn(ctx
, ISA_MIPS_R6
);
25354 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25356 default: /* Invalid */
25357 MIPS_INVAL("major opcode");
25363 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25365 /* make sure instructions are on a word boundary */
25366 if (ctx
->base
.pc_next
& 0x3) {
25367 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25368 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25372 /* Handle blikely not taken case */
25373 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25374 TCGLabel
*l1
= gen_new_label();
25376 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25377 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25378 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25382 /* Transition to the auto-generated decoder. */
25384 /* ISA extensions */
25385 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25389 /* ISA (from latest to oldest) */
25390 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25393 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25397 if (decode_opc_legacy(env
, ctx
)) {
25401 gen_reserved_instruction(ctx
);
25404 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25406 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25407 CPUMIPSState
*env
= cs
->env_ptr
;
25409 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25410 ctx
->saved_pc
= -1;
25411 ctx
->insn_flags
= env
->insn_flags
;
25412 ctx
->CP0_Config1
= env
->CP0_Config1
;
25413 ctx
->CP0_Config2
= env
->CP0_Config2
;
25414 ctx
->CP0_Config3
= env
->CP0_Config3
;
25415 ctx
->CP0_Config5
= env
->CP0_Config5
;
25417 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25418 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25419 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25420 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25421 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25422 ctx
->PAMask
= env
->PAMask
;
25423 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25424 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25425 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25426 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25427 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25428 /* Restore delay slot state from the tb context. */
25429 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25430 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25431 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25432 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25433 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25434 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25435 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25436 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25437 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25438 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25439 restore_cpu_state(env
, ctx
);
25440 #ifdef CONFIG_USER_ONLY
25441 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25443 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25445 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25446 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25448 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25452 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25456 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25458 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25460 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25464 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25465 const CPUBreakpoint
*bp
)
25467 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25469 save_cpu_state(ctx
, 1);
25470 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25471 gen_helper_raise_exception_debug(cpu_env
);
25473 * The address covered by the breakpoint must be included in
25474 * [tb->pc, tb->pc + tb->size) in order to for it to be
25475 * properly cleared -- thus we increment the PC here so that
25476 * the logic setting tb->size below does the right thing.
25478 ctx
->base
.pc_next
+= 4;
25482 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
25484 CPUMIPSState
*env
= cs
->env_ptr
;
25485 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25489 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
25490 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
25491 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25492 insn_bytes
= decode_nanomips_opc(env
, ctx
);
25493 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
25494 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
25496 decode_opc(env
, ctx
);
25497 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
25498 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25499 insn_bytes
= decode_micromips_opc(env
, ctx
);
25500 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
25501 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25502 insn_bytes
= decode_mips16_opc(env
, ctx
);
25504 gen_reserved_instruction(ctx
);
25505 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
25509 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
25510 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
25511 MIPS_HFLAG_FBNSLOT
))) {
25513 * Force to generate branch as there is neither delay nor
25518 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
25519 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
25521 * Force to generate branch as microMIPS R6 doesn't restrict
25522 * branches in the forbidden slot.
25528 gen_branch(ctx
, insn_bytes
);
25530 ctx
->base
.pc_next
+= insn_bytes
;
25532 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
25536 * Execute a branch and its delay slot as a single instruction.
25537 * This is what GDB expects and is consistent with what the
25538 * hardware does (e.g. if a delay slot instruction faults, the
25539 * reported PC is the PC of the branch).
25541 if (ctx
->base
.singlestep_enabled
&&
25542 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
25543 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25545 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
25546 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25550 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
25552 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25554 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
25555 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
25556 gen_helper_raise_exception_debug(cpu_env
);
25558 switch (ctx
->base
.is_jmp
) {
25560 gen_save_pc(ctx
->base
.pc_next
);
25561 tcg_gen_lookup_and_goto_ptr();
25564 case DISAS_TOO_MANY
:
25565 save_cpu_state(ctx
, 0);
25566 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
25569 tcg_gen_exit_tb(NULL
, 0);
25571 case DISAS_NORETURN
:
25574 g_assert_not_reached();
25579 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
25581 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
25582 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
25585 static const TranslatorOps mips_tr_ops
= {
25586 .init_disas_context
= mips_tr_init_disas_context
,
25587 .tb_start
= mips_tr_tb_start
,
25588 .insn_start
= mips_tr_insn_start
,
25589 .breakpoint_check
= mips_tr_breakpoint_check
,
25590 .translate_insn
= mips_tr_translate_insn
,
25591 .tb_stop
= mips_tr_tb_stop
,
25592 .disas_log
= mips_tr_disas_log
,
25595 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
25599 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
25602 void mips_tcg_init(void)
25607 for (i
= 1; i
< 32; i
++)
25608 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
25609 offsetof(CPUMIPSState
,
25612 #if defined(TARGET_MIPS64)
25613 cpu_gpr_hi
[0] = NULL
;
25615 for (unsigned i
= 1; i
< 32; i
++) {
25616 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
25618 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
25619 offsetof(CPUMIPSState
,
25620 active_tc
.gpr_hi
[i
]),
25623 #endif /* !TARGET_MIPS64 */
25624 for (i
= 0; i
< 32; i
++) {
25625 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
25627 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
25629 msa_translate_init();
25630 cpu_PC
= tcg_global_mem_new(cpu_env
,
25631 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
25632 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
25633 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
25634 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
25636 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
25637 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
25640 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
25641 offsetof(CPUMIPSState
,
25642 active_tc
.DSPControl
),
25644 bcond
= tcg_global_mem_new(cpu_env
,
25645 offsetof(CPUMIPSState
, bcond
), "bcond");
25646 btarget
= tcg_global_mem_new(cpu_env
,
25647 offsetof(CPUMIPSState
, btarget
), "btarget");
25648 hflags
= tcg_global_mem_new_i32(cpu_env
,
25649 offsetof(CPUMIPSState
, hflags
), "hflags");
25651 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
25652 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
25654 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
25655 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
25657 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
25659 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
25662 if (TARGET_LONG_BITS
== 32) {
25663 mxu_translate_init();
25667 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
25668 target_ulong
*data
)
25670 env
->active_tc
.PC
= data
[0];
25671 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
25672 env
->hflags
|= data
[1];
25673 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
25674 case MIPS_HFLAG_BR
:
25676 case MIPS_HFLAG_BC
:
25677 case MIPS_HFLAG_BL
:
25679 env
->btarget
= data
[2];