mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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,
|
||||
},
|
||||
{
|
||||
|
||||
+6
-1
@@ -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),
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)) {
|
||||
|
||||
+90
-325
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user