summaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-02-21 19:52:58 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-02-21 19:52:58 +0000
commit00d8ba9e0d62ea1c7459c25aeabf9c8bb7659462 (patch)
tree188c7a650d48c12a9cf244575cdd13700471b584 /target
parent4115aec9af2a3de5fa89a0b1daa12debcd7741ff (diff)
parentcc2b4550115baf77d556341f17eb464d18953cee (diff)
downloadqemu-00d8ba9e0d62ea1c7459c25aeabf9c8bb7659462.zip
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/mips-20210221' into staging
MIPS patches queue - Drop redundant struct MemmapEntry (Bin) - Fix for Coverity CID 1438965 and 1438967 (Jiaxun) - Add MIPS bootloader API (Jiaxun) - Use MIPS bootloader API on fuloong2e and boston machines (Jiaxun) - Add PMON test for Loongson-3A1000 CPU (Jiaxun) - Convert to translator API (Philippe) - MMU cleanups (Philippe) - Promote 128-bit multimedia registers as global ones (Philippe) - Various cleanups/fixes on the VT82C686B southbridge (Zoltan) # gpg: Signature made Sun 21 Feb 2021 18:43:57 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 * remotes/philmd-gitlab/tags/mips-20210221: (43 commits) vt82c686: Fix superio_cfg_{read,write}() functions vt82c686: Log superio_cfg unimplemented accesses vt82c686: Simplify by returning earlier vt82c686: Reduce indentation by returning early vt82c686: Remove index field of SuperIOConfig vt82c686: Move creation of ISA devices to the ISA bridge vt82c686: Simplify vt82c686b_realize() vt82c686: Make vt82c686b-pm an abstract base class and add vt8231-pm based on it vt82c686: Set user_creatable=false for VT82C686B_PM vt82c686: Fix up power management io base and config vt82c686: Correctly reset all registers to default values on reset vt82c686: Correct vt82c686-pm I/O size vt82c686: Make vt82c686-pm an I/O tracing region vt82c686: Fix SMBus IO base and configuration registers vt82c686: Reorganise code vt82c686: Move superio memory region to SuperIOConfig struct target/mips: Use GPR move functions in gen_HILO1_tx79() target/mips: Introduce gen_load_gpr_hi() / gen_store_gpr_hi() helpers target/mips: Rename 128-bit upper halve GPR registers target/mips: Promote 128-bit multimedia registers as global ones ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/mips/cpu.h26
-rw-r--r--target/mips/internal.h10
-rw-r--r--target/mips/msa_helper.c1
-rw-r--r--target/mips/op_helper.c9
-rw-r--r--target/mips/tlb_helper.c80
-rw-r--r--target/mips/translate.c111
-rw-r--r--target/mips/translate.h8
7 files changed, 123 insertions, 122 deletions
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index b9e227a30e..075c24abda 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -460,6 +460,13 @@ typedef struct mips_def_t mips_def_t;
typedef struct TCState TCState;
struct TCState {
target_ulong gpr[32];
+#if defined(TARGET_MIPS64)
+ /*
+ * For CPUs using 128-bit GPR registers, we put the lower halves in gpr[])
+ * and the upper halves in gpr_hi[].
+ */
+ uint64_t gpr_hi[32];
+#endif /* TARGET_MIPS64 */
target_ulong PC;
target_ulong HI[MIPS_DSP_ACC];
target_ulong LO[MIPS_DSP_ACC];
@@ -505,9 +512,6 @@ struct TCState {
float_status msa_fp_status;
- /* Upper 64-bit MMRs (multimedia registers); the lower 64-bit are GPRs */
- uint64_t mmr[32];
-
#define NUMBER_OF_MXU_REGISTERS 16
target_ulong mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
target_ulong mxu_cr;
@@ -1220,22 +1224,6 @@ typedef MIPSCPU ArchCPU;
#include "exec/cpu-all.h"
-/*
- * Memory access type :
- * may be needed for precise access rights control and precise exceptions.
- */
-enum {
- /* 1 bit to define user level / supervisor access */
- ACCESS_USER = 0x00,
- ACCESS_SUPER = 0x01,
- /* 1 bit to indicate direction */
- ACCESS_STORE = 0x02,
- /* Type of instruction that generated the access */
- ACCESS_CODE = 0x10, /* Code fetch access */
- ACCESS_INT = 0x20, /* Integer load/store access */
- ACCESS_FLOAT = 0x30, /* floating point load/store access */
-};
-
/* Exceptions */
enum {
EXCP_NONE = -1,
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 5dd17ff733..99264b8bf6 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -111,7 +111,7 @@ struct CPUMIPSTLBContext {
uint32_t nb_tlb;
uint32_t tlb_in_use;
int (*map_address)(struct CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type);
+ target_ulong address, MMUAccessType access_type);
void (*helper_tlbwi)(struct CPUMIPSState *env);
void (*helper_tlbwr)(struct CPUMIPSState *env);
void (*helper_tlbp)(struct CPUMIPSState *env);
@@ -126,11 +126,11 @@ struct CPUMIPSTLBContext {
};
int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type);
+ target_ulong address, MMUAccessType access_type);
int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type);
+ target_ulong address, MMUAccessType access_type);
int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type);
+ target_ulong address, MMUAccessType access_type);
void r4k_helper_tlbwi(CPUMIPSState *env);
void r4k_helper_tlbwr(CPUMIPSState *env);
void r4k_helper_tlbp(CPUMIPSState *env);
@@ -146,7 +146,7 @@ void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
int mmu_idx, MemTxAttrs attrs,
MemTxResult response, uintptr_t retaddr);
hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
- int rw);
+ MMUAccessType access_type);
#endif
#define cpu_signal_handler cpu_mips_signal_handler
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 1298a1917c..4caefe29ad 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "internal.h"
+#include "tcg/tcg.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "exec/memop.h"
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 89c7d4556a..b80e8f7540 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -288,13 +288,14 @@ target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx,
#ifndef CONFIG_USER_ONLY
static inline hwaddr do_translate_address(CPUMIPSState *env,
- target_ulong address,
- int rw, uintptr_t retaddr)
+ target_ulong address,
+ MMUAccessType access_type,
+ uintptr_t retaddr)
{
hwaddr paddr;
CPUState *cs = env_cpu(env);
- paddr = cpu_mips_translate_address(env, address, rw);
+ paddr = cpu_mips_translate_address(env, address, access_type);
if (paddr == -1LL) {
cpu_loop_exit_restore(cs, retaddr);
@@ -312,7 +313,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \
} \
do_raise_exception(env, EXCP_AdEL, GETPC()); \
} \
- env->CP0_LLAddr = do_translate_address(env, arg, 0, GETPC()); \
+ env->CP0_LLAddr = do_translate_address(env, arg, MMU_DATA_LOAD, GETPC()); \
env->lladdr = arg; \
env->llval = do_cast cpu_##insn##_mmuidx_ra(env, arg, mem_idx, GETPC()); \
return env->llval; \
diff --git a/target/mips/tlb_helper.c b/target/mips/tlb_helper.c
index 082c17928d..8d3ea49780 100644
--- a/target/mips/tlb_helper.c
+++ b/target/mips/tlb_helper.c
@@ -39,7 +39,7 @@ enum {
/* no MMU emulation */
int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type)
+ target_ulong address, MMUAccessType access_type)
{
*physical = address;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -48,7 +48,7 @@ int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
/* fixed mapping MMU emulation */
int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type)
+ target_ulong address, MMUAccessType access_type)
{
if (address <= (int32_t)0x7FFFFFFFUL) {
if (!(env->CP0_Status & (1 << CP0St_ERL))) {
@@ -68,7 +68,7 @@ int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
/* MIPS32/MIPS64 R4000-style MMU emulation */
int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, int rw, int access_type)
+ target_ulong address, MMUAccessType access_type)
{
uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
uint32_t MMID = env->CP0_MemoryMapID;
@@ -97,13 +97,13 @@ int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
if (!(n ? tlb->V1 : tlb->V0)) {
return TLBRET_INVALID;
}
- if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) {
+ if (access_type == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) {
return TLBRET_XI;
}
- if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) {
+ if (access_type == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) {
return TLBRET_RI;
}
- if (rw != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) {
+ if (access_type != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) {
*physical = tlb->PFN[n] | (address & (mask >> 1));
*prot = PAGE_READ;
if (n ? tlb->D1 : tlb->D0) {
@@ -222,7 +222,7 @@ static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
int *prot, target_ulong real_address,
- int rw, int access_type, int mmu_idx,
+ MMUAccessType access_type, int mmu_idx,
unsigned int am, bool eu,
target_ulong segmask,
hwaddr physical_base)
@@ -234,7 +234,7 @@ static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
return mapped;
} else if (mapped) {
/* The segment is TLB mapped */
- return env->tlb->map_address(env, physical, prot, real_address, rw,
+ return env->tlb->map_address(env, physical, prot, real_address,
access_type);
} else {
/* The segment is unmapped */
@@ -246,21 +246,21 @@ static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical,
int *prot, target_ulong real_address,
- int rw, int access_type, int mmu_idx,
+ MMUAccessType access_type, int mmu_idx,
uint16_t segctl, target_ulong segmask)
{
unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM;
bool eu = (segctl >> CP0SC_EU) & 1;
hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20;
- return get_seg_physical_address(env, physical, prot, real_address, rw,
+ return get_seg_physical_address(env, physical, prot, real_address,
access_type, mmu_idx, am, eu, segmask,
pa & ~(hwaddr)segmask);
}
static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
int *prot, target_ulong real_address,
- int rw, int access_type, int mmu_idx)
+ MMUAccessType access_type, int mmu_idx)
{
/* User mode can only access useg/xuseg */
#if defined(TARGET_MIPS64)
@@ -307,14 +307,14 @@ static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
segctl = env->CP0_SegCtl2 >> 16;
}
ret = get_segctl_physical_address(env, physical, prot,
- real_address, rw, access_type,
+ real_address, access_type,
mmu_idx, segctl, 0x3FFFFFFF);
#if defined(TARGET_MIPS64)
} else if (address < 0x4000000000000000ULL) {
/* xuseg */
if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
ret = env->tlb->map_address(env, physical, prot,
- real_address, rw, access_type);
+ real_address, access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -323,7 +323,7 @@ static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
if ((supervisor_mode || kernel_mode) &&
SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
ret = env->tlb->map_address(env, physical, prot,
- real_address, rw, access_type);
+ real_address, access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -350,7 +350,7 @@ static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
/* Does CP0_Status.KX/SX/UX permit the access mode (am) */
if (env->CP0_Status & am_ksux[am]) {
ret = get_seg_physical_address(env, physical, prot,
- real_address, rw, access_type,
+ real_address, access_type,
mmu_idx, am, false, env->PAMask,
0);
} else {
@@ -364,24 +364,24 @@ static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
if (kernel_mode && KX &&
address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
ret = env->tlb->map_address(env, physical, prot,
- real_address, rw, access_type);
+ real_address, access_type);
} else {
ret = TLBRET_BADADDR;
}
#endif
} else if (address < KSEG1_BASE) {
/* kseg0 */
- ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
access_type, mmu_idx,
env->CP0_SegCtl1 >> 16, 0x1FFFFFFF);
} else if (address < KSEG2_BASE) {
/* kseg1 */
- ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
access_type, mmu_idx,
env->CP0_SegCtl1, 0x1FFFFFFF);
} else if (address < KSEG3_BASE) {
/* sseg (kseg2) */
- ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
access_type, mmu_idx,
env->CP0_SegCtl0 >> 16, 0x1FFFFFFF);
} else {
@@ -389,7 +389,7 @@ static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
* kseg3
* XXX: debug segment is not emulated
*/
- ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
access_type, mmu_idx,
env->CP0_SegCtl0, 0x1FFFFFFF);
}
@@ -406,12 +406,12 @@ void cpu_mips_tlb_flush(CPUMIPSState *env)
#endif /* !CONFIG_USER_ONLY */
static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
- int rw, int tlb_error)
+ MMUAccessType access_type, int tlb_error)
{
CPUState *cs = env_cpu(env);
int exception = 0, error_code = 0;
- if (rw == MMU_INST_FETCH) {
+ if (access_type == MMU_INST_FETCH) {
error_code |= EXCP_INST_NOTAVAIL;
}
@@ -420,7 +420,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
case TLBRET_BADADDR:
/* Reference to kernel address from user mode or supervisor mode */
/* Reference to supervisor address from user mode */
- if (rw == MMU_DATA_STORE) {
+ if (access_type == MMU_DATA_STORE) {
exception = EXCP_AdES;
} else {
exception = EXCP_AdEL;
@@ -428,7 +428,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
break;
case TLBRET_NOMATCH:
/* No TLB match for a mapped address */
- if (rw == MMU_DATA_STORE) {
+ if (access_type == MMU_DATA_STORE) {
exception = EXCP_TLBS;
} else {
exception = EXCP_TLBL;
@@ -437,7 +437,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
break;
case TLBRET_INVALID:
/* TLB match with no valid bit */
- if (rw == MMU_DATA_STORE) {
+ if (access_type == MMU_DATA_STORE) {
exception = EXCP_TLBS;
} else {
exception = EXCP_TLBL;
@@ -493,7 +493,7 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
hwaddr phys_addr;
int prot;
- if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT,
+ if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
cpu_mmu_index(env, false)) != 0) {
return -1;
}
@@ -571,7 +571,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
uint64_t w = 0;
if (get_physical_address(env, &paddr, &prot, *vaddr, MMU_DATA_LOAD,
- ACCESS_INT, cpu_mmu_index(env, false)) !=
+ cpu_mmu_index(env, false)) !=
TLBRET_MATCH) {
/* wrong base address */
return 0;
@@ -599,7 +599,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
*pw_entrylo0 = entry;
}
if (get_physical_address(env, &paddr, &prot, vaddr2, MMU_DATA_LOAD,
- ACCESS_INT, cpu_mmu_index(env, false)) !=
+ cpu_mmu_index(env, false)) !=
TLBRET_MATCH) {
return 0;
}
@@ -622,8 +622,8 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
}
}
-static bool page_table_walk_refill(CPUMIPSState *env, vaddr address, int rw,
- int mmu_idx)
+static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
+ int mmu_idx)
{
int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F;
int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F;
@@ -753,7 +753,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address, int rw,
/* Leaf Level Page Table - First half of PTE pair */
vaddr |= ptoffset0;
if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
- ACCESS_INT, cpu_mmu_index(env, false)) !=
+ cpu_mmu_index(env, false)) !=
TLBRET_MATCH) {
return false;
}
@@ -766,7 +766,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address, int rw,
/* Leaf Level Page Table - Second half of PTE pair */
vaddr |= ptoffset1;
if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
- ACCESS_INT, cpu_mmu_index(env, false)) !=
+ cpu_mmu_index(env, false)) !=
TLBRET_MATCH) {
return false;
}
@@ -844,16 +844,14 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
#if !defined(CONFIG_USER_ONLY)
hwaddr physical;
int prot;
- int mips_access_type;
#endif
int ret = TLBRET_BADADDR;
/* data access */
#if !defined(CONFIG_USER_ONLY)
/* XXX: put correct access by using cpu_restore_state() correctly */
- mips_access_type = ACCESS_INT;
ret = get_physical_address(env, &physical, &prot, address,
- access_type, mips_access_type, mmu_idx);
+ access_type, mmu_idx);
switch (ret) {
case TLBRET_MATCH:
qemu_log_mask(CPU_LOG_MMU,
@@ -881,11 +879,11 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
int mode = (env->hflags & MIPS_HFLAG_KSU);
bool ret_walker;
env->hflags &= ~MIPS_HFLAG_KSU;
- ret_walker = page_table_walk_refill(env, address, access_type, mmu_idx);
+ ret_walker = page_table_walk_refill(env, address, mmu_idx);
env->hflags |= mode;
if (ret_walker) {
ret = get_physical_address(env, &physical, &prot, address,
- access_type, mips_access_type, mmu_idx);
+ access_type, mmu_idx);
if (ret == TLBRET_MATCH) {
tlb_set_page(cs, address & TARGET_PAGE_MASK,
physical & TARGET_PAGE_MASK, prot,
@@ -906,19 +904,17 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
#ifndef CONFIG_USER_ONLY
hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
- int rw)
+ MMUAccessType access_type)
{
hwaddr physical;
int prot;
- int access_type;
int ret = 0;
/* data access */
- access_type = ACCESS_INT;
- ret = get_physical_address(env, &physical, &prot, address, rw, access_type,
+ ret = get_physical_address(env, &physical, &prot, address, access_type,
cpu_mmu_index(env, false));
if (ret != TLBRET_MATCH) {
- raise_mmu_exception(env, address, rw, ret);
+ raise_mmu_exception(env, address, access_type, ret);
return -1LL;
} else {
return physical;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index a5cf1742a8..70891c37cd 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -26,7 +26,7 @@
#include "cpu.h"
#include "internal.h"
#include "tcg/tcg-op.h"
-#include "exec/cpu_ldst.h"
+#include "exec/translator.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "hw/semihosting/semihost.h"
@@ -2179,7 +2179,12 @@ enum {
/* global register indices */
TCGv cpu_gpr[32], cpu_PC;
-static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
+/*
+ * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
+ * and the upper halves in cpu_gpr_hi[].
+ */
+TCGv_i64 cpu_gpr_hi[32];
+TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
static TCGv cpu_dspctrl, btarget;
TCGv bcond;
static TCGv cpu_lladdr, cpu_llval;
@@ -2187,11 +2192,6 @@ static TCGv_i32 hflags;
TCGv_i32 fpu_fcr0, fpu_fcr31;
TCGv_i64 fpu_f64[32];
-#if defined(TARGET_MIPS64)
-/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
-static TCGv_i64 cpu_mmr[32];
-#endif
-
#if !defined(TARGET_MIPS64)
/* MXU registers */
static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
@@ -2291,6 +2291,24 @@ void gen_store_gpr(TCGv t, int reg)
}
}
+#if defined(TARGET_MIPS64)
+void gen_load_gpr_hi(TCGv_i64 t, int reg)
+{
+ if (reg == 0) {
+ tcg_gen_movi_i64(t, 0);
+ } else {
+ tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
+ }
+}
+
+void gen_store_gpr_hi(TCGv_i64 t, int reg)
+{
+ if (reg != 0) {
+ tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
+ }
+}
+#endif /* TARGET_MIPS64 */
+
/* Moves to/from shadow registers. */
static inline void gen_load_srsgpr(int from, int to)
{
@@ -4108,31 +4126,18 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
/* Copy GPR to and from TX79 HI1/LO1 register. */
static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
{
- if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
- /* Treat as NOP. */
- return;
- }
-
switch (opc) {
case MMI_OPC_MFHI1:
- tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
+ gen_store_gpr(cpu_HI[1], reg);
break;
case MMI_OPC_MFLO1:
- tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
+ gen_store_gpr(cpu_LO[1], reg);
break;
case MMI_OPC_MTHI1:
- if (reg != 0) {
- tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
- } else {
- tcg_gen_movi_tl(cpu_HI[1], 0);
- }
+ gen_load_gpr(cpu_HI[1], reg);
break;
case MMI_OPC_MTLO1:
- if (reg != 0) {
- tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
- } else {
- tcg_gen_movi_tl(cpu_LO[1], 0);
- }
+ gen_load_gpr(cpu_LO[1], reg);
break;
default:
MIPS_INVAL("mfthilo1 TX79");
@@ -13911,7 +13916,7 @@ static void decode_i64_mips16(DisasContext *ctx,
static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
{
- int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ int extend = translator_lduw(env, ctx->base.pc_next + 2);
int op, rx, ry, funct, sa;
int16_t imm, offset;
@@ -14161,7 +14166,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
/* No delay slot, so just process as a normal instruction */
break;
case M16_OPC_JAL:
- offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ offset = translator_lduw(env, ctx->base.pc_next + 2);
offset = (((ctx->opcode & 0x1f) << 21)
| ((ctx->opcode >> 5) & 0x1f) << 16
| offset) << 2;
@@ -16295,7 +16300,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
uint32_t op, minor, minor2, mips32_op;
uint32_t cond, fmt, cc;
- insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ insn = translator_lduw(env, ctx->base.pc_next + 2);
ctx->opcode = (ctx->opcode << 16) | insn;
rt = (ctx->opcode >> 21) & 0x1f;
@@ -21350,7 +21355,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
int offset;
int imm;
- insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ insn = translator_lduw(env, ctx->base.pc_next + 2);
ctx->opcode = (ctx->opcode << 16) | insn;
rt = extract32(ctx->opcode, 21, 5);
@@ -21469,7 +21474,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
break;
case NM_P48I:
{
- insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
+ insn = translator_lduw(env, ctx->base.pc_next + 4);
target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
switch (extract32(ctx->opcode, 16, 5)) {
case NM_LI48:
@@ -24784,7 +24789,7 @@ static void gen_mmi_pcpyh(DisasContext *ctx)
/* nop */
} else if (rt == 0) {
tcg_gen_movi_i64(cpu_gpr[rd], 0);
- tcg_gen_movi_i64(cpu_mmr[rd], 0);
+ tcg_gen_movi_i64(cpu_gpr_hi[rd], 0);
} else {
TCGv_i64 t0 = tcg_temp_new();
TCGv_i64 t1 = tcg_temp_new();
@@ -24802,7 +24807,7 @@ static void gen_mmi_pcpyh(DisasContext *ctx)
tcg_gen_mov_i64(cpu_gpr[rd], t1);
- tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
+ tcg_gen_andi_i64(t0, cpu_gpr_hi[rt], mask);
tcg_gen_movi_i64(t1, 0);
tcg_gen_or_i64(t1, t0, t1);
tcg_gen_shli_i64(t0, t0, 16);
@@ -24812,7 +24817,7 @@ static void gen_mmi_pcpyh(DisasContext *ctx)
tcg_gen_shli_i64(t0, t0, 16);
tcg_gen_or_i64(t1, t0, t1);
- tcg_gen_mov_i64(cpu_mmr[rd], t1);
+ tcg_gen_mov_i64(cpu_gpr_hi[rd], t1);
tcg_temp_free(t0);
tcg_temp_free(t1);
@@ -24844,9 +24849,9 @@ static void gen_mmi_pcpyld(DisasContext *ctx)
/* nop */
} else {
if (rs == 0) {
- tcg_gen_movi_i64(cpu_mmr[rd], 0);
+ tcg_gen_movi_i64(cpu_gpr_hi[rd], 0);
} else {
- tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
+ tcg_gen_mov_i64(cpu_gpr_hi[rd], cpu_gpr[rs]);
}
if (rt == 0) {
tcg_gen_movi_i64(cpu_gpr[rd], 0);
@@ -24885,13 +24890,13 @@ static void gen_mmi_pcpyud(DisasContext *ctx)
if (rs == 0) {
tcg_gen_movi_i64(cpu_gpr[rd], 0);
} else {
- tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
+ tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr_hi[rs]);
}
if (rt == 0) {
- tcg_gen_movi_i64(cpu_mmr[rd], 0);
+ tcg_gen_movi_i64(cpu_gpr_hi[rd], 0);
} else {
if (rd != rt) {
- tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
+ tcg_gen_mov_i64(cpu_gpr_hi[rd], cpu_gpr_hi[rt]);
}
}
}
@@ -29087,17 +29092,17 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
if (ctx->insn_flags & ISA_NANOMIPS32) {
- ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
+ ctx->opcode = translator_lduw(env, ctx->base.pc_next);
insn_bytes = decode_nanomips_opc(env, ctx);
} else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
- ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+ ctx->opcode = translator_ldl(env, ctx->base.pc_next);
insn_bytes = 4;
decode_opc(env, ctx);
} else if (ctx->insn_flags & ASE_MICROMIPS) {
- ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
+ ctx->opcode = translator_lduw(env, ctx->base.pc_next);
insn_bytes = decode_micromips_opc(env, ctx);
} else if (ctx->insn_flags & ASE_MIPS16) {
- ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
+ ctx->opcode = translator_lduw(env, ctx->base.pc_next);
insn_bytes = decode_mips16_opc(env, ctx);
} else {
gen_reserved_instruction(ctx);
@@ -29285,6 +29290,18 @@ void mips_tcg_init(void)
offsetof(CPUMIPSState,
active_tc.gpr[i]),
regnames[i]);
+#if defined(TARGET_MIPS64)
+ cpu_gpr_hi[0] = NULL;
+
+ for (unsigned i = 1; i < 32; i++) {
+ g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
+
+ cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUMIPSState,
+ active_tc.gpr_hi[i]),
+ rname);
+ }
+#endif /* !TARGET_MIPS64 */
for (i = 0; i < 32; i++) {
int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
@@ -29323,16 +29340,6 @@ void mips_tcg_init(void)
cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
"llval");
-#if defined(TARGET_MIPS64)
- cpu_mmr[0] = NULL;
- for (i = 1; i < 32; i++) {
- cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUMIPSState,
- active_tc.mmr[i]),
- regnames[i]);
- }
-#endif
-
#if !defined(TARGET_MIPS64)
for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
mxu_gpr[i] = tcg_global_mem_new(cpu_env,
@@ -29344,7 +29351,7 @@ void mips_tcg_init(void)
mxu_CR = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.mxu_cr),
mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
-#endif
+#endif /* !TARGET_MIPS64 */
}
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
diff --git a/target/mips/translate.h b/target/mips/translate.h
index f47b5f2c8d..468e29d757 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -131,6 +131,10 @@ void gen_move_low32(TCGv ret, TCGv_i64 arg);
void gen_move_high32(TCGv ret, TCGv_i64 arg);
void gen_load_gpr(TCGv t, int reg);
void gen_store_gpr(TCGv t, int reg);
+#if defined(TARGET_MIPS64)
+void gen_load_gpr_hi(TCGv_i64 t, int reg);
+void gen_store_gpr_hi(TCGv_i64 t, int reg);
+#endif /* TARGET_MIPS64 */
void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
@@ -145,6 +149,10 @@ bool gen_lsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
bool gen_dlsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
extern TCGv cpu_gpr[32], cpu_PC;
+#if defined(TARGET_MIPS64)
+extern TCGv_i64 cpu_gpr_hi[32];
+#endif
+extern TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
extern TCGv_i32 fpu_fcr0, fpu_fcr31;
extern TCGv_i64 fpu_f64[32];
extern TCGv bcond;