MIPS patches queue
- Migrate missing CP0 TLB MemoryMapID register (Yongbok) - Enable MSA ASE for mips32r6-generic (Aleksandar) - Convert Loongson LEXT opcodes to decodetree (Philippe) - Introduce ase_3d_available and disas_mt_available helpers (Philippe) -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmcopxgACgkQ4+MsLN6t wN4DzQ//UPDSvcwCj6QIZ2TR2oKG5JIVRYrep7aUb+LdK1uus8P2G9REMnr1X/uC 817aiUC6fK/PJEGAo6dTCKrPnMz71YAHM2259jreQXVZtCzOEzU9Fg9RHBCrbzxP +kL+Sjzvnw3Kp0jVB1sgNn8PhKCkIVg9Go6tr4sXyTjINzsNbk78H6w3O4YlFOSX dbQLWDpFQQRvliiSJR5erQyELs1tVJt+76aab9mM7uWvSbpX/6O80bJ607fUFG8J t07c5u6aOU1MaZrGE5KO6G7BQwqYE/O3lGAd1akj8UMQNxJY8lrS+4bxH9+vjJTF ojRdTRGa2cXC1wxiifFphUNfJe2fH+Wvjtdpgnu3vdp17J0wbnJyw5PmZolS2RI6 w9rAn1xnF2C/2HVZw37+Ghf+sdR9EgewgPAGoU1bKN4iQVE7FX1B4B6rIuq5Zxje l2EFyFzkVWFDd+uy62o6WdH8mgwlHySxUkDeUgLLJwjupVKKvm4FCs0r8CE3g5RZ GkHW6iOVg7QqR4OveGe3BGVK41Gex/iU7WNDWqQ2xqXDywnyFuTQVs/y2b7dPtMd dbcQ6a/zFQl+WdhhnE5S1Y4Pjfw0TQ/+nKd+jc8lme8eihUbPvETfDLk3j0JI9xd eXf4plnVMy33qvlLG4GVYzjYU+jNlGK1KCBcBFccFWasLo75Lyk= =Ocl+ -----END PGP SIGNATURE----- Merge tag 'mips-20241104' of https://github.com/philmd/qemu into staging MIPS patches queue - Migrate missing CP0 TLB MemoryMapID register (Yongbok) - Enable MSA ASE for mips32r6-generic (Aleksandar) - Convert Loongson LEXT opcodes to decodetree (Philippe) - Introduce ase_3d_available and disas_mt_available helpers (Philippe) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmcopxgACgkQ4+MsLN6t # wN4DzQ//UPDSvcwCj6QIZ2TR2oKG5JIVRYrep7aUb+LdK1uus8P2G9REMnr1X/uC # 817aiUC6fK/PJEGAo6dTCKrPnMz71YAHM2259jreQXVZtCzOEzU9Fg9RHBCrbzxP # +kL+Sjzvnw3Kp0jVB1sgNn8PhKCkIVg9Go6tr4sXyTjINzsNbk78H6w3O4YlFOSX # dbQLWDpFQQRvliiSJR5erQyELs1tVJt+76aab9mM7uWvSbpX/6O80bJ607fUFG8J # t07c5u6aOU1MaZrGE5KO6G7BQwqYE/O3lGAd1akj8UMQNxJY8lrS+4bxH9+vjJTF # ojRdTRGa2cXC1wxiifFphUNfJe2fH+Wvjtdpgnu3vdp17J0wbnJyw5PmZolS2RI6 # w9rAn1xnF2C/2HVZw37+Ghf+sdR9EgewgPAGoU1bKN4iQVE7FX1B4B6rIuq5Zxje # l2EFyFzkVWFDd+uy62o6WdH8mgwlHySxUkDeUgLLJwjupVKKvm4FCs0r8CE3g5RZ # GkHW6iOVg7QqR4OveGe3BGVK41Gex/iU7WNDWqQ2xqXDywnyFuTQVs/y2b7dPtMd # dbcQ6a/zFQl+WdhhnE5S1Y4Pjfw0TQ/+nKd+jc8lme8eihUbPvETfDLk3j0JI9xd # eXf4plnVMy33qvlLG4GVYzjYU+jNlGK1KCBcBFccFWasLo75Lyk= # =Ocl+ # -----END PGP SIGNATURE----- # gpg: Signature made Mon 04 Nov 2024 10:51:04 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'mips-20241104' of https://github.com/philmd/qemu: target/mips: Remove unused CPUMIPSState::current_fpu field target/mips: Introduce disas_mt_available() target/mips: Introduce ase_3d_available() helper target/mips: Remove unreachable 32-bit code on 64-bit Loongson Ext target/mips: Convert Loongson [D]MULT[U].G opcodes to decodetree target/mips: Convert Loongson [D]MOD[U].G opcodes to decodetree target/mips: Convert Loongson [D]DIVU.G opcodes to decodetree target/mips: Convert Loongson DIV.G opcodes to decodetree target/mips: Convert Loongson DDIV.G opcodes to decodetree target/mips: Re-introduce OPC_ADDUH_QB_DSP and OPC_MUL_PH_DSP target/mips: Simplify Loongson MULTU.G opcode target/mips: Extract decode_64bit_enabled() helper target/mips: Enable MSA ASE for mips32r6-generic target/mips: Migrate TLB MemoryMapID register Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
67194c7018
@ -314,7 +314,7 @@ const mips_def_t mips_defs[] =
|
||||
(0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
|
||||
.SEGBITS = 32,
|
||||
.PABITS = 32,
|
||||
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT,
|
||||
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
@ -478,14 +478,15 @@ const mips_def_t mips_defs[] =
|
||||
(2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
|
||||
(0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
|
||||
.CP0_Config2 = MIPS_CONFIG2,
|
||||
.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_BP) | (1 << CP0C3_BI) |
|
||||
.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_MSAP) |
|
||||
(1 << CP0C3_BP) | (1 << CP0C3_BI) |
|
||||
(2 << CP0C3_ISA) | (1 << CP0C3_ULRI) |
|
||||
(1 << CP0C3_RXI) | (1U << CP0C3_M),
|
||||
.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
|
||||
(3 << CP0C4_IE) | (1U << CP0C4_M),
|
||||
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_LLB),
|
||||
.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
|
||||
(1 << CP0C5_UFE),
|
||||
.CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) |
|
||||
(1 << CP0C5_FRE) | (1 << CP0C5_SBRI),
|
||||
.CP0_LLAddr_rw_bitmask = 0,
|
||||
.CP0_LLAddr_shift = 0,
|
||||
.SYNCI_Step = 32,
|
||||
@ -499,6 +500,7 @@ const mips_def_t mips_defs[] =
|
||||
(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
.CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
|
||||
.CP1_fcr31_rw_bitmask = 0x0103FFFF,
|
||||
.MSAIR = 0x03 << MSAIR_ProcID,
|
||||
.SEGBITS = 32,
|
||||
.PABITS = 32,
|
||||
.insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
|
||||
@ -541,7 +543,7 @@ const mips_def_t mips_defs[] =
|
||||
.SEGBITS = 32,
|
||||
.PABITS = 32,
|
||||
.insn_flags = CPU_MIPS32R6 | ISA_NANOMIPS32 |
|
||||
ASE_DSP | ASE_DSP_R2 | ASE_DSP_R3 | ASE_MT,
|
||||
ASE_DSP | ASE_DSP_R2 | ASE_DSP_R3,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
#if defined(TARGET_MIPS64)
|
||||
@ -661,7 +663,7 @@ const mips_def_t mips_defs[] =
|
||||
.CP1_fcr31_rw_bitmask = 0xFF83FFFF,
|
||||
.SEGBITS = 40,
|
||||
.PABITS = 36,
|
||||
.insn_flags = CPU_MIPS64R1 | ASE_MIPS3D,
|
||||
.insn_flags = CPU_MIPS64R1,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
@ -690,7 +692,7 @@ const mips_def_t mips_defs[] =
|
||||
.CP1_fcr31_rw_bitmask = 0xFF83FFFF,
|
||||
.SEGBITS = 42,
|
||||
.PABITS = 36,
|
||||
.insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
|
||||
.insn_flags = CPU_MIPS64R2,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
|
@ -530,7 +530,6 @@ typedef struct CPUArchState {
|
||||
CPUMIPSFPUContext active_fpu;
|
||||
|
||||
uint32_t current_tc;
|
||||
uint32_t current_fpu;
|
||||
|
||||
uint32_t SEGBITS;
|
||||
uint32_t PABITS;
|
||||
@ -1319,6 +1318,12 @@ bool cpu_type_supports_cps_smp(const char *cpu_type);
|
||||
bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask);
|
||||
bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa);
|
||||
|
||||
/* Check presence of MIPS-3D ASE */
|
||||
static inline bool ase_3d_available(const CPUMIPSState *env)
|
||||
{
|
||||
return env->active_fpu.fcr0 & (1 << FCR0_3D);
|
||||
}
|
||||
|
||||
/* Check presence of MSA implementation */
|
||||
static inline bool ase_msa_available(CPUMIPSState *env)
|
||||
{
|
||||
|
@ -26,12 +26,10 @@
|
||||
* bits 24-39: MIPS ASEs
|
||||
*/
|
||||
#define ASE_MIPS16 0x0000000001000000ULL
|
||||
#define ASE_MIPS3D 0x0000000002000000ULL
|
||||
#define ASE_MDMX 0x0000000004000000ULL
|
||||
#define ASE_DSP 0x0000000008000000ULL
|
||||
#define ASE_DSP_R2 0x0000000010000000ULL
|
||||
#define ASE_DSP_R3 0x0000000020000000ULL
|
||||
#define ASE_MT 0x0000000040000000ULL
|
||||
#define ASE_SMARTMIPS 0x0000000080000000ULL
|
||||
#define ASE_MICROMIPS 0x0000000100000000ULL
|
||||
/*
|
||||
|
@ -142,6 +142,7 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size,
|
||||
qemu_get_betls(f, &v->VPN);
|
||||
qemu_get_be32s(f, &v->PageMask);
|
||||
qemu_get_be16s(f, &v->ASID);
|
||||
qemu_get_be32s(f, &v->MMID);
|
||||
qemu_get_be16s(f, &flags);
|
||||
v->G = (flags >> 10) & 1;
|
||||
v->C0 = (flags >> 7) & 3;
|
||||
@ -167,6 +168,7 @@ static int put_tlb(QEMUFile *f, void *pv, size_t size,
|
||||
r4k_tlb_t *v = pv;
|
||||
|
||||
uint16_t asid = v->ASID;
|
||||
uint32_t mmid = v->MMID;
|
||||
uint16_t flags = ((v->EHINV << 15) |
|
||||
(v->RI1 << 14) |
|
||||
(v->RI0 << 13) |
|
||||
@ -183,6 +185,7 @@ static int put_tlb(QEMUFile *f, void *pv, size_t size,
|
||||
qemu_put_betls(f, &v->VPN);
|
||||
qemu_put_be32s(f, &v->PageMask);
|
||||
qemu_put_be16s(f, &asid);
|
||||
qemu_put_be32s(f, &mmid);
|
||||
qemu_put_be16s(f, &flags);
|
||||
qemu_put_be64s(f, &v->PFN[0]);
|
||||
qemu_put_be64s(f, &v->PFN[1]);
|
||||
@ -204,8 +207,8 @@ static const VMStateInfo vmstate_info_tlb = {
|
||||
|
||||
static const VMStateDescription vmstate_tlb = {
|
||||
.name = "cpu/tlb",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext),
|
||||
VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext),
|
||||
@ -239,7 +242,7 @@ const VMStateDescription vmstate_mips_cpu = {
|
||||
|
||||
/* CPU metastate */
|
||||
VMSTATE_UINT32(env.current_tc, MIPSCPU),
|
||||
VMSTATE_UINT32(env.current_fpu, MIPSCPU),
|
||||
VMSTATE_UNUSED(sizeof(uint32_t)), /* was current_fpu */
|
||||
VMSTATE_INT32(env.error_code, MIPSCPU),
|
||||
VMSTATE_UINTTL(env.btarget, MIPSCPU),
|
||||
VMSTATE_UINTTL(env.bcond, MIPSCPU),
|
||||
|
27
target/mips/tcg/godson2.decode
Normal file
27
target/mips/tcg/godson2.decode
Normal file
@ -0,0 +1,27 @@
|
||||
# Godson2 64-bit Integer instructions
|
||||
#
|
||||
# Copyright (C) 2021 Philippe Mathieu-Daudé
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# Reference:
|
||||
# Godson-2E Software Manual
|
||||
# (Document Number: godson2e-user-manual-V0.6)
|
||||
#
|
||||
|
||||
&muldiv rs rt rd
|
||||
|
||||
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
|
||||
|
||||
MULTu_G 011111 ..... ..... ..... 00000 01100- @rs_rt_rd
|
||||
DMULTu_G 011111 ..... ..... ..... 00000 01110- @rs_rt_rd
|
||||
|
||||
DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd
|
||||
DIVU_G 011111 ..... ..... ..... 00000 011011 @rs_rt_rd
|
||||
DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd
|
||||
DDIVU_G 011111 ..... ..... ..... 00000 011111 @rs_rt_rd
|
||||
|
||||
MOD_G 011111 ..... ..... ..... 00000 100010 @rs_rt_rd
|
||||
MODU_G 011111 ..... ..... ..... 00000 100011 @rs_rt_rd
|
||||
DMOD_G 011111 ..... ..... ..... 00000 100110 @rs_rt_rd
|
||||
DMODU_G 011111 ..... ..... ..... 00000 100111 @rs_rt_rd
|
28
target/mips/tcg/loong-ext.decode
Normal file
28
target/mips/tcg/loong-ext.decode
Normal file
@ -0,0 +1,28 @@
|
||||
# Loongson 64-bit Extension instructions
|
||||
#
|
||||
# Copyright (C) 2021 Philippe Mathieu-Daudé
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# Reference:
|
||||
# STLS2F01 User Manual
|
||||
# Appendix A: new integer instructions
|
||||
# (Document Number: UM0447)
|
||||
#
|
||||
|
||||
&muldiv rs rt rd !extern
|
||||
|
||||
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
|
||||
|
||||
MULTu_G 011100 ..... ..... ..... 00000 0100-0 @rs_rt_rd
|
||||
DMULTu_G 011100 ..... ..... ..... 00000 0100-1 @rs_rt_rd
|
||||
|
||||
DIV_G 011100 ..... ..... ..... 00000 010100 @rs_rt_rd
|
||||
DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd
|
||||
DIVU_G 011100 ..... ..... ..... 00000 010110 @rs_rt_rd
|
||||
DDIVU_G 011100 ..... ..... ..... 00000 010111 @rs_rt_rd
|
||||
|
||||
MOD_G 011100 ..... ..... ..... 00000 011100 @rs_rt_rd
|
||||
DMOD_G 011100 ..... ..... ..... 00000 011101 @rs_rt_rd
|
||||
MODU_G 011100 ..... ..... ..... 00000 011110 @rs_rt_rd
|
||||
DMODU_G 011100 ..... ..... ..... 00000 011111 @rs_rt_rd
|
271
target/mips/tcg/loong_translate.c
Normal file
271
target/mips/tcg/loong_translate.c
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* MIPS Loongson 64-bit translation routines
|
||||
*
|
||||
* Copyright (c) 2004-2005 Jocelyn Mayer
|
||||
* Copyright (c) 2006 Marius Groeger (FPU operations)
|
||||
* Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
|
||||
* Copyright (c) 2011 Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (c) 2021 Philippe Mathieu-Daudé
|
||||
*
|
||||
* This code is licensed under the GNU GPLv2 and later.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "translate.h"
|
||||
|
||||
/* Include the auto-generated decoder. */
|
||||
#include "decode-godson2.c.inc"
|
||||
#include "decode-loong-ext.c.inc"
|
||||
|
||||
/*
|
||||
* Word or double-word Fixed-point instructions.
|
||||
* ---------------------------------------------
|
||||
*
|
||||
* Fixed-point multiplies and divisions write only
|
||||
* one result into general-purpose registers.
|
||||
*/
|
||||
|
||||
static bool gen_lext_DIV_G(DisasContext *s, int rd, int rs, int rt,
|
||||
bool is_double)
|
||||
{
|
||||
TCGv t0, t1;
|
||||
TCGLabel *l1, *l2, *l3;
|
||||
|
||||
if (rd == 0) {
|
||||
/* Treat as NOP. */
|
||||
return true;
|
||||
}
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
l1 = gen_new_label();
|
||||
l2 = gen_new_label();
|
||||
l3 = gen_new_label();
|
||||
|
||||
gen_load_gpr(t0, rs);
|
||||
gen_load_gpr(t1, rt);
|
||||
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32s_tl(t0, t0);
|
||||
tcg_gen_ext32s_tl(t1, t1);
|
||||
}
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l1);
|
||||
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t0, is_double ? LLONG_MIN : INT_MIN, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
|
||||
tcg_gen_mov_tl(cpu_gpr[rd], t0);
|
||||
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
}
|
||||
gen_set_label(l3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_DIV_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_DIV_G(s, a->rd, a->rs, a->rt, false);
|
||||
}
|
||||
|
||||
static bool trans_DDIV_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_DIV_G(s, a->rd, a->rs, a->rt, true);
|
||||
}
|
||||
|
||||
static bool gen_lext_DIVU_G(DisasContext *s, int rd, int rs, int rt,
|
||||
bool is_double)
|
||||
{
|
||||
TCGv t0, t1;
|
||||
TCGLabel *l1, *l2;
|
||||
|
||||
if (rd == 0) {
|
||||
/* Treat as NOP. */
|
||||
return true;
|
||||
}
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
l1 = gen_new_label();
|
||||
l2 = gen_new_label();
|
||||
|
||||
gen_load_gpr(t0, rs);
|
||||
gen_load_gpr(t1, rt);
|
||||
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
}
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
}
|
||||
gen_set_label(l2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_DIVU_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_DIVU_G(s, a->rd, a->rs, a->rt, false);
|
||||
}
|
||||
|
||||
static bool trans_DDIVU_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_DIVU_G(s, a->rd, a->rs, a->rt, true);
|
||||
}
|
||||
|
||||
static bool gen_lext_MOD_G(DisasContext *s, int rd, int rs, int rt,
|
||||
bool is_double)
|
||||
{
|
||||
TCGv t0, t1;
|
||||
TCGLabel *l1, *l2, *l3;
|
||||
|
||||
if (rd == 0) {
|
||||
/* Treat as NOP. */
|
||||
return true;
|
||||
}
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
l1 = gen_new_label();
|
||||
l2 = gen_new_label();
|
||||
l3 = gen_new_label();
|
||||
|
||||
gen_load_gpr(t0, rs);
|
||||
gen_load_gpr(t1, rt);
|
||||
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
}
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t0, is_double ? LLONG_MIN : INT_MIN, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
}
|
||||
gen_set_label(l3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_MOD_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_MOD_G(s, a->rd, a->rs, a->rt, false);
|
||||
}
|
||||
|
||||
static bool trans_DMOD_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_MOD_G(s, a->rd, a->rs, a->rt, true);
|
||||
}
|
||||
|
||||
static bool gen_lext_MODU_G(DisasContext *s, int rd, int rs, int rt,
|
||||
bool is_double)
|
||||
{
|
||||
TCGv t0, t1;
|
||||
TCGLabel *l1, *l2;
|
||||
|
||||
if (rd == 0) {
|
||||
/* Treat as NOP. */
|
||||
return true;
|
||||
}
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
l1 = gen_new_label();
|
||||
l2 = gen_new_label();
|
||||
|
||||
gen_load_gpr(t0, rs);
|
||||
gen_load_gpr(t1, rt);
|
||||
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
}
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
}
|
||||
gen_set_label(l2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_MODU_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_MODU_G(s, a->rd, a->rs, a->rt, false);
|
||||
}
|
||||
|
||||
static bool trans_DMODU_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_MODU_G(s, a->rd, a->rs, a->rt, true);
|
||||
}
|
||||
|
||||
static bool gen_lext_MULT_G(DisasContext *s, int rd, int rs, int rt,
|
||||
bool is_double)
|
||||
{
|
||||
TCGv t0, t1;
|
||||
|
||||
if (rd == 0) {
|
||||
/* Treat as NOP. */
|
||||
return true;
|
||||
}
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
|
||||
gen_load_gpr(t0, rs);
|
||||
gen_load_gpr(t1, rt);
|
||||
|
||||
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
|
||||
if (!is_double) {
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_MULTu_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_MULT_G(s, a->rd, a->rs, a->rt, false);
|
||||
}
|
||||
|
||||
static bool trans_DMULTu_G(DisasContext *s, arg_muldiv *a)
|
||||
{
|
||||
return gen_lext_MULT_G(s, a->rd, a->rs, a->rt, true);
|
||||
}
|
||||
|
||||
bool decode_ext_loongson(DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
if (!decode_64bit_enabled(ctx)) {
|
||||
return false;
|
||||
}
|
||||
if ((ctx->insn_flags & INSN_LOONGSON2E) && decode_godson2(ctx, ctx->opcode)) {
|
||||
return true;
|
||||
}
|
||||
if ((ctx->insn_flags & ASE_LEXT) && decode_loong_ext(ctx, ctx->opcode)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -5,6 +5,8 @@ gen = [
|
||||
decodetree.process('vr54xx.decode', extra_args: '--decode=decode_ext_vr54xx'),
|
||||
decodetree.process('octeon.decode', extra_args: '--decode=decode_ext_octeon'),
|
||||
decodetree.process('lcsr.decode', extra_args: '--decode=decode_ase_lcsr'),
|
||||
decodetree.process('godson2.decode', extra_args: ['--static-decode=decode_godson2']),
|
||||
decodetree.process('loong-ext.decode', extra_args: ['--static-decode=decode_loong_ext']),
|
||||
]
|
||||
|
||||
mips_ss.add(gen)
|
||||
@ -28,6 +30,7 @@ mips_ss.add(when: 'TARGET_MIPS64', if_true: files(
|
||||
'tx79_translate.c',
|
||||
'octeon_translate.c',
|
||||
'lcsr_translate.c',
|
||||
'loong_translate.c',
|
||||
), if_false: files(
|
||||
'mxu_translate.c',
|
||||
))
|
||||
|
@ -2484,7 +2484,10 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||
mips32_op = OPC_BC1TANY4;
|
||||
do_cp1mips3d:
|
||||
check_cop1x(ctx);
|
||||
check_insn(ctx, ASE_MIPS3D);
|
||||
if (!ase_3d_available(env)) {
|
||||
gen_reserved_instruction(ctx);
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
do_cp1branch:
|
||||
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
||||
|
@ -327,19 +327,6 @@ enum {
|
||||
OPC_MUL = 0x02 | OPC_SPECIAL2,
|
||||
OPC_MSUB = 0x04 | OPC_SPECIAL2,
|
||||
OPC_MSUBU = 0x05 | OPC_SPECIAL2,
|
||||
/* Loongson 2F */
|
||||
OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
|
||||
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
|
||||
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
|
||||
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
|
||||
OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
|
||||
OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
|
||||
OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
|
||||
OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
|
||||
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
|
||||
OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
|
||||
OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
|
||||
OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
|
||||
/* Misc */
|
||||
OPC_CLZ = 0x20 | OPC_SPECIAL2,
|
||||
OPC_CLO = 0x21 | OPC_SPECIAL2,
|
||||
@ -368,20 +355,6 @@ enum {
|
||||
OPC_RDHWR = 0x3B | OPC_SPECIAL3,
|
||||
OPC_GINV = 0x3D | OPC_SPECIAL3,
|
||||
|
||||
/* Loongson 2E */
|
||||
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
|
||||
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
|
||||
OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
|
||||
OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
|
||||
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
|
||||
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
|
||||
OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
|
||||
OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
|
||||
OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
|
||||
OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
|
||||
OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
|
||||
OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
|
||||
|
||||
/* MIPS DSP Load */
|
||||
OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
|
||||
/* MIPS DSP Arithmetic */
|
||||
@ -389,16 +362,14 @@ enum {
|
||||
OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
|
||||
OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
|
||||
OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
|
||||
/* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
|
||||
/* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
|
||||
OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3,
|
||||
OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
|
||||
OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
|
||||
/* MIPS DSP GPR-Based Shift Sub-class */
|
||||
OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
|
||||
OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
|
||||
/* MIPS DSP Multiply Sub-class insns */
|
||||
/* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
|
||||
/* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
|
||||
OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3,
|
||||
OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
|
||||
OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
|
||||
/* DSP Bit/Manipulation Sub-class */
|
||||
@ -556,7 +527,6 @@ enum {
|
||||
OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
|
||||
};
|
||||
|
||||
#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
|
||||
#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
|
||||
enum {
|
||||
/* MIPS DSP Arithmetic Sub-class */
|
||||
@ -1645,13 +1615,18 @@ static inline void check_ps(DisasContext *ctx)
|
||||
check_cp1_64bitmode(ctx);
|
||||
}
|
||||
|
||||
bool decode_64bit_enabled(DisasContext *ctx)
|
||||
{
|
||||
return ctx->hflags & MIPS_HFLAG_64;
|
||||
}
|
||||
|
||||
/*
|
||||
* This code generates a "reserved instruction" exception if cpu is not
|
||||
* 64-bit or 64-bit instructions are not enabled.
|
||||
*/
|
||||
void check_mips_64(DisasContext *ctx)
|
||||
{
|
||||
if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
|
||||
if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) {
|
||||
gen_reserved_instruction(ctx);
|
||||
}
|
||||
}
|
||||
@ -3586,184 +3561,6 @@ static void gen_cl(DisasContext *ctx, uint32_t opc,
|
||||
}
|
||||
}
|
||||
|
||||
/* Godson integer instructions */
|
||||
static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
|
||||
int rd, int rs, int rt)
|
||||
{
|
||||
TCGv t0, t1;
|
||||
|
||||
if (rd == 0) {
|
||||
/* Treat as NOP. */
|
||||
return;
|
||||
}
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
gen_load_gpr(t0, rs);
|
||||
gen_load_gpr(t1, rt);
|
||||
|
||||
switch (opc) {
|
||||
case OPC_MULT_G_2E:
|
||||
case OPC_MULT_G_2F:
|
||||
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
break;
|
||||
case OPC_MULTU_G_2E:
|
||||
case OPC_MULTU_G_2F:
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
break;
|
||||
case OPC_DIV_G_2E:
|
||||
case OPC_DIV_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
TCGLabel *l3 = gen_new_label();
|
||||
tcg_gen_ext32s_tl(t0, t0);
|
||||
tcg_gen_ext32s_tl(t1, t1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
|
||||
tcg_gen_mov_tl(cpu_gpr[rd], t0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
gen_set_label(l3);
|
||||
}
|
||||
break;
|
||||
case OPC_DIVU_G_2E:
|
||||
case OPC_DIVU_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
gen_set_label(l2);
|
||||
}
|
||||
break;
|
||||
case OPC_MOD_G_2E:
|
||||
case OPC_MOD_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
TCGLabel *l3 = gen_new_label();
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
gen_set_label(l3);
|
||||
}
|
||||
break;
|
||||
case OPC_MODU_G_2E:
|
||||
case OPC_MODU_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_ext32u_tl(t0, t0);
|
||||
tcg_gen_ext32u_tl(t1, t1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
|
||||
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
|
||||
gen_set_label(l2);
|
||||
}
|
||||
break;
|
||||
#if defined(TARGET_MIPS64)
|
||||
case OPC_DMULT_G_2E:
|
||||
case OPC_DMULT_G_2F:
|
||||
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
|
||||
break;
|
||||
case OPC_DMULTU_G_2E:
|
||||
case OPC_DMULTU_G_2F:
|
||||
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
|
||||
break;
|
||||
case OPC_DDIV_G_2E:
|
||||
case OPC_DDIV_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
TCGLabel *l3 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
|
||||
tcg_gen_mov_tl(cpu_gpr[rd], t0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
|
||||
gen_set_label(l3);
|
||||
}
|
||||
break;
|
||||
case OPC_DDIVU_G_2E:
|
||||
case OPC_DDIVU_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
|
||||
gen_set_label(l2);
|
||||
}
|
||||
break;
|
||||
case OPC_DMOD_G_2E:
|
||||
case OPC_DMOD_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
TCGLabel *l3 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
|
||||
gen_set_label(l3);
|
||||
}
|
||||
break;
|
||||
case OPC_DMODU_G_2E:
|
||||
case OPC_DMODU_G_2F:
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
tcg_gen_movi_tl(cpu_gpr[rd], 0);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
|
||||
gen_set_label(l2);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Loongson multimedia instructions */
|
||||
static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
|
||||
{
|
||||
@ -5315,17 +5112,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Index";
|
||||
break;
|
||||
case CP0_REG00__MVPCONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_mvpcontrol(arg, tcg_env);
|
||||
register_name = "MVPControl";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_mvpconf0(arg, tcg_env);
|
||||
register_name = "MVPConf0";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_mvpconf1(arg, tcg_env);
|
||||
register_name = "MVPConf1";
|
||||
break;
|
||||
@ -5346,37 +5143,37 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Random";
|
||||
break;
|
||||
case CP0_REG01__VPECONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
|
||||
register_name = "VPEControl";
|
||||
break;
|
||||
case CP0_REG01__VPECONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
|
||||
register_name = "VPEConf0";
|
||||
break;
|
||||
case CP0_REG01__VPECONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
|
||||
register_name = "VPEConf1";
|
||||
break;
|
||||
case CP0_REG01__YQMASK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
|
||||
register_name = "YQMask";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
|
||||
register_name = "VPESchedule";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
|
||||
register_name = "VPEScheFBack";
|
||||
break;
|
||||
case CP0_REG01__VPEOPT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
|
||||
register_name = "VPEOpt";
|
||||
break;
|
||||
@ -5403,37 +5200,37 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "EntryLo0";
|
||||
break;
|
||||
case CP0_REG02__TCSTATUS:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcstatus(arg, tcg_env);
|
||||
register_name = "TCStatus";
|
||||
break;
|
||||
case CP0_REG02__TCBIND:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcbind(arg, tcg_env);
|
||||
register_name = "TCBind";
|
||||
break;
|
||||
case CP0_REG02__TCRESTART:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcrestart(arg, tcg_env);
|
||||
register_name = "TCRestart";
|
||||
break;
|
||||
case CP0_REG02__TCHALT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tchalt(arg, tcg_env);
|
||||
register_name = "TCHalt";
|
||||
break;
|
||||
case CP0_REG02__TCCONTEXT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tccontext(arg, tcg_env);
|
||||
register_name = "TCContext";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcschedule(arg, tcg_env);
|
||||
register_name = "TCSchedule";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcschefback(arg, tcg_env);
|
||||
register_name = "TCScheFBack";
|
||||
break;
|
||||
@ -6072,17 +5869,17 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Index";
|
||||
break;
|
||||
case CP0_REG00__MVPCONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_mvpcontrol(tcg_env, arg);
|
||||
register_name = "MVPControl";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
/* ignored */
|
||||
register_name = "MVPConf0";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
/* ignored */
|
||||
register_name = "MVPConf1";
|
||||
break;
|
||||
@ -6102,39 +5899,39 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Random";
|
||||
break;
|
||||
case CP0_REG01__VPECONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpecontrol(tcg_env, arg);
|
||||
register_name = "VPEControl";
|
||||
break;
|
||||
case CP0_REG01__VPECONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpeconf0(tcg_env, arg);
|
||||
register_name = "VPEConf0";
|
||||
break;
|
||||
case CP0_REG01__VPECONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpeconf1(tcg_env, arg);
|
||||
register_name = "VPEConf1";
|
||||
break;
|
||||
case CP0_REG01__YQMASK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_yqmask(tcg_env, arg);
|
||||
register_name = "YQMask";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_st_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_VPESchedule));
|
||||
register_name = "VPESchedule";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_st_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_VPEScheFBack));
|
||||
register_name = "VPEScheFBack";
|
||||
break;
|
||||
case CP0_REG01__VPEOPT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpeopt(tcg_env, arg);
|
||||
register_name = "VPEOpt";
|
||||
break;
|
||||
@ -6149,37 +5946,37 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "EntryLo0";
|
||||
break;
|
||||
case CP0_REG02__TCSTATUS:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcstatus(tcg_env, arg);
|
||||
register_name = "TCStatus";
|
||||
break;
|
||||
case CP0_REG02__TCBIND:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcbind(tcg_env, arg);
|
||||
register_name = "TCBind";
|
||||
break;
|
||||
case CP0_REG02__TCRESTART:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcrestart(tcg_env, arg);
|
||||
register_name = "TCRestart";
|
||||
break;
|
||||
case CP0_REG02__TCHALT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tchalt(tcg_env, arg);
|
||||
register_name = "TCHalt";
|
||||
break;
|
||||
case CP0_REG02__TCCONTEXT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tccontext(tcg_env, arg);
|
||||
register_name = "TCContext";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcschedule(tcg_env, arg);
|
||||
register_name = "TCSchedule";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcschefback(tcg_env, arg);
|
||||
register_name = "TCScheFBack";
|
||||
break;
|
||||
@ -6822,17 +6619,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Index";
|
||||
break;
|
||||
case CP0_REG00__MVPCONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_mvpcontrol(arg, tcg_env);
|
||||
register_name = "MVPControl";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_mvpconf0(arg, tcg_env);
|
||||
register_name = "MVPConf0";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_mvpconf1(arg, tcg_env);
|
||||
register_name = "MVPConf1";
|
||||
break;
|
||||
@ -6853,40 +6650,40 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Random";
|
||||
break;
|
||||
case CP0_REG01__VPECONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
|
||||
register_name = "VPEControl";
|
||||
break;
|
||||
case CP0_REG01__VPECONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
|
||||
register_name = "VPEConf0";
|
||||
break;
|
||||
case CP0_REG01__VPECONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
|
||||
register_name = "VPEConf1";
|
||||
break;
|
||||
case CP0_REG01__YQMASK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_ld_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_YQMask));
|
||||
register_name = "YQMask";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_ld_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_VPESchedule));
|
||||
register_name = "VPESchedule";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_ld_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_VPEScheFBack));
|
||||
register_name = "VPEScheFBack";
|
||||
break;
|
||||
case CP0_REG01__VPEOPT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
|
||||
register_name = "VPEOpt";
|
||||
break;
|
||||
@ -6902,37 +6699,37 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "EntryLo0";
|
||||
break;
|
||||
case CP0_REG02__TCSTATUS:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcstatus(arg, tcg_env);
|
||||
register_name = "TCStatus";
|
||||
break;
|
||||
case CP0_REG02__TCBIND:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mfc0_tcbind(arg, tcg_env);
|
||||
register_name = "TCBind";
|
||||
break;
|
||||
case CP0_REG02__TCRESTART:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_dmfc0_tcrestart(arg, tcg_env);
|
||||
register_name = "TCRestart";
|
||||
break;
|
||||
case CP0_REG02__TCHALT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_dmfc0_tchalt(arg, tcg_env);
|
||||
register_name = "TCHalt";
|
||||
break;
|
||||
case CP0_REG02__TCCONTEXT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_dmfc0_tccontext(arg, tcg_env);
|
||||
register_name = "TCContext";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_dmfc0_tcschedule(arg, tcg_env);
|
||||
register_name = "TCSchedule";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_dmfc0_tcschefback(arg, tcg_env);
|
||||
register_name = "TCScheFBack";
|
||||
break;
|
||||
@ -7539,17 +7336,17 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Index";
|
||||
break;
|
||||
case CP0_REG00__MVPCONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_mvpcontrol(tcg_env, arg);
|
||||
register_name = "MVPControl";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
/* ignored */
|
||||
register_name = "MVPConf0";
|
||||
break;
|
||||
case CP0_REG00__MVPCONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
/* ignored */
|
||||
register_name = "MVPConf1";
|
||||
break;
|
||||
@ -7569,39 +7366,39 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "Random";
|
||||
break;
|
||||
case CP0_REG01__VPECONTROL:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpecontrol(tcg_env, arg);
|
||||
register_name = "VPEControl";
|
||||
break;
|
||||
case CP0_REG01__VPECONF0:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpeconf0(tcg_env, arg);
|
||||
register_name = "VPEConf0";
|
||||
break;
|
||||
case CP0_REG01__VPECONF1:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpeconf1(tcg_env, arg);
|
||||
register_name = "VPEConf1";
|
||||
break;
|
||||
case CP0_REG01__YQMASK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_yqmask(tcg_env, arg);
|
||||
register_name = "YQMask";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_st_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_VPESchedule));
|
||||
register_name = "VPESchedule";
|
||||
break;
|
||||
case CP0_REG01__VPESCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
tcg_gen_st_tl(arg, tcg_env,
|
||||
offsetof(CPUMIPSState, CP0_VPEScheFBack));
|
||||
register_name = "VPEScheFBack";
|
||||
break;
|
||||
case CP0_REG01__VPEOPT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_vpeopt(tcg_env, arg);
|
||||
register_name = "VPEOpt";
|
||||
break;
|
||||
@ -7616,37 +7413,37 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||
register_name = "EntryLo0";
|
||||
break;
|
||||
case CP0_REG02__TCSTATUS:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcstatus(tcg_env, arg);
|
||||
register_name = "TCStatus";
|
||||
break;
|
||||
case CP0_REG02__TCBIND:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcbind(tcg_env, arg);
|
||||
register_name = "TCBind";
|
||||
break;
|
||||
case CP0_REG02__TCRESTART:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcrestart(tcg_env, arg);
|
||||
register_name = "TCRestart";
|
||||
break;
|
||||
case CP0_REG02__TCHALT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tchalt(tcg_env, arg);
|
||||
register_name = "TCHalt";
|
||||
break;
|
||||
case CP0_REG02__TCCONTEXT:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tccontext(tcg_env, arg);
|
||||
register_name = "TCContext";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEDULE:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcschedule(tcg_env, arg);
|
||||
register_name = "TCSchedule";
|
||||
break;
|
||||
case CP0_REG02__TCSCHEFBACK:
|
||||
CP0_CHECK(ctx->insn_flags & ASE_MT);
|
||||
CP0_CHECK(disas_mt_available(ctx));
|
||||
gen_helper_mtc0_tcschefback(tcg_env, arg);
|
||||
register_name = "TCScheFBack";
|
||||
break;
|
||||
@ -11584,8 +11381,7 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
|
||||
gen_load_gpr(v2_t, v2);
|
||||
|
||||
switch (op1) {
|
||||
/* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
|
||||
case OPC_MULT_G_2E:
|
||||
case OPC_ADDUH_QB_DSP:
|
||||
check_dsp_r2(ctx);
|
||||
switch (op2) {
|
||||
case OPC_ADDUH_QB:
|
||||
@ -12268,11 +12064,7 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
|
||||
gen_load_gpr(v2_t, v2);
|
||||
|
||||
switch (op1) {
|
||||
/*
|
||||
* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
|
||||
* the same mask and op1.
|
||||
*/
|
||||
case OPC_MULT_G_2E:
|
||||
case OPC_MUL_PH_DSP:
|
||||
check_dsp_r2(ctx);
|
||||
switch (op2) {
|
||||
case OPC_MUL_PH:
|
||||
@ -13624,15 +13416,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
case OPC_MUL:
|
||||
gen_arith(ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
case OPC_DIV_G_2F:
|
||||
case OPC_DIVU_G_2F:
|
||||
case OPC_MULT_G_2F:
|
||||
case OPC_MULTU_G_2F:
|
||||
case OPC_MOD_G_2F:
|
||||
case OPC_MODU_G_2F:
|
||||
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
|
||||
gen_loongson_integer(ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
case OPC_CLO:
|
||||
case OPC_CLZ:
|
||||
check_insn(ctx, ISA_MIPS_R1);
|
||||
@ -13657,15 +13440,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
check_mips_64(ctx);
|
||||
gen_cl(ctx, op1, rd, rs);
|
||||
break;
|
||||
case OPC_DMULT_G_2F:
|
||||
case OPC_DMULTU_G_2F:
|
||||
case OPC_DDIV_G_2F:
|
||||
case OPC_DDIVU_G_2F:
|
||||
case OPC_DMOD_G_2F:
|
||||
case OPC_DMODU_G_2F:
|
||||
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
|
||||
gen_loongson_integer(ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
#endif
|
||||
default: /* Invalid */
|
||||
MIPS_INVAL("special2_legacy");
|
||||
@ -13798,17 +13572,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
|
||||
op1 = MASK_SPECIAL3(ctx->opcode);
|
||||
switch (op1) {
|
||||
case OPC_DIV_G_2E:
|
||||
case OPC_DIVU_G_2E:
|
||||
case OPC_MOD_G_2E:
|
||||
case OPC_MODU_G_2E:
|
||||
case OPC_MULT_G_2E:
|
||||
case OPC_MULTU_G_2E:
|
||||
case OPC_MUL_PH_DSP:
|
||||
/*
|
||||
* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
|
||||
* OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
|
||||
* the same mask and op1.
|
||||
*/
|
||||
if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
|
||||
if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) {
|
||||
op2 = MASK_ADDUH_QB(ctx->opcode);
|
||||
switch (op2) {
|
||||
case OPC_ADDUH_QB:
|
||||
@ -13836,8 +13605,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
gen_reserved_instruction(ctx);
|
||||
break;
|
||||
}
|
||||
} else if (ctx->insn_flags & INSN_LOONGSON2E) {
|
||||
gen_loongson_integer(ctx, op1, rd, rs, rt);
|
||||
} else {
|
||||
gen_reserved_instruction(ctx);
|
||||
}
|
||||
@ -14066,15 +13833,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
}
|
||||
break;
|
||||
#if defined(TARGET_MIPS64)
|
||||
case OPC_DDIV_G_2E:
|
||||
case OPC_DDIVU_G_2E:
|
||||
case OPC_DMULT_G_2E:
|
||||
case OPC_DMULTU_G_2E:
|
||||
case OPC_DMOD_G_2E:
|
||||
case OPC_DMODU_G_2E:
|
||||
check_insn(ctx, INSN_LOONGSON2E);
|
||||
gen_loongson_integer(ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
case OPC_ABSQ_S_QH_DSP:
|
||||
op2 = MASK_ABSQ_S_QH(ctx->opcode);
|
||||
switch (op2) {
|
||||
@ -14952,7 +14710,9 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
} else {
|
||||
/* OPC_BC1ANY2 */
|
||||
check_cop1x(ctx);
|
||||
check_insn(ctx, ASE_MIPS3D);
|
||||
if (!ase_3d_available(env)) {
|
||||
return false;
|
||||
}
|
||||
gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
|
||||
(rt >> 2) & 0x7, imm << 2);
|
||||
}
|
||||
@ -14967,7 +14727,9 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
check_cp1_enabled(ctx);
|
||||
check_insn_opc_removed(ctx, ISA_MIPS_R6);
|
||||
check_cop1x(ctx);
|
||||
check_insn(ctx, ASE_MIPS3D);
|
||||
if (!ase_3d_available(env)) {
|
||||
return false;
|
||||
}
|
||||
/* fall through */
|
||||
case OPC_BC1:
|
||||
check_cp1_enabled(ctx);
|
||||
@ -15267,6 +15029,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||
if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
|
||||
return;
|
||||
}
|
||||
if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) {
|
||||
return;
|
||||
}
|
||||
#if defined(TARGET_MIPS64)
|
||||
if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
|
||||
return;
|
||||
|
@ -217,10 +217,13 @@ void msa_translate_init(void);
|
||||
void mxu_translate_init(void);
|
||||
bool decode_ase_mxu(DisasContext *ctx, uint32_t insn);
|
||||
|
||||
bool decode_64bit_enabled(DisasContext *ctx);
|
||||
|
||||
/* decodetree generated */
|
||||
bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
|
||||
bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
|
||||
bool decode_ext_txx9(DisasContext *ctx, uint32_t insn);
|
||||
bool decode_ext_loongson(DisasContext *ctx, uint32_t insn);
|
||||
#if defined(TARGET_MIPS64)
|
||||
bool decode_ase_lcsr(DisasContext *ctx, uint32_t insn);
|
||||
bool decode_ext_tx79(DisasContext *ctx, uint32_t insn);
|
||||
@ -228,6 +231,11 @@ bool decode_ext_octeon(DisasContext *ctx, uint32_t insn);
|
||||
#endif
|
||||
bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn);
|
||||
|
||||
static inline bool disas_mt_available(DisasContext *ctx)
|
||||
{
|
||||
return ctx->CP0_Config3 & (1 << CP0C3_MT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers for implementing sets of trans_* functions.
|
||||
* Defer the implementation of NAME to FUNC, with optional extra arguments.
|
||||
|
Loading…
Reference in New Issue
Block a user