diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-02-21 19:52:58 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-02-21 19:52:58 +0000 |
commit | 00d8ba9e0d62ea1c7459c25aeabf9c8bb7659462 (patch) | |
tree | 188c7a650d48c12a9cf244575cdd13700471b584 /target | |
parent | 4115aec9af2a3de5fa89a0b1daa12debcd7741ff (diff) | |
parent | cc2b4550115baf77d556341f17eb464d18953cee (diff) | |
download | qemu-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.h | 26 | ||||
-rw-r--r-- | target/mips/internal.h | 10 | ||||
-rw-r--r-- | target/mips/msa_helper.c | 1 | ||||
-rw-r--r-- | target/mips/op_helper.c | 9 | ||||
-rw-r--r-- | target/mips/tlb_helper.c | 80 | ||||
-rw-r--r-- | target/mips/translate.c | 111 | ||||
-rw-r--r-- | target/mips/translate.h | 8 |
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; |