mirror of https://github.com/xemu-project/xemu.git
tests/tcg: Fix multiarch/gdbstub/prot-none.py
hw/core: Convert cpu_mmu_index to a CPUClass hook tcg/loongarch64: Set vector registers call clobbered target/sparc: floating-point cleanup linux-user/aarch64: Add padding before __kernel_rt_sigreturn -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmW95WkdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/p+Qf/eVmh5q0pZqcur7ft 8FO0wlIz55OfhaA9MIpH7LEIHRKY37Ybebw2K6SPnx4FmPhLkaj4KXPPjT2nzdXw J2nQM+TOyxOd18GG8P80qFQ1a72dj8VSIRVAl9T46KuPXS5B7luArImfBlUk/GwV Qr/XkOPwVTp05E/ccMJ8PMlcVZw9osHVLqsaFVbsUv/FylTmstzA9c5Gw7/FTfkG T2rk+7go+F4IXs/9uQuuFMOpQOZngXE621hnro+qle7j9oarEUVJloAgVn06o59O fUjuoKO0aMCr2iQqNJTH7Dnqp5OIzzxUoXiNTOj0EimwWfAcUKthoFO2LGcy1/ew wWNR/Q== =e3J3 -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20240202-2' of https://gitlab.com/rth7680/qemu into staging tests/tcg: Fix multiarch/gdbstub/prot-none.py hw/core: Convert cpu_mmu_index to a CPUClass hook tcg/loongarch64: Set vector registers call clobbered target/sparc: floating-point cleanup linux-user/aarch64: Add padding before __kernel_rt_sigreturn # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmW95WkdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/p+Qf/eVmh5q0pZqcur7ft # 8FO0wlIz55OfhaA9MIpH7LEIHRKY37Ybebw2K6SPnx4FmPhLkaj4KXPPjT2nzdXw # J2nQM+TOyxOd18GG8P80qFQ1a72dj8VSIRVAl9T46KuPXS5B7luArImfBlUk/GwV # Qr/XkOPwVTp05E/ccMJ8PMlcVZw9osHVLqsaFVbsUv/FylTmstzA9c5Gw7/FTfkG # T2rk+7go+F4IXs/9uQuuFMOpQOZngXE621hnro+qle7j9oarEUVJloAgVn06o59O # fUjuoKO0aMCr2iQqNJTH7Dnqp5OIzzxUoXiNTOj0EimwWfAcUKthoFO2LGcy1/ew # wWNR/Q== # =e3J3 # -----END PGP SIGNATURE----- # gpg: Signature made Sat 03 Feb 2024 07:04:09 GMT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * tag 'pull-tcg-20240202-2' of https://gitlab.com/rth7680/qemu: (58 commits) linux-user/aarch64: Add padding before __kernel_rt_sigreturn target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK target/sparc: Split fcc out of env->fsr target/sparc: Remove cpu_fsr target/sparc: Split cexc and ftt from env->fsr target/sparc: Merge check_ieee_exceptions with FPop helpers target/sparc: Clear cexc and ftt in do_check_ieee_exceptions target/sparc: Split ver from env->fsr target/sparc: Introduce cpu_get_fsr, cpu_put_fsr target/sparc: Remove qt0, qt1 temporaries target/sparc: Use i128 for Fdmulq target/sparc: Use i128 for FdTOq, FxTOq target/sparc: Use i128 for FsTOq, FiTOq target/sparc: Use i128 for FCMPq, FCMPEq target/sparc: Use i128 for FqTOd, FqTOx target/sparc: Use i128 for FqTOs, FqTOi target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq target/sparc: Use i128 for FSQRTq target/sparc: Inline FNEG, FABS target/sparc: Introduce gen_{load,store}_fpr_Q ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
10eab96e1a
|
@ -1601,7 +1601,7 @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr,
|
|||
void *p;
|
||||
|
||||
(void)probe_access_internal(env_cpu(env), addr, 1, MMU_INST_FETCH,
|
||||
cpu_mmu_index(env, true), false,
|
||||
cpu_mmu_index(env_cpu(env), true), false,
|
||||
&p, &full, 0, false);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
|
@ -2959,26 +2959,30 @@ static void do_st16_mmu(CPUState *cpu, vaddr addr, Int128 val,
|
|||
|
||||
uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(env, true));
|
||||
return do_ld1_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
|
||||
CPUState *cs = env_cpu(env);
|
||||
MemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(cs, true));
|
||||
return do_ld1_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
|
||||
}
|
||||
|
||||
uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(env, true));
|
||||
return do_ld2_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
|
||||
CPUState *cs = env_cpu(env);
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(cs, true));
|
||||
return do_ld2_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
|
||||
}
|
||||
|
||||
uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(env, true));
|
||||
return do_ld4_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
|
||||
CPUState *cs = env_cpu(env);
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(cs, true));
|
||||
return do_ld4_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
|
||||
}
|
||||
|
||||
uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true));
|
||||
return do_ld8_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
|
||||
CPUState *cs = env_cpu(env);
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(cs, true));
|
||||
return do_ld8_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
|
||||
}
|
||||
|
||||
uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
|
||||
|
|
|
@ -354,7 +354,8 @@ void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
|
|||
|
||||
uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_ldub_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_ldub_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
|
@ -364,7 +365,8 @@ int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
|||
|
||||
uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_lduw_be_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_lduw_be_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
|
@ -374,17 +376,20 @@ int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
|||
|
||||
uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_ldl_be_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_ldl_be_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_ldq_be_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_ldq_be_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_lduw_le_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_lduw_le_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
|
@ -394,54 +399,63 @@ int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
|||
|
||||
uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_ldl_le_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_ldl_le_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
|
||||
{
|
||||
return cpu_ldq_le_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
return cpu_ldq_le_mmuidx_ra(env, addr, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stb_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stb_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stb_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stw_be_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stw_be_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stl_be_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stl_be_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stq_be_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stq_be_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stw_le_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stw_le_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stl_le_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stl_le_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t val, uintptr_t ra)
|
||||
{
|
||||
cpu_stq_le_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra);
|
||||
int mmu_index = cpu_mmu_index(env_cpu(env), false);
|
||||
cpu_stq_le_mmuidx_ra(env, addr, val, mmu_index, ra);
|
||||
}
|
||||
|
||||
/*--------------------------*/
|
||||
|
|
|
@ -311,6 +311,10 @@ CPUArchState *cpu_copy(CPUArchState *env);
|
|||
#define TLB_MMIO (1 << (TARGET_PAGE_BITS_MIN - 2))
|
||||
#define TLB_WATCHPOINT 0
|
||||
|
||||
static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return MMU_USER_IDX;
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "exec/hwaddr.h"
|
||||
#endif
|
||||
#include "hw/core/cpu.h"
|
||||
#include "tcg/debug-assert.h"
|
||||
|
||||
#define EXCP_INTERRUPT 0x10000 /* async interruption */
|
||||
#define EXCP_HLT 0x10001 /* hlt instruction reached */
|
||||
|
@ -262,4 +263,24 @@ static inline CPUState *env_cpu(CPUArchState *env)
|
|||
return (void *)env - sizeof(CPUState);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/**
|
||||
* cpu_mmu_index:
|
||||
* @env: The cpu environment
|
||||
* @ifetch: True for code access, false for data access.
|
||||
*
|
||||
* Return the core mmu index for the current translation regime.
|
||||
* This function is used by generic TCG code paths.
|
||||
*
|
||||
* The user-only version of this function is inline in cpu-all.h,
|
||||
* where it always returns MMU_USER_IDX.
|
||||
*/
|
||||
static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
int ret = cs->cc->mmu_index(cs, ifetch);
|
||||
tcg_debug_assert(ret >= 0 && ret < NB_MMU_MODES);
|
||||
return ret;
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
#endif /* CPU_COMMON_H */
|
||||
|
|
|
@ -103,6 +103,8 @@ struct SysemuCPUOps;
|
|||
* @parse_features: Callback to parse command line arguments.
|
||||
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
||||
* @has_work: Callback for checking if there is work to do.
|
||||
* @mmu_index: Callback for choosing softmmu mmu index;
|
||||
* may be used internally by memory_rw_debug without TCG.
|
||||
* @memory_rw_debug: Callback for GDB memory access.
|
||||
* @dump_state: Callback for dumping state.
|
||||
* @query_cpu_fast:
|
||||
|
@ -150,6 +152,7 @@ struct CPUClass {
|
|||
void (*parse_features)(const char *typename, char *str, Error **errp);
|
||||
|
||||
bool (*has_work)(CPUState *cpu);
|
||||
int (*mmu_index)(CPUState *cpu, bool ifetch);
|
||||
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
|
||||
uint8_t *buf, int len, bool is_write);
|
||||
void (*dump_state)(CPUState *cpu, FILE *, int flags);
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -63,7 +63,11 @@ vdso_syscall __kernel_clock_getres, __NR_clock_getres
|
|||
* For now, elide the unwind info for __kernel_rt_sigreturn and rely on
|
||||
* the libgcc fallback routine as we have always done. This requires
|
||||
* that the code sequence used be exact.
|
||||
*
|
||||
* Add a nop as a spacer to ensure that unwind does not pick up the
|
||||
* unwind info from the preceding syscall.
|
||||
*/
|
||||
nop
|
||||
__kernel_rt_sigreturn:
|
||||
/* No BTI C insn here -- we arrive via RET. */
|
||||
mov x8, #__NR_rt_sigreturn
|
||||
|
|
|
@ -293,7 +293,7 @@ void cpu_loop (CPUSPARCState *env)
|
|||
case TT_FP_EXCP:
|
||||
{
|
||||
int code = TARGET_FPE_FLTUNK;
|
||||
target_ulong fsr = env->fsr;
|
||||
target_ulong fsr = cpu_get_fsr(env);
|
||||
|
||||
if ((fsr & FSR_FTT_MASK) == FSR_FTT_IEEE_EXCP) {
|
||||
if (fsr & FSR_NVC) {
|
||||
|
|
|
@ -199,20 +199,21 @@ static void save_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
|
|||
for (i = 0; i < 32; ++i) {
|
||||
__put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
__put_user(env->fsr, &fpu->si_fsr);
|
||||
__put_user(cpu_get_fsr(env), &fpu->si_fsr);
|
||||
__put_user(env->gsr, &fpu->si_gsr);
|
||||
__put_user(env->fprs, &fpu->si_fprs);
|
||||
#else
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
__put_user(env->fsr, &fpu->si_fsr);
|
||||
__put_user(cpu_get_fsr(env), &fpu->si_fsr);
|
||||
__put_user(0, &fpu->si_fpqdepth);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
|
||||
{
|
||||
target_ulong fsr;
|
||||
int i;
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
|
@ -230,15 +231,16 @@ static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
|
|||
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
}
|
||||
__get_user(env->fsr, &fpu->si_fsr);
|
||||
__get_user(env->gsr, &fpu->si_gsr);
|
||||
env->fprs |= fprs;
|
||||
#else
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
__get_user(env->fsr, &fpu->si_fsr);
|
||||
#endif
|
||||
|
||||
__get_user(fsr, &fpu->si_fsr);
|
||||
cpu_put_fsr(env, fsr);
|
||||
}
|
||||
|
||||
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
|
||||
|
@ -662,6 +664,7 @@ void sparc64_set_context(CPUSPARCState *env)
|
|||
__get_user(fenab, &(fpup->mcfpu_enab));
|
||||
if (fenab) {
|
||||
abi_ulong fprs;
|
||||
abi_ulong fsr;
|
||||
|
||||
/*
|
||||
* We use the FPRS from the guest only in deciding whether
|
||||
|
@ -690,7 +693,8 @@ void sparc64_set_context(CPUSPARCState *env)
|
|||
__get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
|
||||
}
|
||||
}
|
||||
__get_user(env->fsr, &(fpup->mcfpu_fsr));
|
||||
__get_user(fsr, &(fpup->mcfpu_fsr));
|
||||
cpu_put_fsr(env, fsr);
|
||||
__get_user(env->gsr, &(fpup->mcfpu_gsr));
|
||||
}
|
||||
unlock_user_struct(ucp, ucp_addr, 0);
|
||||
|
|
|
@ -26,7 +26,7 @@ void *uaccess_lock_user(CPUArchState *env, target_ulong addr,
|
|||
|
||||
ssize_t uaccess_strlen_user(CPUArchState *env, target_ulong addr)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = cpu_mmu_index(env_cpu(env), false);
|
||||
size_t len = 0;
|
||||
|
||||
while (1) {
|
||||
|
|
|
@ -64,6 +64,11 @@ static bool alpha_cpu_has_work(CPUState *cs)
|
|||
| CPU_INTERRUPT_MCHK);
|
||||
}
|
||||
|
||||
static int alpha_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return alpha_env_mmu_index(cpu_env(cs));
|
||||
}
|
||||
|
||||
static void alpha_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
|
||||
{
|
||||
info->mach = bfd_mach_alpha_ev6;
|
||||
|
@ -230,6 +235,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = alpha_cpu_class_by_name;
|
||||
cc->has_work = alpha_cpu_has_work;
|
||||
cc->mmu_index = alpha_cpu_mmu_index;
|
||||
cc->dump_state = alpha_cpu_dump_state;
|
||||
cc->set_pc = alpha_cpu_set_pc;
|
||||
cc->get_pc = alpha_cpu_get_pc;
|
||||
|
|
|
@ -389,7 +389,7 @@ enum {
|
|||
|
||||
#define TB_FLAG_UNALIGN (1u << 1)
|
||||
|
||||
static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
|
||||
static inline int alpha_env_mmu_index(CPUAlphaState *env)
|
||||
{
|
||||
int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX;
|
||||
if (env->flags & ENV_FLAG_PAL_MODE) {
|
||||
|
|
|
@ -2875,7 +2875,7 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
|
|||
int64_t bound;
|
||||
|
||||
ctx->tbflags = ctx->base.tb->flags;
|
||||
ctx->mem_idx = cpu_mmu_index(env, false);
|
||||
ctx->mem_idx = alpha_env_mmu_index(env);
|
||||
ctx->implver = env->implver;
|
||||
ctx->amask = env->amask;
|
||||
|
||||
|
|
|
@ -133,6 +133,11 @@ static bool arm_cpu_has_work(CPUState *cs)
|
|||
| CPU_INTERRUPT_EXITTB);
|
||||
}
|
||||
|
||||
static int arm_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return arm_env_mmu_index(cpu_env(cs));
|
||||
}
|
||||
|
||||
void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
|
||||
void *opaque)
|
||||
{
|
||||
|
@ -2501,6 +2506,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = arm_cpu_class_by_name;
|
||||
cc->has_work = arm_cpu_has_work;
|
||||
cc->mmu_index = arm_cpu_mmu_index;
|
||||
cc->dump_state = arm_cpu_dump_state;
|
||||
cc->set_pc = arm_cpu_set_pc;
|
||||
cc->get_pc = arm_cpu_get_pc;
|
||||
|
|
|
@ -3240,19 +3240,6 @@ FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
|
|||
#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
|
||||
#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
|
||||
|
||||
/**
|
||||
* cpu_mmu_index:
|
||||
* @env: The cpu environment
|
||||
* @ifetch: True for code access, false for data access.
|
||||
*
|
||||
* Return the core mmu index for the current translation regime.
|
||||
* This function is used by generic TCG code paths.
|
||||
*/
|
||||
static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
|
||||
{
|
||||
return EX_TBFLAG_ANY(env->hflags, MMUIDX);
|
||||
}
|
||||
|
||||
/**
|
||||
* sve_vq
|
||||
* @env: the cpu context
|
||||
|
|
|
@ -7841,7 +7841,7 @@ static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
|
|||
uint64_t vaddr_in = (uint64_t) value;
|
||||
uint64_t vaddr = vaddr_in & ~(dline_size - 1);
|
||||
void *haddr;
|
||||
int mem_idx = cpu_mmu_index(env, false);
|
||||
int mem_idx = arm_env_mmu_index(env);
|
||||
|
||||
/* This won't be crossing page boundaries */
|
||||
haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
#define BANK_HYP 6
|
||||
#define BANK_MON 7
|
||||
|
||||
static inline int arm_env_mmu_index(CPUARMState *env)
|
||||
{
|
||||
return EX_TBFLAG_ANY(env->hflags, MMUIDX);
|
||||
}
|
||||
|
||||
static inline bool excp_is_internal(int excp)
|
||||
{
|
||||
/* Return true if this exception number represents a QEMU-internal
|
||||
|
|
|
@ -856,7 +856,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
|
|||
tbii = EX_TBFLAG_A64(env->hflags, TBII);
|
||||
if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
|
||||
/* TBI is enabled. */
|
||||
int core_mmu_idx = cpu_mmu_index(env, false);
|
||||
int core_mmu_idx = arm_env_mmu_index(env);
|
||||
if (regime_has_2_ranges(core_to_aa64_mmu_idx(core_mmu_idx))) {
|
||||
new_pc = sextract64(new_pc, 0, 56);
|
||||
} else {
|
||||
|
@ -925,7 +925,7 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
|
|||
*/
|
||||
int blocklen = 4 << env_archcpu(env)->dcz_blocksize;
|
||||
uint64_t vaddr = vaddr_in & ~(blocklen - 1);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
void *mem;
|
||||
|
||||
/*
|
||||
|
|
|
@ -291,7 +291,7 @@ static int load_tag1(uint64_t ptr, uint8_t *mem)
|
|||
|
||||
uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uint8_t *mem;
|
||||
int rtag = 0;
|
||||
|
||||
|
@ -311,7 +311,7 @@ static void check_tag_aligned(CPUARMState *env, uint64_t ptr, uintptr_t ra)
|
|||
{
|
||||
if (unlikely(!QEMU_IS_ALIGNED(ptr, TAG_GRANULE))) {
|
||||
arm_cpu_do_unaligned_access(env_cpu(env), ptr, MMU_DATA_STORE,
|
||||
cpu_mmu_index(env, false), ra);
|
||||
arm_env_mmu_index(env), ra);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ typedef void stg_store1(uint64_t, uint8_t *, int);
|
|||
static inline void do_stg(CPUARMState *env, uint64_t ptr, uint64_t xt,
|
||||
uintptr_t ra, stg_store1 store1)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uint8_t *mem;
|
||||
|
||||
check_tag_aligned(env, ptr, ra);
|
||||
|
@ -371,7 +371,7 @@ void HELPER(stg_parallel)(CPUARMState *env, uint64_t ptr, uint64_t xt)
|
|||
|
||||
void HELPER(stg_stub)(CPUARMState *env, uint64_t ptr)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
|
||||
check_tag_aligned(env, ptr, ra);
|
||||
|
@ -381,7 +381,7 @@ void HELPER(stg_stub)(CPUARMState *env, uint64_t ptr)
|
|||
static inline void do_st2g(CPUARMState *env, uint64_t ptr, uint64_t xt,
|
||||
uintptr_t ra, stg_store1 store1)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
int tag = allocation_tag_from_addr(xt);
|
||||
uint8_t *mem1, *mem2;
|
||||
|
||||
|
@ -429,7 +429,7 @@ void HELPER(st2g_parallel)(CPUARMState *env, uint64_t ptr, uint64_t xt)
|
|||
|
||||
void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
int in_page = -(ptr | TARGET_PAGE_MASK);
|
||||
|
||||
|
@ -445,7 +445,7 @@ void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
|
|||
|
||||
uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
int gm_bs = env_archcpu(env)->gm_blocksize;
|
||||
int gm_bs_bytes = 4 << gm_bs;
|
||||
|
@ -505,7 +505,7 @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
|
|||
|
||||
void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
int gm_bs = env_archcpu(env)->gm_blocksize;
|
||||
int gm_bs_bytes = 4 << gm_bs;
|
||||
|
@ -555,7 +555,7 @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
|
|||
void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
int log2_dcz_bytes, log2_tag_bytes;
|
||||
intptr_t dcz_bytes, tag_bytes;
|
||||
uint8_t *mem;
|
||||
|
|
|
@ -5481,7 +5481,7 @@ bool sve_cont_ldst_pages(SVEContLdSt *info, SVEContFault fault,
|
|||
CPUARMState *env, target_ulong addr,
|
||||
MMUAccessType access_type, uintptr_t retaddr)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
int mem_off = info->mem_off_first[0];
|
||||
bool nofault = fault == FAULT_NO;
|
||||
bool have_work = true;
|
||||
|
@ -6529,7 +6529,7 @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
|
|||
sve_ldst1_host_fn *host_fn,
|
||||
sve_ldst1_tlb_fn *tlb_fn)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = arm_env_mmu_index(env);
|
||||
const intptr_t reg_max = simd_oprsz(desc);
|
||||
const int scale = simd_data(desc);
|
||||
ARMVectorReg scratch;
|
||||
|
@ -6715,7 +6715,7 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
|
|||
sve_ldst1_host_fn *host_fn,
|
||||
sve_ldst1_tlb_fn *tlb_fn)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = arm_env_mmu_index(env);
|
||||
const intptr_t reg_max = simd_oprsz(desc);
|
||||
const int scale = simd_data(desc);
|
||||
const int esize = 1 << esz;
|
||||
|
@ -6920,7 +6920,7 @@ void sve_st1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
|
|||
sve_ldst1_host_fn *host_fn,
|
||||
sve_ldst1_tlb_fn *tlb_fn)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = arm_env_mmu_index(env);
|
||||
const intptr_t reg_max = simd_oprsz(desc);
|
||||
const int scale = simd_data(desc);
|
||||
void *host[ARM_MAX_VQ * 4];
|
||||
|
|
|
@ -281,7 +281,7 @@ void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
|
|||
{
|
||||
ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
|
||||
int target_el = exception_target_el(env);
|
||||
int mmu_idx = cpu_mmu_index(env, true);
|
||||
int mmu_idx = arm_env_mmu_index(env);
|
||||
uint32_t fsc;
|
||||
|
||||
env->exception.vaddress = pc;
|
||||
|
|
|
@ -50,6 +50,11 @@ static bool avr_cpu_has_work(CPUState *cs)
|
|||
&& cpu_interrupts_enabled(env);
|
||||
}
|
||||
|
||||
static int avr_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
|
||||
}
|
||||
|
||||
static void avr_cpu_synchronize_from_tb(CPUState *cs,
|
||||
const TranslationBlock *tb)
|
||||
{
|
||||
|
@ -236,6 +241,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
|
|||
cc->class_by_name = avr_cpu_class_by_name;
|
||||
|
||||
cc->has_work = avr_cpu_has_work;
|
||||
cc->mmu_index = avr_cpu_mmu_index;
|
||||
cc->dump_state = avr_cpu_dump_state;
|
||||
cc->set_pc = avr_cpu_set_pc;
|
||||
cc->get_pc = avr_cpu_get_pc;
|
||||
|
|
|
@ -184,13 +184,6 @@ static inline void set_avr_feature(CPUAVRState *env, int feature)
|
|||
env->features |= (1U << feature);
|
||||
}
|
||||
|
||||
#define cpu_mmu_index avr_cpu_mmu_index
|
||||
|
||||
static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch)
|
||||
{
|
||||
return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
|
||||
}
|
||||
|
||||
void avr_cpu_tcg_init(void);
|
||||
|
||||
int cpu_avr_exec(CPUState *cpu);
|
||||
|
|
|
@ -56,6 +56,11 @@ static bool cris_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
|
||||
static int cris_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return !!(cpu_env(cs)->pregs[PR_CCS] & U_FLAG);
|
||||
}
|
||||
|
||||
static void cris_cpu_reset_hold(Object *obj)
|
||||
{
|
||||
CPUState *s = CPU(obj);
|
||||
|
@ -274,6 +279,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = cris_cpu_class_by_name;
|
||||
cc->has_work = cris_cpu_has_work;
|
||||
cc->mmu_index = cris_cpu_mmu_index;
|
||||
cc->dump_state = cris_cpu_dump_state;
|
||||
cc->set_pc = cris_cpu_set_pc;
|
||||
cc->get_pc = cris_cpu_get_pc;
|
||||
|
|
|
@ -260,10 +260,6 @@ enum {
|
|||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_USER_IDX 1
|
||||
static inline int cpu_mmu_index (CPUCRISState *env, bool ifetch)
|
||||
{
|
||||
return !!(env->pregs[PR_CCS] & U_FLAG);
|
||||
}
|
||||
|
||||
/* Support function regs. */
|
||||
#define SFR_RW_GC_CFG 0][0
|
||||
|
|
|
@ -94,6 +94,7 @@ typedef struct DisasContext {
|
|||
|
||||
CRISCPU *cpu;
|
||||
target_ulong pc, ppc;
|
||||
int mem_index;
|
||||
|
||||
/* Decoder. */
|
||||
unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
|
||||
|
@ -1008,37 +1009,31 @@ static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
|
|||
|
||||
static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
|
||||
{
|
||||
int mem_index = cpu_mmu_index(&dc->cpu->env, false);
|
||||
|
||||
/* If we get a fault on a delayslot we must keep the jmp state in
|
||||
the cpu-state to be able to re-execute the jmp. */
|
||||
if (dc->delayed_branch == 1) {
|
||||
cris_store_direct_jmp(dc);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEUQ);
|
||||
tcg_gen_qemu_ld_i64(dst, addr, dc->mem_index, MO_TEUQ);
|
||||
}
|
||||
|
||||
static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
|
||||
unsigned int size, int sign)
|
||||
{
|
||||
int mem_index = cpu_mmu_index(&dc->cpu->env, false);
|
||||
|
||||
/* If we get a fault on a delayslot we must keep the jmp state in
|
||||
the cpu-state to be able to re-execute the jmp. */
|
||||
if (dc->delayed_branch == 1) {
|
||||
cris_store_direct_jmp(dc);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_ld_tl(dst, addr, mem_index,
|
||||
tcg_gen_qemu_ld_tl(dst, addr, dc->mem_index,
|
||||
MO_TE + ctz32(size) + (sign ? MO_SIGN : 0));
|
||||
}
|
||||
|
||||
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
|
||||
unsigned int size)
|
||||
{
|
||||
int mem_index = cpu_mmu_index(&dc->cpu->env, false);
|
||||
|
||||
/* If we get a fault on a delayslot we must keep the jmp state in
|
||||
the cpu-state to be able to re-execute the jmp. */
|
||||
if (dc->delayed_branch == 1) {
|
||||
|
@ -1055,7 +1050,7 @@ static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
|
|||
return;
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size));
|
||||
tcg_gen_qemu_st_tl(val, addr, dc->mem_index, MO_TE + ctz32(size));
|
||||
|
||||
if (dc->flags_x) {
|
||||
cris_evaluate_flags(dc);
|
||||
|
@ -2971,6 +2966,7 @@ static void cris_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
|||
dc->cpu = env_archcpu(env);
|
||||
dc->ppc = pc_start;
|
||||
dc->pc = pc_start;
|
||||
dc->mem_index = cpu_mmu_index(cs, false);
|
||||
dc->flags_uptodate = 1;
|
||||
dc->flags_x = tb_flags & X_FLAG;
|
||||
dc->cc_x_uptodate = 0;
|
||||
|
|
|
@ -91,8 +91,6 @@ static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
|
|||
static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
|
||||
unsigned int size)
|
||||
{
|
||||
int mem_index = cpu_mmu_index(&dc->cpu->env, false);
|
||||
|
||||
/* If we get a fault on a delayslot we must keep the jmp state in
|
||||
the cpu-state to be able to re-execute the jmp. */
|
||||
if (dc->delayed_branch == 1) {
|
||||
|
@ -101,11 +99,11 @@ static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
|
|||
|
||||
/* Conditional writes. */
|
||||
if (dc->flags_x) {
|
||||
gen_store_v10_conditional(dc, addr, val, size, mem_index);
|
||||
gen_store_v10_conditional(dc, addr, val, size, dc->mem_index);
|
||||
return;
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_tl(val, addr, mem_index, ctz32(size) | MO_TE);
|
||||
tcg_gen_qemu_st_tl(val, addr, dc->mem_index, ctz32(size) | MO_TE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -146,15 +146,6 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
|
|||
*flags = hex_flags;
|
||||
}
|
||||
|
||||
static inline int cpu_mmu_index(CPUHexagonState *env, bool ifetch)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return MMU_USER_IDX;
|
||||
#else
|
||||
#error System mode not supported on Hexagon yet
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef HexagonCPU ArchCPU;
|
||||
|
||||
void hexagon_translate_init(void);
|
||||
|
|
|
@ -94,6 +94,17 @@ static bool hppa_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
|
||||
static int hppa_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPUHPPAState *env = cpu_env(cs);
|
||||
|
||||
if (env->psw & (ifetch ? PSW_C : PSW_D)) {
|
||||
return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
|
||||
}
|
||||
/* mmu disabled */
|
||||
return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
|
||||
}
|
||||
|
||||
static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
|
||||
{
|
||||
info->mach = bfd_mach_hppa20;
|
||||
|
@ -194,6 +205,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = hppa_cpu_class_by_name;
|
||||
cc->has_work = hppa_cpu_has_work;
|
||||
cc->mmu_index = hppa_cpu_mmu_index;
|
||||
cc->dump_state = hppa_cpu_dump_state;
|
||||
cc->set_pc = hppa_cpu_set_pc;
|
||||
cc->get_pc = hppa_cpu_get_pc;
|
||||
|
|
|
@ -281,19 +281,6 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
|
|||
return hppa_is_pa20(env) ? 0 : PA10_BTLB_FIXED + PA10_BTLB_VARIABLE;
|
||||
}
|
||||
|
||||
static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return MMU_USER_IDX;
|
||||
#else
|
||||
if (env->psw & (ifetch ? PSW_C : PSW_D)) {
|
||||
return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
|
||||
}
|
||||
/* mmu disabled */
|
||||
return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
|
||||
#endif
|
||||
}
|
||||
|
||||
void hppa_translate_init(void);
|
||||
|
||||
#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
|
||||
|
|
|
@ -646,7 +646,7 @@ int hppa_artype_for_page(CPUHPPAState *env, target_ulong vaddr)
|
|||
void HELPER(diag_btlb)(CPUHPPAState *env)
|
||||
{
|
||||
unsigned int phys_page, len, slot;
|
||||
int mmu_idx = cpu_mmu_index(env, 0);
|
||||
int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
|
||||
uintptr_t ra = GETPC();
|
||||
HPPATLBEntry *btlb;
|
||||
uint64_t virt_page;
|
||||
|
|
|
@ -59,7 +59,7 @@ void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
|
|||
static void atomic_store_mask32(CPUHPPAState *env, target_ulong addr,
|
||||
uint32_t val, uint32_t mask, uintptr_t ra)
|
||||
{
|
||||
int mmu_idx = cpu_mmu_index(env, 0);
|
||||
int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
|
||||
uint32_t old, new, cmp, *haddr;
|
||||
void *vaddr;
|
||||
|
||||
|
@ -86,7 +86,7 @@ static void atomic_store_mask64(CPUHPPAState *env, target_ulong addr,
|
|||
int size, uintptr_t ra)
|
||||
{
|
||||
#ifdef CONFIG_ATOMIC64
|
||||
int mmu_idx = cpu_mmu_index(env, 0);
|
||||
int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
|
||||
uint64_t old, new, cmp, *haddr;
|
||||
void *vaddr;
|
||||
|
||||
|
@ -235,7 +235,7 @@ static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ulong val,
|
|||
default:
|
||||
/* Nothing is stored, but protection is checked and the
|
||||
cacheline is marked dirty. */
|
||||
probe_write(env, addr, 0, cpu_mmu_index(env, 0), ra);
|
||||
probe_write(env, addr, 0, cpu_mmu_index(env_cpu(env), 0), ra);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ static void do_stdby_e(CPUHPPAState *env, target_ulong addr, uint64_t val,
|
|||
default:
|
||||
/* Nothing is stored, but protection is checked and the
|
||||
cacheline is marked dirty. */
|
||||
probe_write(env, addr, 0, cpu_mmu_index(env, 0), ra);
|
||||
probe_write(env, addr, 0, cpu_mmu_index(env_cpu(env), 0), ra);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7720,6 +7720,15 @@ static bool x86_cpu_has_work(CPUState *cs)
|
|||
return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
|
||||
}
|
||||
|
||||
static int x86_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPUX86State *env = cpu_env(cs);
|
||||
|
||||
return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
|
||||
(!(env->hflags & HF_SMAP_MASK) || (env->eflags & AC_MASK))
|
||||
? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
|
||||
}
|
||||
|
||||
static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
|
@ -7954,6 +7963,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
|||
cc->class_by_name = x86_cpu_class_by_name;
|
||||
cc->parse_features = x86_cpu_parse_featurestr;
|
||||
cc->has_work = x86_cpu_has_work;
|
||||
cc->mmu_index = x86_cpu_mmu_index;
|
||||
cc->dump_state = x86_cpu_dump_state;
|
||||
cc->set_pc = x86_cpu_set_pc;
|
||||
cc->get_pc = x86_cpu_get_pc;
|
||||
|
|
|
@ -2296,13 +2296,6 @@ uint64_t cpu_get_tsc(CPUX86State *env);
|
|||
#define MMU_NESTED_IDX 3
|
||||
#define MMU_PHYS_IDX 4
|
||||
|
||||
static inline int cpu_mmu_index(CPUX86State *env, bool ifetch)
|
||||
{
|
||||
return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
|
||||
(!(env->hflags & HF_SMAP_MASK) || (env->eflags & AC_MASK))
|
||||
? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
|
||||
}
|
||||
|
||||
static inline int cpu_mmu_index_kernel(CPUX86State *env)
|
||||
{
|
||||
return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX :
|
||||
|
|
|
@ -6955,7 +6955,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
|
|||
dc->cc_op_dirty = false;
|
||||
dc->popl_esp_hack = 0;
|
||||
/* select memory access functions */
|
||||
dc->mem_index = cpu_mmu_index(env, false);
|
||||
dc->mem_index = cpu_mmu_index(cpu, false);
|
||||
dc->cpuid_features = env->features[FEAT_1_EDX];
|
||||
dc->cpuid_ext_features = env->features[FEAT_1_ECX];
|
||||
dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
|
||||
|
|
|
@ -375,6 +375,16 @@ static bool loongarch_cpu_has_work(CPUState *cs)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPULoongArchState *env = cpu_env(cs);
|
||||
|
||||
if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
|
||||
return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
|
||||
}
|
||||
return MMU_DA_IDX;
|
||||
}
|
||||
|
||||
static void loongarch_la464_initfn(Object *obj)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
|
@ -777,6 +787,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
|
|||
|
||||
cc->class_by_name = loongarch_cpu_class_by_name;
|
||||
cc->has_work = loongarch_cpu_has_work;
|
||||
cc->mmu_index = loongarch_cpu_mmu_index;
|
||||
cc->dump_state = loongarch_cpu_dump_state;
|
||||
cc->set_pc = loongarch_cpu_set_pc;
|
||||
cc->get_pc = loongarch_cpu_get_pc;
|
||||
|
|
|
@ -404,21 +404,9 @@ struct LoongArchCPUClass {
|
|||
*/
|
||||
#define MMU_PLV_KERNEL 0
|
||||
#define MMU_PLV_USER 3
|
||||
#define MMU_IDX_KERNEL MMU_PLV_KERNEL
|
||||
#define MMU_IDX_USER MMU_PLV_USER
|
||||
#define MMU_IDX_DA 4
|
||||
|
||||
static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return MMU_IDX_USER;
|
||||
#else
|
||||
if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
|
||||
return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
|
||||
}
|
||||
return MMU_IDX_DA;
|
||||
#endif
|
||||
}
|
||||
#define MMU_KERNEL_IDX MMU_PLV_KERNEL
|
||||
#define MMU_USER_IDX MMU_PLV_USER
|
||||
#define MMU_DA_IDX 4
|
||||
|
||||
static inline bool is_la64(CPULoongArchState *env)
|
||||
{
|
||||
|
|
|
@ -171,8 +171,8 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical,
|
|||
int *prot, target_ulong address,
|
||||
MMUAccessType access_type, int mmu_idx)
|
||||
{
|
||||
int user_mode = mmu_idx == MMU_IDX_USER;
|
||||
int kernel_mode = mmu_idx == MMU_IDX_KERNEL;
|
||||
int user_mode = mmu_idx == MMU_USER_IDX;
|
||||
int kernel_mode = mmu_idx == MMU_KERNEL_IDX;
|
||||
uint32_t plv, base_c, base_v;
|
||||
int64_t addr_high;
|
||||
uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
|
||||
|
@ -224,7 +224,7 @@ hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
int prot;
|
||||
|
||||
if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
|
||||
cpu_mmu_index(env, false)) != 0) {
|
||||
cpu_mmu_index(cs, false)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return phys_addr;
|
||||
|
|
|
@ -323,7 +323,7 @@ TRANS(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
|
|||
|
||||
static void check_mmu_idx(DisasContext *ctx)
|
||||
{
|
||||
if (ctx->mem_idx != MMU_IDX_DA) {
|
||||
if (ctx->mem_idx != MMU_DA_IDX) {
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
|
||||
ctx->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
|
|||
uint8_t tlb_ps;
|
||||
LoongArchTLB *tlb = &env->tlb[index];
|
||||
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = cpu_mmu_index(env_cpu(env), false);
|
||||
uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
|
||||
uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
|
||||
uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
|
||||
|
|
|
@ -125,7 +125,7 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
|
|||
if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) {
|
||||
ctx->mem_idx = ctx->plv;
|
||||
} else {
|
||||
ctx->mem_idx = MMU_IDX_DA;
|
||||
ctx->mem_idx = MMU_DA_IDX;
|
||||
}
|
||||
|
||||
/* Bound the number of insns to execute to those left on the page. */
|
||||
|
|
|
@ -56,6 +56,11 @@ static bool m68k_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
static int m68k_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return cpu_env(cs)->sr & SR_S ? MMU_KERNEL_IDX : MMU_USER_IDX;
|
||||
}
|
||||
|
||||
static void m68k_set_feature(CPUM68KState *env, int feature)
|
||||
{
|
||||
env->features |= BIT_ULL(feature);
|
||||
|
@ -551,6 +556,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
|
|||
|
||||
cc->class_by_name = m68k_cpu_class_by_name;
|
||||
cc->has_work = m68k_cpu_has_work;
|
||||
cc->mmu_index = m68k_cpu_mmu_index;
|
||||
cc->dump_state = m68k_cpu_dump_state;
|
||||
cc->set_pc = m68k_cpu_set_pc;
|
||||
cc->get_pc = m68k_cpu_get_pc;
|
||||
|
|
|
@ -577,10 +577,6 @@ enum {
|
|||
/* MMU modes definitions */
|
||||
#define MMU_KERNEL_IDX 0
|
||||
#define MMU_USER_IDX 1
|
||||
static inline int cpu_mmu_index (CPUM68KState *env, bool ifetch)
|
||||
{
|
||||
return (env->sr & SR_S) == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
|
|
|
@ -811,7 +811,7 @@ static void do_cas2l(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2,
|
|||
uint32_t l1, l2;
|
||||
uintptr_t ra = GETPC();
|
||||
#if defined(CONFIG_ATOMIC64)
|
||||
int mmu_idx = cpu_mmu_index(env, 0);
|
||||
int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
|
||||
MemOpIdx oi = make_memop_idx(MO_BEUQ, mmu_idx);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -118,6 +118,22 @@ static bool mb_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
|
||||
static int mb_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPUMBState *env = cpu_env(cs);
|
||||
MicroBlazeCPU *cpu = env_archcpu(env);
|
||||
|
||||
/* Are we in nommu mode?. */
|
||||
if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
|
||||
return MMU_NOMMU_IDX;
|
||||
}
|
||||
|
||||
if (env->msr & MSR_UM) {
|
||||
return MMU_USER_IDX;
|
||||
}
|
||||
return MMU_KERNEL_IDX;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static void mb_cpu_ns_axi_dp(void *opaque, int irq, int level)
|
||||
{
|
||||
|
@ -415,7 +431,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = mb_cpu_class_by_name;
|
||||
cc->has_work = mb_cpu_has_work;
|
||||
|
||||
cc->mmu_index = mb_cpu_mmu_index;
|
||||
cc->dump_state = mb_cpu_dump_state;
|
||||
cc->set_pc = mb_cpu_set_pc;
|
||||
cc->get_pc = mb_cpu_get_pc;
|
||||
|
|
|
@ -434,21 +434,6 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
|
|||
MemTxResult response, uintptr_t retaddr);
|
||||
#endif
|
||||
|
||||
static inline int cpu_mmu_index(CPUMBState *env, bool ifetch)
|
||||
{
|
||||
MicroBlazeCPU *cpu = env_archcpu(env);
|
||||
|
||||
/* Are we in nommu mode?. */
|
||||
if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
|
||||
return MMU_NOMMU_IDX;
|
||||
}
|
||||
|
||||
if (env->msr & MSR_UM) {
|
||||
return MMU_USER_IDX;
|
||||
}
|
||||
return MMU_KERNEL_IDX;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
extern const VMStateDescription vmstate_mb_cpu;
|
||||
#endif
|
||||
|
|
|
@ -228,10 +228,9 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
|
|||
MemTxAttrs *attrs)
|
||||
{
|
||||
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
|
||||
CPUMBState *env = &cpu->env;
|
||||
target_ulong vaddr, paddr = 0;
|
||||
MicroBlazeMMULookup lu;
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = cpu_mmu_index(cs, false);
|
||||
unsigned int hit;
|
||||
|
||||
/* Caller doesn't initialize */
|
||||
|
|
|
@ -305,7 +305,7 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
|
|||
}
|
||||
|
||||
hit = mmu_translate(cpu, &lu, v & TLB_EPN_MASK,
|
||||
0, cpu_mmu_index(env, false));
|
||||
0, cpu_mmu_index(env_cpu(env), false));
|
||||
if (hit) {
|
||||
env->mmu.regs[MMU_R_TLBX] = lu.idx;
|
||||
} else {
|
||||
|
|
|
@ -1607,7 +1607,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
|
|||
dc->ext_imm = dc->base.tb->cs_base;
|
||||
dc->r0 = NULL;
|
||||
dc->r0_set = false;
|
||||
dc->mem_index = cpu_mmu_index(&cpu->env, false);
|
||||
dc->mem_index = cpu_mmu_index(cs, false);
|
||||
dc->jmp_cond = dc->tb_flags & D_FLAG ? TCG_COND_ALWAYS : TCG_COND_NEVER;
|
||||
dc->jmp_dest = -1;
|
||||
|
||||
|
|
|
@ -182,6 +182,11 @@ static bool mips_cpu_has_work(CPUState *cs)
|
|||
return has_work;
|
||||
}
|
||||
|
||||
static int mips_cpu_mmu_index(CPUState *cs, bool ifunc)
|
||||
{
|
||||
return mips_env_mmu_index(cpu_env(cs));
|
||||
}
|
||||
|
||||
#include "cpu-defs.c.inc"
|
||||
|
||||
static void mips_cpu_reset_hold(Object *obj)
|
||||
|
@ -579,6 +584,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
|
|||
|
||||
cc->class_by_name = mips_cpu_class_by_name;
|
||||
cc->has_work = mips_cpu_has_work;
|
||||
cc->mmu_index = mips_cpu_mmu_index;
|
||||
cc->dump_state = mips_cpu_dump_state;
|
||||
cc->set_pc = mips_cpu_set_pc;
|
||||
cc->get_pc = mips_cpu_get_pc;
|
||||
|
|
|
@ -1242,18 +1242,20 @@ uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
|
|||
* MMU modes definitions. We carefully match the indices with our
|
||||
* hflags layout.
|
||||
*/
|
||||
#define MMU_KERNEL_IDX 0
|
||||
#define MMU_USER_IDX 2
|
||||
#define MMU_ERL_IDX 3
|
||||
|
||||
static inline int hflags_mmu_index(uint32_t hflags)
|
||||
{
|
||||
if (hflags & MIPS_HFLAG_ERL) {
|
||||
return 3; /* ERL */
|
||||
return MMU_ERL_IDX;
|
||||
} else {
|
||||
return hflags & MIPS_HFLAG_KSU;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int cpu_mmu_index(CPUMIPSState *env, bool ifetch)
|
||||
static inline int mips_env_mmu_index(CPUMIPSState *env)
|
||||
{
|
||||
return hflags_mmu_index(env->hflags);
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
int prot;
|
||||
|
||||
if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
|
||||
cpu_mmu_index(env, false)) != 0) {
|
||||
mips_env_mmu_index(env)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return phys_addr;
|
||||
|
|
|
@ -8214,7 +8214,7 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
|||
#if !defined(CONFIG_USER_ONLY)
|
||||
#define MEMOP_IDX(DF) \
|
||||
MemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN, \
|
||||
cpu_mmu_index(env, false));
|
||||
mips_env_mmu_index(env));
|
||||
#else
|
||||
#define MEMOP_IDX(DF)
|
||||
#endif
|
||||
|
@ -8323,7 +8323,7 @@ void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
|
|||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = mips_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
|
||||
ensure_writable_pages(env, addr, mmu_idx, ra);
|
||||
|
@ -8337,7 +8337,7 @@ void helper_msa_st_h(CPUMIPSState *env, uint32_t wd,
|
|||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = mips_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
uint64_t d0, d1;
|
||||
|
||||
|
@ -8358,7 +8358,7 @@ void helper_msa_st_w(CPUMIPSState *env, uint32_t wd,
|
|||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = mips_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
uint64_t d0, d1;
|
||||
|
||||
|
@ -8379,7 +8379,7 @@ void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
|
|||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = mips_env_mmu_index(env);
|
||||
uintptr_t ra = GETPC();
|
||||
|
||||
ensure_writable_pages(env, addr, mmu_idx, GETPC());
|
||||
|
|
|
@ -1202,7 +1202,7 @@ void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
|
|||
old, old & env->CP0_Cause & CP0Ca_IP_mask,
|
||||
val, val & env->CP0_Cause & CP0Ca_IP_mask,
|
||||
env->CP0_Cause);
|
||||
switch (cpu_mmu_index(env, false)) {
|
||||
switch (mips_env_mmu_index(env)) {
|
||||
case 3:
|
||||
qemu_log(", ERL\n");
|
||||
break;
|
||||
|
|
|
@ -68,7 +68,7 @@ static void debug_post_eret(CPUMIPSState *env)
|
|||
if (env->hflags & MIPS_HFLAG_DM) {
|
||||
qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
|
||||
}
|
||||
switch (cpu_mmu_index(env, false)) {
|
||||
switch (mips_env_mmu_index(env)) {
|
||||
case 3:
|
||||
qemu_log(", ERL\n");
|
||||
break;
|
||||
|
|
|
@ -623,7 +623,7 @@ static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
|
|||
static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
|
||||
int directory_index, bool *huge_page, bool *hgpg_directory_hit,
|
||||
uint64_t *pw_entrylo0, uint64_t *pw_entrylo1,
|
||||
unsigned directory_shift, unsigned leaf_shift)
|
||||
unsigned directory_shift, unsigned leaf_shift, int ptw_mmu_idx)
|
||||
{
|
||||
int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1;
|
||||
int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F;
|
||||
|
@ -638,8 +638,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,
|
||||
cpu_mmu_index(env, false)) !=
|
||||
TLBRET_MATCH) {
|
||||
ptw_mmu_idx) != TLBRET_MATCH) {
|
||||
/* wrong base address */
|
||||
return 0;
|
||||
}
|
||||
|
@ -666,8 +665,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
|
|||
*pw_entrylo0 = entry;
|
||||
}
|
||||
if (get_physical_address(env, &paddr, &prot, vaddr2, MMU_DATA_LOAD,
|
||||
cpu_mmu_index(env, false)) !=
|
||||
TLBRET_MATCH) {
|
||||
ptw_mmu_idx) != TLBRET_MATCH) {
|
||||
return 0;
|
||||
}
|
||||
if (!get_pte(env, vaddr2, leafentry_size, &entry)) {
|
||||
|
@ -690,7 +688,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
|
|||
}
|
||||
|
||||
static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
|
||||
int mmu_idx)
|
||||
int ptw_mmu_idx)
|
||||
{
|
||||
int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F;
|
||||
int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F;
|
||||
|
@ -776,7 +774,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
|
|||
vaddr |= goffset;
|
||||
switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit,
|
||||
&pw_entrylo0, &pw_entrylo1,
|
||||
directory_shift, leaf_shift))
|
||||
directory_shift, leaf_shift, ptw_mmu_idx))
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
|
@ -793,7 +791,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
|
|||
vaddr |= uoffset;
|
||||
switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit,
|
||||
&pw_entrylo0, &pw_entrylo1,
|
||||
directory_shift, leaf_shift))
|
||||
directory_shift, leaf_shift, ptw_mmu_idx))
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
|
@ -810,7 +808,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
|
|||
vaddr |= moffset;
|
||||
switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit,
|
||||
&pw_entrylo0, &pw_entrylo1,
|
||||
directory_shift, leaf_shift))
|
||||
directory_shift, leaf_shift, ptw_mmu_idx))
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
|
@ -825,8 +823,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
|
|||
/* Leaf Level Page Table - First half of PTE pair */
|
||||
vaddr |= ptoffset0;
|
||||
if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
|
||||
cpu_mmu_index(env, false)) !=
|
||||
TLBRET_MATCH) {
|
||||
ptw_mmu_idx) != TLBRET_MATCH) {
|
||||
return false;
|
||||
}
|
||||
if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) {
|
||||
|
@ -838,8 +835,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
|
|||
/* Leaf Level Page Table - Second half of PTE pair */
|
||||
vaddr |= ptoffset1;
|
||||
if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
|
||||
cpu_mmu_index(env, false)) !=
|
||||
TLBRET_MATCH) {
|
||||
ptw_mmu_idx) != TLBRET_MATCH) {
|
||||
return false;
|
||||
}
|
||||
if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) {
|
||||
|
@ -944,12 +940,10 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||
* Memory reads during hardware page table walking are performed
|
||||
* as if they were kernel-mode load instructions.
|
||||
*/
|
||||
int mode = (env->hflags & MIPS_HFLAG_KSU);
|
||||
bool ret_walker;
|
||||
env->hflags &= ~MIPS_HFLAG_KSU;
|
||||
ret_walker = page_table_walk_refill(env, address, mmu_idx);
|
||||
env->hflags |= mode;
|
||||
if (ret_walker) {
|
||||
int ptw_mmu_idx = (env->hflags & MIPS_HFLAG_ERL ?
|
||||
MMU_ERL_IDX : MMU_KERNEL_IDX);
|
||||
|
||||
if (page_table_walk_refill(env, address, ptw_mmu_idx)) {
|
||||
ret = get_physical_address(env, &physical, &prot, address,
|
||||
access_type, mmu_idx);
|
||||
if (ret == TLBRET_MATCH) {
|
||||
|
@ -979,7 +973,7 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
|
|||
|
||||
/* data access */
|
||||
ret = get_physical_address(env, &physical, &prot, address, access_type,
|
||||
cpu_mmu_index(env, false));
|
||||
mips_env_mmu_index(env));
|
||||
if (ret == TLBRET_MATCH) {
|
||||
return physical;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,12 @@ static bool nios2_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
static int nios2_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return (cpu_env(cs)->ctrl[CR_STATUS] & CR_STATUS_U
|
||||
? MMU_USER_IDX : MMU_SUPERVISOR_IDX);
|
||||
}
|
||||
|
||||
static void nios2_cpu_reset_hold(Object *obj)
|
||||
{
|
||||
CPUState *cs = CPU(obj);
|
||||
|
@ -381,6 +387,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = nios2_cpu_class_by_name;
|
||||
cc->has_work = nios2_cpu_has_work;
|
||||
cc->mmu_index = nios2_cpu_mmu_index;
|
||||
cc->dump_state = nios2_cpu_dump_state;
|
||||
cc->set_pc = nios2_cpu_set_pc;
|
||||
cc->get_pc = nios2_cpu_get_pc;
|
||||
|
|
|
@ -270,12 +270,6 @@ void do_nios2_semihosting(CPUNios2State *env);
|
|||
#define MMU_SUPERVISOR_IDX 0
|
||||
#define MMU_USER_IDX 1
|
||||
|
||||
static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch)
|
||||
{
|
||||
return (env->ctrl[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX :
|
||||
MMU_SUPERVISOR_IDX;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
hwaddr nios2_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
|
|
|
@ -948,7 +948,7 @@ static void nios2_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
|||
Nios2CPU *cpu = env_archcpu(env);
|
||||
int page_insns;
|
||||
|
||||
dc->mem_idx = cpu_mmu_index(env, false);
|
||||
dc->mem_idx = cpu_mmu_index(cs, false);
|
||||
dc->cr_state = cpu->cr_state;
|
||||
dc->tb_flags = dc->base.tb->flags;
|
||||
dc->eic_present = cpu->eic_present;
|
||||
|
|
|
@ -68,6 +68,18 @@ static bool openrisc_cpu_has_work(CPUState *cs)
|
|||
CPU_INTERRUPT_TIMER);
|
||||
}
|
||||
|
||||
static int openrisc_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPUOpenRISCState *env = cpu_env(cs);
|
||||
|
||||
if (env->sr & (ifetch ? SR_IME : SR_DME)) {
|
||||
/* The mmu is enabled; test supervisor state. */
|
||||
return env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
|
||||
}
|
||||
|
||||
return MMU_NOMMU_IDX; /* mmu is disabled */
|
||||
}
|
||||
|
||||
static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info)
|
||||
{
|
||||
info->print_insn = print_insn_or1k;
|
||||
|
@ -239,6 +251,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = openrisc_cpu_class_by_name;
|
||||
cc->has_work = openrisc_cpu_has_work;
|
||||
cc->mmu_index = openrisc_cpu_mmu_index;
|
||||
cc->dump_state = openrisc_cpu_dump_state;
|
||||
cc->set_pc = openrisc_cpu_set_pc;
|
||||
cc->get_pc = openrisc_cpu_get_pc;
|
||||
|
|
|
@ -361,18 +361,6 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, vaddr *pc,
|
|||
| (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE));
|
||||
}
|
||||
|
||||
static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
|
||||
{
|
||||
int ret = MMU_NOMMU_IDX; /* mmu is disabled */
|
||||
|
||||
if (env->sr & (ifetch ? SR_IME : SR_DME)) {
|
||||
/* The mmu is enabled; test supervisor state. */
|
||||
ret = env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env)
|
||||
{
|
||||
return (env->sr
|
||||
|
|
|
@ -1528,7 +1528,7 @@ static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
|
|||
CPUOpenRISCState *env = cpu_env(cs);
|
||||
int bound;
|
||||
|
||||
dc->mem_idx = cpu_mmu_index(env, false);
|
||||
dc->mem_idx = cpu_mmu_index(cs, false);
|
||||
dc->tb_flags = dc->base.tb->flags;
|
||||
dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
|
||||
dc->cpucfgr = env->cpucfgr;
|
||||
|
|
|
@ -1624,7 +1624,7 @@ int ppc_dcr_write(ppc_dcr_t *dcr_env, int dcrn, uint32_t val);
|
|||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_USER_IDX 0
|
||||
static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch)
|
||||
static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return MMU_USER_IDX;
|
||||
|
|
|
@ -7105,6 +7105,11 @@ static bool ppc_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
static int ppc_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return ppc_env_mmu_index(cpu_env(cs), ifetch);
|
||||
}
|
||||
|
||||
static void ppc_cpu_reset_hold(Object *obj)
|
||||
{
|
||||
CPUState *s = CPU(obj);
|
||||
|
@ -7372,6 +7377,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = ppc_cpu_class_by_name;
|
||||
cc->has_work = ppc_cpu_has_work;
|
||||
cc->mmu_index = ppc_cpu_mmu_index;
|
||||
cc->dump_state = ppc_cpu_dump_state;
|
||||
cc->set_pc = ppc_cpu_set_pc;
|
||||
cc->get_pc = ppc_cpu_get_pc;
|
||||
|
@ -7457,7 +7463,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||
qemu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF "
|
||||
"%08x iidx %d didx %d\n",
|
||||
env->msr, env->spr[SPR_HID0], env->hflags,
|
||||
cpu_mmu_index(env, true), cpu_mmu_index(env, false));
|
||||
ppc_env_mmu_index(env, true), ppc_env_mmu_index(env, false));
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (env->tb_env) {
|
||||
qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
|
||||
|
|
|
@ -83,7 +83,7 @@ static void *probe_contiguous(CPUPPCState *env, target_ulong addr, uint32_t nb,
|
|||
void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
|
||||
{
|
||||
uintptr_t raddr = GETPC();
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = ppc_env_mmu_index(env, false);
|
||||
void *host = probe_contiguous(env, addr, (32 - reg) * 4,
|
||||
MMU_DATA_LOAD, mmu_idx, raddr);
|
||||
|
||||
|
@ -105,7 +105,7 @@ void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
|
|||
void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
|
||||
{
|
||||
uintptr_t raddr = GETPC();
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = ppc_env_mmu_index(env, false);
|
||||
void *host = probe_contiguous(env, addr, (32 - reg) * 4,
|
||||
MMU_DATA_STORE, mmu_idx, raddr);
|
||||
|
||||
|
@ -135,7 +135,7 @@ static void do_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
|
|||
return;
|
||||
}
|
||||
|
||||
mmu_idx = cpu_mmu_index(env, false);
|
||||
mmu_idx = ppc_env_mmu_index(env, false);
|
||||
host = probe_contiguous(env, addr, nb, MMU_DATA_LOAD, mmu_idx, raddr);
|
||||
|
||||
if (likely(host)) {
|
||||
|
@ -224,7 +224,7 @@ void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
|
|||
return;
|
||||
}
|
||||
|
||||
mmu_idx = cpu_mmu_index(env, false);
|
||||
mmu_idx = ppc_env_mmu_index(env, false);
|
||||
host = probe_contiguous(env, addr, nb, MMU_DATA_STORE, mmu_idx, raddr);
|
||||
|
||||
if (likely(host)) {
|
||||
|
@ -276,7 +276,7 @@ static void dcbz_common(CPUPPCState *env, target_ulong addr,
|
|||
target_ulong mask, dcbz_size = env->dcache_line_size;
|
||||
uint32_t i;
|
||||
void *haddr;
|
||||
int mmu_idx = epid ? PPC_TLB_EPID_STORE : cpu_mmu_index(env, false);
|
||||
int mmu_idx = epid ? PPC_TLB_EPID_STORE : ppc_env_mmu_index(env, false);
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
/* Check for dcbz vs dcbzl on 970 */
|
||||
|
|
|
@ -1561,9 +1561,9 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
* mapped by code TLBs, so we also try a MMU_INST_FETCH.
|
||||
*/
|
||||
if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
|
||||
cpu_mmu_index(&cpu->env, false), false) ||
|
||||
ppc_env_mmu_index(&cpu->env, false), false) ||
|
||||
ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
|
||||
cpu_mmu_index(&cpu->env, true), false)) {
|
||||
ppc_env_mmu_index(&cpu->env, true), false)) {
|
||||
return raddr & TARGET_PAGE_MASK;
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -867,6 +867,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return riscv_env_mmu_index(cpu_env(cs), ifetch);
|
||||
}
|
||||
|
||||
static void riscv_cpu_reset_hold(Object *obj)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
@ -1810,6 +1815,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
|
|||
|
||||
cc->class_by_name = riscv_cpu_class_by_name;
|
||||
cc->has_work = riscv_cpu_has_work;
|
||||
cc->mmu_index = riscv_cpu_mmu_index;
|
||||
cc->dump_state = riscv_cpu_dump_state;
|
||||
cc->set_pc = riscv_cpu_set_pc;
|
||||
cc->get_pc = riscv_cpu_get_pc;
|
||||
|
|
|
@ -498,7 +498,7 @@ target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
|
|||
void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
|
||||
bool riscv_cpu_vector_enabled(CPURISCVState *env);
|
||||
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
|
||||
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
|
||||
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
|
||||
G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
||||
MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr);
|
||||
|
@ -507,8 +507,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||
bool probe, uintptr_t retaddr);
|
||||
char *riscv_isa_string(RISCVCPU *cpu);
|
||||
|
||||
#define cpu_mmu_index riscv_cpu_mmu_index
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
|
||||
vaddr addr, unsigned size,
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "debug.h"
|
||||
#include "tcg/oversized-guest.h"
|
||||
|
||||
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
|
||||
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return 0;
|
||||
|
@ -106,7 +106,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
|
|||
#else
|
||||
flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
|
||||
|
||||
flags |= cpu_mmu_index(env, 0);
|
||||
flags |= riscv_env_mmu_index(env, 0);
|
||||
fs = get_field(env->mstatus, MSTATUS_FS);
|
||||
vs = get_field(env->mstatus, MSTATUS_VS);
|
||||
|
||||
|
@ -1200,7 +1200,7 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
CPURISCVState *env = &cpu->env;
|
||||
hwaddr phys_addr;
|
||||
int prot;
|
||||
int mmu_idx = cpu_mmu_index(&cpu->env, false);
|
||||
int mmu_idx = riscv_env_mmu_index(&cpu->env, false);
|
||||
|
||||
if (get_physical_address(env, &phys_addr, &prot, addr, NULL, 0, mmu_idx,
|
||||
true, env->virt_enabled, true)) {
|
||||
|
|
|
@ -157,7 +157,7 @@ void helper_cbo_zero(CPURISCVState *env, target_ulong address)
|
|||
{
|
||||
RISCVCPU *cpu = env_archcpu(env);
|
||||
uint16_t cbozlen = cpu->cfg.cboz_blocksize;
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = riscv_env_mmu_index(env, false);
|
||||
uintptr_t ra = GETPC();
|
||||
void *mem;
|
||||
|
||||
|
@ -205,7 +205,7 @@ static void check_zicbom_access(CPURISCVState *env,
|
|||
uintptr_t ra)
|
||||
{
|
||||
RISCVCPU *cpu = env_archcpu(env);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = riscv_env_mmu_index(env, false);
|
||||
uint16_t cbomlen = cpu->cfg.cbom_blocksize;
|
||||
void *phost;
|
||||
int ret;
|
||||
|
|
|
@ -113,14 +113,15 @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
|
|||
{
|
||||
target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
|
||||
target_ulong curlen = MIN(pagelen, len);
|
||||
int mmu_index = riscv_env_mmu_index(env, false);
|
||||
|
||||
probe_access(env, adjust_addr(env, addr), curlen, access_type,
|
||||
cpu_mmu_index(env, false), ra);
|
||||
mmu_index, ra);
|
||||
if (len > curlen) {
|
||||
addr += curlen;
|
||||
curlen = len - curlen;
|
||||
probe_access(env, adjust_addr(env, addr), curlen, access_type,
|
||||
cpu_mmu_index(env, false), ra);
|
||||
mmu_index, ra);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -464,6 +465,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
|
|||
uint32_t esz = 1 << log2_esz;
|
||||
uint32_t vma = vext_vma(desc);
|
||||
target_ulong addr, offset, remain;
|
||||
int mmu_index = riscv_env_mmu_index(env, false);
|
||||
|
||||
/* probe every access */
|
||||
for (i = env->vstart; i < env->vl; i++) {
|
||||
|
@ -478,8 +480,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
|
|||
remain = nf << log2_esz;
|
||||
while (remain > 0) {
|
||||
offset = -(addr | TARGET_PAGE_MASK);
|
||||
host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD,
|
||||
cpu_mmu_index(env, false));
|
||||
host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, mmu_index);
|
||||
if (host) {
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
if (!page_check_range(addr, offset, PAGE_READ)) {
|
||||
|
|
|
@ -64,6 +64,11 @@ static bool rx_cpu_has_work(CPUState *cs)
|
|||
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR);
|
||||
}
|
||||
|
||||
static int riscv_cpu_mmu_index(CPUState *cs, bool ifunc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rx_cpu_reset_hold(Object *obj)
|
||||
{
|
||||
RXCPU *cpu = RX_CPU(obj);
|
||||
|
@ -204,6 +209,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
cc->class_by_name = rx_cpu_class_by_name;
|
||||
cc->has_work = rx_cpu_has_work;
|
||||
cc->mmu_index = riscv_cpu_mmu_index;
|
||||
cc->dump_state = rx_cpu_dump_state;
|
||||
cc->set_pc = rx_cpu_set_pc;
|
||||
cc->get_pc = rx_cpu_get_pc;
|
||||
|
|
|
@ -158,11 +158,6 @@ static inline void cpu_get_tb_cpu_state(CPURXState *env, vaddr *pc,
|
|||
*flags = FIELD_DP32(*flags, PSW, U, env->psw_u);
|
||||
}
|
||||
|
||||
static inline int cpu_mmu_index(CPURXState *env, bool ifetch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t rx_cpu_pack_psw(CPURXState *env)
|
||||
{
|
||||
uint32_t psw = 0;
|
||||
|
|
|
@ -142,6 +142,11 @@ static bool s390_cpu_has_work(CPUState *cs)
|
|||
return s390_cpu_has_int(cpu);
|
||||
}
|
||||
|
||||
static int s390x_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return s390x_env_mmu_index(cpu_env(cs), ifetch);
|
||||
}
|
||||
|
||||
static void s390_query_cpu_fast(CPUState *cpu, CpuInfoFast *value)
|
||||
{
|
||||
S390CPU *s390_cpu = S390_CPU(cpu);
|
||||
|
@ -352,6 +357,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
|
|||
scc->reset = s390_cpu_reset;
|
||||
cc->class_by_name = s390_cpu_class_by_name,
|
||||
cc->has_work = s390_cpu_has_work;
|
||||
cc->mmu_index = s390x_cpu_mmu_index;
|
||||
cc->dump_state = s390_cpu_dump_state;
|
||||
cc->query_cpu_fast = s390_query_cpu_fast;
|
||||
cc->set_pc = s390_cpu_set_pc;
|
||||
|
|
|
@ -381,7 +381,7 @@ extern const VMStateDescription vmstate_s390_cpu;
|
|||
#define MMU_HOME_IDX 2
|
||||
#define MMU_REAL_IDX 3
|
||||
|
||||
static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
|
||||
static inline int s390x_env_mmu_index(CPUS390XState *env, bool ifetch)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return MMU_USER_IDX;
|
||||
|
|
|
@ -358,7 +358,7 @@ static int mmu_idx_from_as(uint8_t as)
|
|||
static uint32_t do_helper_nc(CPUS390XState *env, uint32_t l, uint64_t dest,
|
||||
uint64_t src, uintptr_t ra)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca1, srca2, desta;
|
||||
uint32_t i;
|
||||
uint8_t c = 0;
|
||||
|
@ -392,7 +392,7 @@ uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, uint64_t dest,
|
|||
static uint32_t do_helper_xc(CPUS390XState *env, uint32_t l, uint64_t dest,
|
||||
uint64_t src, uintptr_t ra)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca1, srca2, desta;
|
||||
uint32_t i;
|
||||
uint8_t c = 0;
|
||||
|
@ -433,7 +433,7 @@ uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest,
|
|||
static uint32_t do_helper_oc(CPUS390XState *env, uint32_t l, uint64_t dest,
|
||||
uint64_t src, uintptr_t ra)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca1, srca2, desta;
|
||||
uint32_t i;
|
||||
uint8_t c = 0;
|
||||
|
@ -467,7 +467,7 @@ uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest,
|
|||
static uint32_t do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest,
|
||||
uint64_t src, uintptr_t ra)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca, desta;
|
||||
uint32_t i;
|
||||
|
||||
|
@ -508,7 +508,7 @@ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
|||
/* move right to left */
|
||||
void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t dest, uint64_t src)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
const uint64_t ra = GETPC();
|
||||
S390Access srca, desta;
|
||||
int32_t i;
|
||||
|
@ -529,7 +529,7 @@ void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t dest, uint64_t src)
|
|||
/* move inverse */
|
||||
void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca, desta;
|
||||
uintptr_t ra = GETPC();
|
||||
int i;
|
||||
|
@ -550,7 +550,7 @@ void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
|||
/* move numerics */
|
||||
void HELPER(mvn)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca1, srca2, desta;
|
||||
uintptr_t ra = GETPC();
|
||||
int i;
|
||||
|
@ -572,7 +572,7 @@ void HELPER(mvn)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
|||
/* move with offset */
|
||||
void HELPER(mvo)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
/* MVO always processes one more byte than specified - maximum is 16 */
|
||||
const int len_dest = (l >> 4) + 1;
|
||||
const int len_src = (l & 0xf) + 1;
|
||||
|
@ -606,7 +606,7 @@ void HELPER(mvo)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
|||
/* move zones */
|
||||
void HELPER(mvz)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
S390Access srca1, srca2, desta;
|
||||
uintptr_t ra = GETPC();
|
||||
int i;
|
||||
|
@ -669,7 +669,7 @@ uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
|
|||
|
||||
if (!mask) {
|
||||
/* Recognize access exceptions for the first byte */
|
||||
probe_read(env, addr, 1, cpu_mmu_index(env, false), ra);
|
||||
probe_read(env, addr, 1, s390x_env_mmu_index(env, false), ra);
|
||||
}
|
||||
|
||||
while (mask) {
|
||||
|
@ -893,7 +893,7 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint32_t r1, uint32_t r2)
|
|||
{
|
||||
const uint64_t src = get_address(env, r2) & TARGET_PAGE_MASK;
|
||||
const uint64_t dst = get_address(env, r1) & TARGET_PAGE_MASK;
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
const bool f = extract64(r0, 11, 1);
|
||||
const bool s = extract64(r0, 10, 1);
|
||||
const bool cco = extract64(r0, 8, 1);
|
||||
|
@ -946,7 +946,7 @@ inject_exc:
|
|||
/* string copy */
|
||||
uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
const uint64_t d = get_address(env, r1);
|
||||
const uint64_t s = get_address(env, r2);
|
||||
const uint8_t c = env->regs[0];
|
||||
|
@ -1027,7 +1027,7 @@ static inline uint32_t do_mvcl(CPUS390XState *env,
|
|||
uint64_t *src, uint64_t *srclen,
|
||||
uint16_t pad, int wordsize, uintptr_t ra)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
int len = MIN(*destlen, -(*dest | TARGET_PAGE_MASK));
|
||||
S390Access srca, desta;
|
||||
int i, cc;
|
||||
|
@ -1084,7 +1084,7 @@ static inline uint32_t do_mvcl(CPUS390XState *env,
|
|||
/* move long */
|
||||
uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
const int mmu_idx = cpu_mmu_index(env, false);
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
uintptr_t ra = GETPC();
|
||||
uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
|
||||
uint64_t dest = get_address(env, r1);
|
||||
|
@ -1742,7 +1742,7 @@ uint32_t HELPER(trXX)(CPUS390XState *env, uint32_t r1, uint32_t r2,
|
|||
static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
|
||||
uint64_t a2, bool parallel)
|
||||
{
|
||||
uint32_t mem_idx = cpu_mmu_index(env, false);
|
||||
uint32_t mem_idx = s390x_env_mmu_index(env, false);
|
||||
MemOpIdx oi16 = make_memop_idx(MO_TE | MO_128, mem_idx);
|
||||
MemOpIdx oi8 = make_memop_idx(MO_TE | MO_64, mem_idx);
|
||||
MemOpIdx oi4 = make_memop_idx(MO_TE | MO_32, mem_idx);
|
||||
|
@ -2867,12 +2867,14 @@ uint32_t HELPER(cu42)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
|
|||
void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
|
||||
uintptr_t ra)
|
||||
{
|
||||
const int mmu_idx = s390x_env_mmu_index(env, false);
|
||||
|
||||
/* test the actual access, not just any access to the page due to LAP */
|
||||
while (len) {
|
||||
const uint64_t pagelen = -(addr | TARGET_PAGE_MASK);
|
||||
const uint64_t curlen = MIN(pagelen, len);
|
||||
|
||||
probe_write(env, addr, curlen, cpu_mmu_index(env, false), ra);
|
||||
probe_write(env, addr, curlen, mmu_idx, ra);
|
||||
addr = wrap_address(env, addr + curlen);
|
||||
len -= curlen;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,21 @@ static bool superh_cpu_has_work(CPUState *cs)
|
|||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
static int sh4_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPUSH4State *env = cpu_env(cs);
|
||||
|
||||
/*
|
||||
* The instruction in a RTE delay slot is fetched in privileged mode,
|
||||
* but executed in user mode.
|
||||
*/
|
||||
if (ifetch && (env->flags & TB_FLAG_DELAY_SLOT_RTE)) {
|
||||
return 0;
|
||||
} else {
|
||||
return (env->sr & (1u << SR_MD)) == 0 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void superh_cpu_reset_hold(Object *obj)
|
||||
{
|
||||
CPUState *s = CPU(obj);
|
||||
|
@ -266,6 +281,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = superh_cpu_class_by_name;
|
||||
cc->has_work = superh_cpu_has_work;
|
||||
cc->mmu_index = sh4_cpu_mmu_index;
|
||||
cc->dump_state = superh_cpu_dump_state;
|
||||
cc->set_pc = superh_cpu_set_pc;
|
||||
cc->get_pc = superh_cpu_get_pc;
|
||||
|
|
|
@ -273,16 +273,6 @@ void cpu_load_tlb(CPUSH4State * env);
|
|||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_USER_IDX 1
|
||||
static inline int cpu_mmu_index (CPUSH4State *env, bool ifetch)
|
||||
{
|
||||
/* The instruction in a RTE delay slot is fetched in privileged
|
||||
mode, but executed in user mode. */
|
||||
if (ifetch && (env->flags & TB_FLAG_DELAY_SLOT_RTE)) {
|
||||
return 0;
|
||||
} else {
|
||||
return (env->sr & (1u << SR_MD)) == 0 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
|
|
|
@ -368,7 +368,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "Fujitsu MB86904",
|
||||
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
|
||||
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
|
||||
.fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
|
||||
.mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
|
||||
.mmu_bm = 0x00004000,
|
||||
.mmu_ctpr_mask = 0x00ffffc0,
|
||||
|
@ -381,7 +381,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "Fujitsu MB86907",
|
||||
.iu_version = 0x05 << 24, /* Impl 0, ver 5 */
|
||||
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
|
||||
.fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
|
||||
.mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
|
||||
.mmu_bm = 0x00004000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -394,7 +394,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI MicroSparc I",
|
||||
.iu_version = 0x41000000,
|
||||
.fpu_version = 4 << 17,
|
||||
.fpu_version = 4 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x41000000,
|
||||
.mmu_bm = 0x00004000,
|
||||
.mmu_ctpr_mask = 0x007ffff0,
|
||||
|
@ -407,7 +407,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI MicroSparc II",
|
||||
.iu_version = 0x42000000,
|
||||
.fpu_version = 4 << 17,
|
||||
.fpu_version = 4 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x02000000,
|
||||
.mmu_bm = 0x00004000,
|
||||
.mmu_ctpr_mask = 0x00ffffc0,
|
||||
|
@ -420,7 +420,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI MicroSparc IIep",
|
||||
.iu_version = 0x42000000,
|
||||
.fpu_version = 4 << 17,
|
||||
.fpu_version = 4 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x04000000,
|
||||
.mmu_bm = 0x00004000,
|
||||
.mmu_ctpr_mask = 0x00ffffc0,
|
||||
|
@ -433,7 +433,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI SuperSparc 40", /* STP1020NPGA */
|
||||
.iu_version = 0x41000000, /* SuperSPARC 2.x */
|
||||
.fpu_version = 0 << 17,
|
||||
.fpu_version = 0 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
|
||||
.mmu_bm = 0x00002000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -446,7 +446,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI SuperSparc 50", /* STP1020PGA */
|
||||
.iu_version = 0x40000000, /* SuperSPARC 3.x */
|
||||
.fpu_version = 0 << 17,
|
||||
.fpu_version = 0 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
|
||||
.mmu_bm = 0x00002000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -459,7 +459,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI SuperSparc 51",
|
||||
.iu_version = 0x40000000, /* SuperSPARC 3.x */
|
||||
.fpu_version = 0 << 17,
|
||||
.fpu_version = 0 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
|
||||
.mmu_bm = 0x00002000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -473,7 +473,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI SuperSparc 60", /* STP1020APGA */
|
||||
.iu_version = 0x40000000, /* SuperSPARC 3.x */
|
||||
.fpu_version = 0 << 17,
|
||||
.fpu_version = 0 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
|
||||
.mmu_bm = 0x00002000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -486,7 +486,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI SuperSparc 61",
|
||||
.iu_version = 0x44000000, /* SuperSPARC 3.x */
|
||||
.fpu_version = 0 << 17,
|
||||
.fpu_version = 0 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
|
||||
.mmu_bm = 0x00002000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -500,7 +500,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "TI SuperSparc II",
|
||||
.iu_version = 0x40000000, /* SuperSPARC II 1.x */
|
||||
.fpu_version = 0 << 17,
|
||||
.fpu_version = 0 << FSR_VER_SHIFT,
|
||||
.mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
|
||||
.mmu_bm = 0x00002000,
|
||||
.mmu_ctpr_mask = 0xffffffc0,
|
||||
|
@ -514,7 +514,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "LEON2",
|
||||
.iu_version = 0xf2000000,
|
||||
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
|
||||
.fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
|
||||
.mmu_version = 0xf2000000,
|
||||
.mmu_bm = 0x00004000,
|
||||
.mmu_ctpr_mask = 0x007ffff0,
|
||||
|
@ -527,7 +527,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "LEON3",
|
||||
.iu_version = 0xf3000000,
|
||||
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
|
||||
.fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
|
||||
.mmu_version = 0xf3000000,
|
||||
.mmu_bm = 0x00000000,
|
||||
.mmu_ctpr_mask = 0xfffffffc,
|
||||
|
@ -670,7 +670,7 @@ static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||
env->cansave, env->canrestore, env->otherwin, env->wstate,
|
||||
env->cleanwin, env->nwindows - 1 - env->cwp);
|
||||
qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: %016x\n",
|
||||
env->fsr, env->y, env->fprs);
|
||||
cpu_get_fsr(env), env->y, env->fprs);
|
||||
|
||||
#else
|
||||
qemu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
|
||||
|
@ -679,7 +679,7 @@ static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||
env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
|
||||
env->wim);
|
||||
qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
|
||||
env->fsr, env->y);
|
||||
cpu_get_fsr(env), env->y);
|
||||
#endif
|
||||
qemu_fprintf(f, "\n");
|
||||
}
|
||||
|
@ -718,6 +718,34 @@ static bool sparc_cpu_has_work(CPUState *cs)
|
|||
cpu_interrupts_enabled(env);
|
||||
}
|
||||
|
||||
static int sparc_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
CPUSPARCState *env = cpu_env(cs);
|
||||
|
||||
#ifndef TARGET_SPARC64
|
||||
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
||||
return MMU_PHYS_IDX;
|
||||
} else {
|
||||
return env->psrs;
|
||||
}
|
||||
#else
|
||||
/* IMMU or DMMU disabled. */
|
||||
if (ifetch
|
||||
? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
|
||||
: (env->lsu & DMMU_E) == 0) {
|
||||
return MMU_PHYS_IDX;
|
||||
} else if (cpu_hypervisor_mode(env)) {
|
||||
return MMU_PHYS_IDX;
|
||||
} else if (env->tl > 0) {
|
||||
return MMU_NUCLEUS_IDX;
|
||||
} else if (cpu_supervisor_mode(env)) {
|
||||
return MMU_KERNEL_IDX;
|
||||
} else {
|
||||
return MMU_USER_IDX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *sparc_cpu_type_name(const char *cpu_model)
|
||||
{
|
||||
char *name = g_strdup_printf(SPARC_CPU_TYPE_NAME("%s"), cpu_model);
|
||||
|
@ -758,7 +786,6 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
#endif
|
||||
|
||||
env->version = env->def.iu_version;
|
||||
env->fsr = env->def.fpu_version;
|
||||
env->nwindows = env->def.nwindows;
|
||||
#if !defined(TARGET_SPARC64)
|
||||
env->mmuregs[0] |= env->def.mmu_version;
|
||||
|
@ -770,6 +797,7 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
env->version |= env->def.maxtl << 8;
|
||||
env->version |= env->def.nwindows - 1;
|
||||
#endif
|
||||
cpu_put_fsr(env, 0);
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
|
@ -906,6 +934,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
|
|||
cc->class_by_name = sparc_cpu_class_by_name;
|
||||
cc->parse_features = sparc_cpu_parse_features;
|
||||
cc->has_work = sparc_cpu_has_work;
|
||||
cc->mmu_index = sparc_cpu_mmu_index;
|
||||
cc->dump_state = sparc_cpu_dump_state;
|
||||
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
||||
cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
|
||||
#if !defined(TARGET_SPARC64)
|
||||
#define TARGET_DPREGS 16
|
||||
#define TARGET_FCCREGS 1
|
||||
#else
|
||||
#define TARGET_DPREGS 32
|
||||
#define TARGET_FCCREGS 4
|
||||
#endif
|
||||
|
||||
/*#define EXCP_INTERRUPT 0x100*/
|
||||
|
@ -176,6 +178,7 @@ enum {
|
|||
#define FSR_DZM (1ULL << 24)
|
||||
#define FSR_NXM (1ULL << 23)
|
||||
#define FSR_TEM_MASK (FSR_NVM | FSR_OFM | FSR_UFM | FSR_DZM | FSR_NXM)
|
||||
#define FSR_TEM_SHIFT 23
|
||||
|
||||
#define FSR_NVA (1ULL << 9)
|
||||
#define FSR_OFA (1ULL << 8)
|
||||
|
@ -183,6 +186,7 @@ enum {
|
|||
#define FSR_DZA (1ULL << 6)
|
||||
#define FSR_NXA (1ULL << 5)
|
||||
#define FSR_AEXC_MASK (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
|
||||
#define FSR_AEXC_SHIFT 5
|
||||
|
||||
#define FSR_NVC (1ULL << 4)
|
||||
#define FSR_OFC (1ULL << 3)
|
||||
|
@ -191,31 +195,22 @@ enum {
|
|||
#define FSR_NXC (1ULL << 0)
|
||||
#define FSR_CEXC_MASK (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC)
|
||||
|
||||
#define FSR_VER_SHIFT 17
|
||||
#define FSR_VER_MASK (7 << FSR_VER_SHIFT)
|
||||
|
||||
#define FSR_FTT2 (1ULL << 16)
|
||||
#define FSR_FTT1 (1ULL << 15)
|
||||
#define FSR_FTT0 (1ULL << 14)
|
||||
#define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0)
|
||||
#ifdef TARGET_SPARC64
|
||||
#define FSR_FTT_NMASK 0xfffffffffffe3fffULL
|
||||
#define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL
|
||||
#define FSR_LDFSR_OLDMASK 0x0000003f000fc000ULL
|
||||
#define FSR_LDXFSR_MASK 0x0000003fcfc00fffULL
|
||||
#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL
|
||||
#else
|
||||
#define FSR_FTT_NMASK 0xfffe3fffULL
|
||||
#define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL
|
||||
#define FSR_LDFSR_OLDMASK 0x000fc000ULL
|
||||
#endif
|
||||
#define FSR_LDFSR_MASK 0xcfc00fffULL
|
||||
#define FSR_FTT_IEEE_EXCP (1ULL << 14)
|
||||
#define FSR_FTT_UNIMPFPOP (3ULL << 14)
|
||||
#define FSR_FTT_SEQ_ERROR (4ULL << 14)
|
||||
#define FSR_FTT_INVAL_FPR (6ULL << 14)
|
||||
|
||||
#define FSR_FCC1_SHIFT 11
|
||||
#define FSR_FCC1 (1ULL << FSR_FCC1_SHIFT)
|
||||
#define FSR_FCC0_SHIFT 10
|
||||
#define FSR_FCC0 (1ULL << FSR_FCC0_SHIFT)
|
||||
#define FSR_FCC0_SHIFT 10
|
||||
#define FSR_FCC1_SHIFT 32
|
||||
#define FSR_FCC2_SHIFT 34
|
||||
#define FSR_FCC3_SHIFT 36
|
||||
|
||||
/* MMU */
|
||||
#define MMU_E (1<<0)
|
||||
|
@ -461,7 +456,11 @@ struct CPUArchState {
|
|||
target_ulong cond; /* conditional branch result (XXX: save it in a
|
||||
temporary register when possible) */
|
||||
|
||||
target_ulong fsr; /* FPU state register */
|
||||
/* FPU State Register, in parts */
|
||||
uint32_t fsr; /* rm, tem, aexc */
|
||||
uint32_t fsr_cexc_ftt; /* cexc, ftt */
|
||||
uint32_t fcc[TARGET_FCCREGS]; /* fcc* */
|
||||
|
||||
CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */
|
||||
uint32_t cwp; /* index of current register window (extracted
|
||||
from PSR) */
|
||||
|
@ -509,8 +508,6 @@ struct CPUArchState {
|
|||
uint64_t mmubpregs[4];
|
||||
uint64_t prom_addr;
|
||||
#endif
|
||||
/* temporary float registers */
|
||||
float128 qt0, qt1;
|
||||
float_status fp_status;
|
||||
#if defined(TARGET_SPARC64)
|
||||
#define MAXTL_MAX 8
|
||||
|
@ -619,7 +616,9 @@ void sparc_restore_state_to_opc(CPUState *cs,
|
|||
const TranslationBlock *tb,
|
||||
const uint64_t *data);
|
||||
|
||||
/* cpu-exec.c */
|
||||
/* fop_helper.c */
|
||||
target_ulong cpu_get_fsr(CPUSPARCState *);
|
||||
void cpu_put_fsr(CPUSPARCState *, target_ulong);
|
||||
|
||||
/* win_helper.c */
|
||||
target_ulong cpu_get_psr(CPUSPARCState *env1);
|
||||
|
@ -708,34 +707,6 @@ static inline int cpu_supervisor_mode(CPUSPARCState *env1)
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
|
||||
{
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
return MMU_USER_IDX;
|
||||
#elif !defined(TARGET_SPARC64)
|
||||
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
||||
return MMU_PHYS_IDX;
|
||||
} else {
|
||||
return env->psrs;
|
||||
}
|
||||
#else
|
||||
/* IMMU or DMMU disabled. */
|
||||
if (ifetch
|
||||
? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
|
||||
: (env->lsu & DMMU_E) == 0) {
|
||||
return MMU_PHYS_IDX;
|
||||
} else if (cpu_hypervisor_mode(env)) {
|
||||
return MMU_PHYS_IDX;
|
||||
} else if (env->tl > 0) {
|
||||
return MMU_NUCLEUS_IDX;
|
||||
} else if (cpu_supervisor_mode(env)) {
|
||||
return MMU_KERNEL_IDX;
|
||||
} else {
|
||||
return MMU_USER_IDX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
|
||||
{
|
||||
#if !defined (TARGET_SPARC64)
|
||||
|
@ -783,7 +754,7 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc,
|
|||
uint32_t flags;
|
||||
*pc = env->pc;
|
||||
*cs_base = env->npc;
|
||||
flags = cpu_mmu_index(env, false);
|
||||
flags = cpu_mmu_index(env_cpu(env), false);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (cpu_supervisor_mode(env)) {
|
||||
flags |= TB_FLAG_SUPER;
|
||||
|
|
|
@ -23,13 +23,32 @@
|
|||
#include "exec/helper-proto.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
#define QT0 (env->qt0)
|
||||
#define QT1 (env->qt1)
|
||||
static inline float128 f128_in(Int128 i)
|
||||
{
|
||||
union {
|
||||
Int128 i;
|
||||
float128 f;
|
||||
} u;
|
||||
|
||||
static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
|
||||
u.i = i;
|
||||
return u.f;
|
||||
}
|
||||
|
||||
static inline Int128 f128_ret(float128 f)
|
||||
{
|
||||
union {
|
||||
Int128 i;
|
||||
float128 f;
|
||||
} u;
|
||||
|
||||
u.f = f;
|
||||
return u.i;
|
||||
}
|
||||
|
||||
static void check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
|
||||
{
|
||||
target_ulong status = get_float_exception_flags(&env->fp_status);
|
||||
target_ulong fsr = env->fsr;
|
||||
uint32_t cexc = 0;
|
||||
|
||||
if (unlikely(status)) {
|
||||
/* Keep exception flags clear for next time. */
|
||||
|
@ -37,333 +56,384 @@ static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
|
|||
|
||||
/* Copy IEEE 754 flags into FSR */
|
||||
if (status & float_flag_invalid) {
|
||||
fsr |= FSR_NVC;
|
||||
cexc |= FSR_NVC;
|
||||
}
|
||||
if (status & float_flag_overflow) {
|
||||
fsr |= FSR_OFC;
|
||||
cexc |= FSR_OFC;
|
||||
}
|
||||
if (status & float_flag_underflow) {
|
||||
fsr |= FSR_UFC;
|
||||
cexc |= FSR_UFC;
|
||||
}
|
||||
if (status & float_flag_divbyzero) {
|
||||
fsr |= FSR_DZC;
|
||||
cexc |= FSR_DZC;
|
||||
}
|
||||
if (status & float_flag_inexact) {
|
||||
fsr |= FSR_NXC;
|
||||
cexc |= FSR_NXC;
|
||||
}
|
||||
|
||||
if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) {
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
/* Unmasked exception, generate a trap. Note that while
|
||||
the helper is marked as NO_WG, we can get away with
|
||||
writing to cpu state along the exception path, since
|
||||
TCG generated code will never see the write. */
|
||||
env->fsr = fsr | FSR_FTT_IEEE_EXCP;
|
||||
cs->exception_index = TT_FP_EXCP;
|
||||
cpu_loop_exit_restore(cs, ra);
|
||||
} else {
|
||||
/* Accumulate exceptions */
|
||||
fsr |= (fsr & FSR_CEXC_MASK) << 5;
|
||||
if (cexc & (env->fsr >> FSR_TEM_SHIFT)) {
|
||||
/* Unmasked exception, generate an IEEE trap. */
|
||||
env->fsr_cexc_ftt = cexc | FSR_FTT_IEEE_EXCP;
|
||||
cpu_raise_exception_ra(env, TT_FP_EXCP, ra);
|
||||
}
|
||||
|
||||
/* Accumulate exceptions */
|
||||
env->fsr |= cexc << FSR_AEXC_SHIFT;
|
||||
}
|
||||
|
||||
return fsr;
|
||||
/* No trap, so FTT is cleared. */
|
||||
env->fsr_cexc_ftt = cexc;
|
||||
}
|
||||
|
||||
target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
|
||||
float32 helper_fadds(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
return do_check_ieee_exceptions(env, GETPC());
|
||||
float32 ret = float32_add(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
|
||||
float32 helper_fsubs(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
float32 ret = float32_sub(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define F_BINOP(name) \
|
||||
float32 helper_f ## name ## s (CPUSPARCState *env, float32 src1, \
|
||||
float32 src2) \
|
||||
{ \
|
||||
return float32_ ## name (src1, src2, &env->fp_status); \
|
||||
} \
|
||||
float64 helper_f ## name ## d (CPUSPARCState * env, float64 src1,\
|
||||
float64 src2) \
|
||||
{ \
|
||||
return float64_ ## name (src1, src2, &env->fp_status); \
|
||||
} \
|
||||
F_HELPER(name, q) \
|
||||
{ \
|
||||
QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
|
||||
}
|
||||
float32 helper_fmuls(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
float32 ret = float32_mul(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
F_BINOP(add);
|
||||
F_BINOP(sub);
|
||||
F_BINOP(mul);
|
||||
F_BINOP(div);
|
||||
#undef F_BINOP
|
||||
float32 helper_fdivs(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
float32 ret = float32_div(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_faddd(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
float64 ret = float64_add(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fsubd(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
float64 ret = float64_sub(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fmuld(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
float64 ret = float64_mul(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fdivd(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
float64 ret = float64_div(src1, src2, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
Int128 helper_faddq(CPUSPARCState *env, Int128 src1, Int128 src2)
|
||||
{
|
||||
float128 ret = float128_add(f128_in(src1), f128_in(src2), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
Int128 helper_fsubq(CPUSPARCState *env, Int128 src1, Int128 src2)
|
||||
{
|
||||
float128 ret = float128_sub(f128_in(src1), f128_in(src2), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
Int128 helper_fmulq(CPUSPARCState *env, Int128 src1, Int128 src2)
|
||||
{
|
||||
float128 ret = float128_mul(f128_in(src1), f128_in(src2), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
Int128 helper_fdivq(CPUSPARCState *env, Int128 src1, Int128 src2)
|
||||
{
|
||||
float128 ret = float128_div(f128_in(src1), f128_in(src2), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
return float64_mul(float32_to_float64(src1, &env->fp_status),
|
||||
float32_to_float64(src2, &env->fp_status),
|
||||
&env->fp_status);
|
||||
float64 ret = float64_mul(float32_to_float64(src1, &env->fp_status),
|
||||
float32_to_float64(src2, &env->fp_status),
|
||||
&env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
Int128 helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
QT0 = float128_mul(float64_to_float128(src1, &env->fp_status),
|
||||
float64_to_float128(src2, &env->fp_status),
|
||||
&env->fp_status);
|
||||
float128 ret = float128_mul(float64_to_float128(src1, &env->fp_status),
|
||||
float64_to_float128(src2, &env->fp_status),
|
||||
&env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
float32 helper_fnegs(float32 src)
|
||||
{
|
||||
return float32_chs(src);
|
||||
}
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
float64 helper_fnegd(float64 src)
|
||||
{
|
||||
return float64_chs(src);
|
||||
}
|
||||
|
||||
F_HELPER(neg, q)
|
||||
{
|
||||
QT0 = float128_chs(QT1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Integer to float conversion. */
|
||||
float32 helper_fitos(CPUSPARCState *env, int32_t src)
|
||||
{
|
||||
return int32_to_float32(src, &env->fp_status);
|
||||
float32 ret = int32_to_float32(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fitod(CPUSPARCState *env, int32_t src)
|
||||
{
|
||||
return int32_to_float64(src, &env->fp_status);
|
||||
float64 ret = int32_to_float64(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void helper_fitoq(CPUSPARCState *env, int32_t src)
|
||||
Int128 helper_fitoq(CPUSPARCState *env, int32_t src)
|
||||
{
|
||||
QT0 = int32_to_float128(src, &env->fp_status);
|
||||
float128 ret = int32_to_float128(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
float32 helper_fxtos(CPUSPARCState *env, int64_t src)
|
||||
{
|
||||
return int64_to_float32(src, &env->fp_status);
|
||||
float32 ret = int64_to_float32(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fxtod(CPUSPARCState *env, int64_t src)
|
||||
{
|
||||
return int64_to_float64(src, &env->fp_status);
|
||||
float64 ret = int64_to_float64(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void helper_fxtoq(CPUSPARCState *env, int64_t src)
|
||||
Int128 helper_fxtoq(CPUSPARCState *env, int64_t src)
|
||||
{
|
||||
QT0 = int64_to_float128(src, &env->fp_status);
|
||||
float128 ret = int64_to_float128(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
#endif
|
||||
#undef F_HELPER
|
||||
|
||||
/* floating point conversion */
|
||||
float32 helper_fdtos(CPUSPARCState *env, float64 src)
|
||||
{
|
||||
return float64_to_float32(src, &env->fp_status);
|
||||
float32 ret = float64_to_float32(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fstod(CPUSPARCState *env, float32 src)
|
||||
{
|
||||
return float32_to_float64(src, &env->fp_status);
|
||||
float64 ret = float32_to_float64(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 helper_fqtos(CPUSPARCState *env)
|
||||
float32 helper_fqtos(CPUSPARCState *env, Int128 src)
|
||||
{
|
||||
return float128_to_float32(QT1, &env->fp_status);
|
||||
float32 ret = float128_to_float32(f128_in(src), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void helper_fstoq(CPUSPARCState *env, float32 src)
|
||||
Int128 helper_fstoq(CPUSPARCState *env, float32 src)
|
||||
{
|
||||
QT0 = float32_to_float128(src, &env->fp_status);
|
||||
float128 ret = float32_to_float128(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
float64 helper_fqtod(CPUSPARCState *env)
|
||||
float64 helper_fqtod(CPUSPARCState *env, Int128 src)
|
||||
{
|
||||
return float128_to_float64(QT1, &env->fp_status);
|
||||
float64 ret = float128_to_float64(f128_in(src), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void helper_fdtoq(CPUSPARCState *env, float64 src)
|
||||
Int128 helper_fdtoq(CPUSPARCState *env, float64 src)
|
||||
{
|
||||
QT0 = float64_to_float128(src, &env->fp_status);
|
||||
float128 ret = float64_to_float128(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
/* Float to integer conversion. */
|
||||
int32_t helper_fstoi(CPUSPARCState *env, float32 src)
|
||||
{
|
||||
return float32_to_int32_round_to_zero(src, &env->fp_status);
|
||||
int32_t ret = float32_to_int32_round_to_zero(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t helper_fdtoi(CPUSPARCState *env, float64 src)
|
||||
{
|
||||
return float64_to_int32_round_to_zero(src, &env->fp_status);
|
||||
int32_t ret = float64_to_int32_round_to_zero(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t helper_fqtoi(CPUSPARCState *env)
|
||||
int32_t helper_fqtoi(CPUSPARCState *env, Int128 src)
|
||||
{
|
||||
return float128_to_int32_round_to_zero(QT1, &env->fp_status);
|
||||
int32_t ret = float128_to_int32_round_to_zero(f128_in(src),
|
||||
&env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
int64_t helper_fstox(CPUSPARCState *env, float32 src)
|
||||
{
|
||||
return float32_to_int64_round_to_zero(src, &env->fp_status);
|
||||
int64_t ret = float32_to_int64_round_to_zero(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t helper_fdtox(CPUSPARCState *env, float64 src)
|
||||
{
|
||||
return float64_to_int64_round_to_zero(src, &env->fp_status);
|
||||
int64_t ret = float64_to_int64_round_to_zero(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t helper_fqtox(CPUSPARCState *env)
|
||||
int64_t helper_fqtox(CPUSPARCState *env, Int128 src)
|
||||
{
|
||||
return float128_to_int64_round_to_zero(QT1, &env->fp_status);
|
||||
}
|
||||
#endif
|
||||
|
||||
float32 helper_fabss(float32 src)
|
||||
{
|
||||
return float32_abs(src);
|
||||
}
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
float64 helper_fabsd(float64 src)
|
||||
{
|
||||
return float64_abs(src);
|
||||
}
|
||||
|
||||
void helper_fabsq(CPUSPARCState *env)
|
||||
{
|
||||
QT0 = float128_abs(QT1);
|
||||
int64_t ret = float128_to_int64_round_to_zero(f128_in(src),
|
||||
&env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
float32 helper_fsqrts(CPUSPARCState *env, float32 src)
|
||||
{
|
||||
return float32_sqrt(src, &env->fp_status);
|
||||
float32 ret = float32_sqrt(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 helper_fsqrtd(CPUSPARCState *env, float64 src)
|
||||
{
|
||||
return float64_sqrt(src, &env->fp_status);
|
||||
float64 ret = float64_sqrt(src, &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void helper_fsqrtq(CPUSPARCState *env)
|
||||
Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
|
||||
{
|
||||
QT0 = float128_sqrt(QT1, &env->fp_status);
|
||||
float128 ret = float128_sqrt(f128_in(src), &env->fp_status);
|
||||
check_ieee_exceptions(env, GETPC());
|
||||
return f128_ret(ret);
|
||||
}
|
||||
|
||||
#define GEN_FCMP(name, size, reg1, reg2, FS, E) \
|
||||
target_ulong glue(helper_, name) (CPUSPARCState *env) \
|
||||
{ \
|
||||
FloatRelation ret; \
|
||||
target_ulong fsr; \
|
||||
if (E) { \
|
||||
ret = glue(size, _compare)(reg1, reg2, &env->fp_status); \
|
||||
} else { \
|
||||
ret = glue(size, _compare_quiet)(reg1, reg2, \
|
||||
&env->fp_status); \
|
||||
} \
|
||||
fsr = do_check_ieee_exceptions(env, GETPC()); \
|
||||
switch (ret) { \
|
||||
case float_relation_unordered: \
|
||||
fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
|
||||
fsr |= FSR_NVA; \
|
||||
break; \
|
||||
case float_relation_less: \
|
||||
fsr &= ~(FSR_FCC1) << FS; \
|
||||
fsr |= FSR_FCC0 << FS; \
|
||||
break; \
|
||||
case float_relation_greater: \
|
||||
fsr &= ~(FSR_FCC0) << FS; \
|
||||
fsr |= FSR_FCC1 << FS; \
|
||||
break; \
|
||||
default: \
|
||||
fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
break; \
|
||||
} \
|
||||
return fsr; \
|
||||
}
|
||||
#define GEN_FCMP_T(name, size, FS, E) \
|
||||
target_ulong glue(helper_, name)(CPUSPARCState *env, size src1, size src2)\
|
||||
{ \
|
||||
FloatRelation ret; \
|
||||
target_ulong fsr; \
|
||||
if (E) { \
|
||||
ret = glue(size, _compare)(src1, src2, &env->fp_status); \
|
||||
} else { \
|
||||
ret = glue(size, _compare_quiet)(src1, src2, \
|
||||
&env->fp_status); \
|
||||
} \
|
||||
fsr = do_check_ieee_exceptions(env, GETPC()); \
|
||||
switch (ret) { \
|
||||
case float_relation_unordered: \
|
||||
fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
|
||||
break; \
|
||||
case float_relation_less: \
|
||||
fsr &= ~(FSR_FCC1 << FS); \
|
||||
fsr |= FSR_FCC0 << FS; \
|
||||
break; \
|
||||
case float_relation_greater: \
|
||||
fsr &= ~(FSR_FCC0 << FS); \
|
||||
fsr |= FSR_FCC1 << FS; \
|
||||
break; \
|
||||
default: \
|
||||
fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
break; \
|
||||
} \
|
||||
return fsr; \
|
||||
static uint32_t finish_fcmp(CPUSPARCState *env, FloatRelation r, uintptr_t ra)
|
||||
{
|
||||
check_ieee_exceptions(env, ra);
|
||||
|
||||
/*
|
||||
* FCC values:
|
||||
* 0 =
|
||||
* 1 <
|
||||
* 2 >
|
||||
* 3 unordered
|
||||
*/
|
||||
switch (r) {
|
||||
case float_relation_equal:
|
||||
return 0;
|
||||
case float_relation_less:
|
||||
return 1;
|
||||
case float_relation_greater:
|
||||
return 2;
|
||||
case float_relation_unordered:
|
||||
env->fsr |= FSR_NVA;
|
||||
return 3;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
GEN_FCMP_T(fcmps, float32, 0, 0);
|
||||
GEN_FCMP_T(fcmpd, float64, 0, 0);
|
||||
uint32_t helper_fcmps(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
FloatRelation r = float32_compare_quiet(src1, src2, &env->fp_status);
|
||||
return finish_fcmp(env, r, GETPC());
|
||||
}
|
||||
|
||||
GEN_FCMP_T(fcmpes, float32, 0, 1);
|
||||
GEN_FCMP_T(fcmped, float64, 0, 1);
|
||||
uint32_t helper_fcmpes(CPUSPARCState *env, float32 src1, float32 src2)
|
||||
{
|
||||
FloatRelation r = float32_compare(src1, src2, &env->fp_status);
|
||||
return finish_fcmp(env, r, GETPC());
|
||||
}
|
||||
|
||||
GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
|
||||
GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
|
||||
uint32_t helper_fcmpd(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
FloatRelation r = float64_compare_quiet(src1, src2, &env->fp_status);
|
||||
return finish_fcmp(env, r, GETPC());
|
||||
}
|
||||
|
||||
uint32_t helper_fcmped(CPUSPARCState *env, float64 src1, float64 src2)
|
||||
{
|
||||
FloatRelation r = float64_compare(src1, src2, &env->fp_status);
|
||||
return finish_fcmp(env, r, GETPC());
|
||||
}
|
||||
|
||||
uint32_t helper_fcmpq(CPUSPARCState *env, Int128 src1, Int128 src2)
|
||||
{
|
||||
FloatRelation r = float128_compare_quiet(f128_in(src1), f128_in(src2),
|
||||
&env->fp_status);
|
||||
return finish_fcmp(env, r, GETPC());
|
||||
}
|
||||
|
||||
uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
|
||||
{
|
||||
FloatRelation r = float128_compare(f128_in(src1), f128_in(src2),
|
||||
&env->fp_status);
|
||||
return finish_fcmp(env, r, GETPC());
|
||||
}
|
||||
|
||||
target_ulong cpu_get_fsr(CPUSPARCState *env)
|
||||
{
|
||||
target_ulong fsr = env->fsr | env->fsr_cexc_ftt;
|
||||
|
||||
fsr |= env->fcc[0] << FSR_FCC0_SHIFT;
|
||||
#ifdef TARGET_SPARC64
|
||||
GEN_FCMP_T(fcmps_fcc1, float32, 22, 0);
|
||||
GEN_FCMP_T(fcmpd_fcc1, float64, 22, 0);
|
||||
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
|
||||
|
||||
GEN_FCMP_T(fcmps_fcc2, float32, 24, 0);
|
||||
GEN_FCMP_T(fcmpd_fcc2, float64, 24, 0);
|
||||
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
|
||||
|
||||
GEN_FCMP_T(fcmps_fcc3, float32, 26, 0);
|
||||
GEN_FCMP_T(fcmpd_fcc3, float64, 26, 0);
|
||||
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
|
||||
|
||||
GEN_FCMP_T(fcmpes_fcc1, float32, 22, 1);
|
||||
GEN_FCMP_T(fcmped_fcc1, float64, 22, 1);
|
||||
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
|
||||
|
||||
GEN_FCMP_T(fcmpes_fcc2, float32, 24, 1);
|
||||
GEN_FCMP_T(fcmped_fcc2, float64, 24, 1);
|
||||
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
|
||||
|
||||
GEN_FCMP_T(fcmpes_fcc3, float32, 26, 1);
|
||||
GEN_FCMP_T(fcmped_fcc3, float64, 26, 1);
|
||||
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
|
||||
fsr |= (uint64_t)env->fcc[1] << FSR_FCC1_SHIFT;
|
||||
fsr |= (uint64_t)env->fcc[2] << FSR_FCC2_SHIFT;
|
||||
fsr |= (uint64_t)env->fcc[3] << FSR_FCC3_SHIFT;
|
||||
#endif
|
||||
#undef GEN_FCMP_T
|
||||
#undef GEN_FCMP
|
||||
|
||||
static void set_fsr(CPUSPARCState *env, target_ulong fsr)
|
||||
/* VER is kept completely separate until re-assembly. */
|
||||
fsr |= env->def.fpu_version;
|
||||
|
||||
return fsr;
|
||||
}
|
||||
|
||||
target_ulong helper_get_fsr(CPUSPARCState *env)
|
||||
{
|
||||
return cpu_get_fsr(env);
|
||||
}
|
||||
|
||||
static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
|
||||
{
|
||||
int rnd_mode;
|
||||
|
||||
env->fsr = fsr & (FSR_RD_MASK | FSR_TEM_MASK | FSR_AEXC_MASK);
|
||||
|
||||
switch (fsr & FSR_RD_MASK) {
|
||||
case FSR_RD_NEAREST:
|
||||
rnd_mode = float_round_nearest_even;
|
||||
|
@ -382,7 +452,23 @@ static void set_fsr(CPUSPARCState *env, target_ulong fsr)
|
|||
set_float_rounding_mode(rnd_mode, &env->fp_status);
|
||||
}
|
||||
|
||||
void helper_set_fsr(CPUSPARCState *env, target_ulong fsr)
|
||||
void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
|
||||
{
|
||||
set_fsr(env, fsr);
|
||||
env->fsr_cexc_ftt = fsr & (FSR_CEXC_MASK | FSR_FTT_MASK);
|
||||
|
||||
env->fcc[0] = extract32(fsr, FSR_FCC0_SHIFT, 2);
|
||||
#ifdef TARGET_SPARC64
|
||||
env->fcc[1] = extract64(fsr, FSR_FCC1_SHIFT, 2);
|
||||
env->fcc[2] = extract64(fsr, FSR_FCC2_SHIFT, 2);
|
||||
env->fcc[3] = extract64(fsr, FSR_FCC3_SHIFT, 2);
|
||||
#endif
|
||||
|
||||
set_fsr_nonsplit(env, fsr);
|
||||
}
|
||||
|
||||
void helper_set_fsr_nofcc_noftt(CPUSPARCState *env, uint32_t fsr)
|
||||
{
|
||||
env->fsr_cexc_ftt &= FSR_FTT_MASK;
|
||||
env->fsr_cexc_ftt |= fsr & FSR_CEXC_MASK;
|
||||
set_fsr_nonsplit(env, fsr);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
case 69:
|
||||
return gdb_get_rega(mem_buf, env->npc);
|
||||
case 70:
|
||||
return gdb_get_rega(mem_buf, env->fsr);
|
||||
return gdb_get_rega(mem_buf, cpu_get_fsr(env));
|
||||
case 71:
|
||||
return gdb_get_rega(mem_buf, 0); /* csr */
|
||||
default:
|
||||
|
@ -94,7 +94,7 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
((env->pstate & 0xfff) << 8) |
|
||||
cpu_get_cwp64(env));
|
||||
case 83:
|
||||
return gdb_get_regl(mem_buf, env->fsr);
|
||||
return gdb_get_regl(mem_buf, cpu_get_fsr(env));
|
||||
case 84:
|
||||
return gdb_get_regl(mem_buf, env->fprs);
|
||||
case 85:
|
||||
|
@ -156,7 +156,7 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
env->npc = tmp;
|
||||
break;
|
||||
case 70:
|
||||
env->fsr = tmp;
|
||||
cpu_put_fsr(env, tmp);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -191,7 +191,7 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
cpu_put_cwp64(env, tmp & 0xff);
|
||||
break;
|
||||
case 83:
|
||||
env->fsr = tmp;
|
||||
cpu_put_fsr(env, tmp);
|
||||
break;
|
||||
case 84:
|
||||
env->fprs = tmp;
|
||||
|
|
|
@ -35,87 +35,60 @@ DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
|
|||
DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
|
||||
DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_2(set_fsr, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32)
|
||||
DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, f32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_RWG, f64, env, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_1(fsqrtq, TCG_CALL_NO_RWG, void, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpq, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpeq, TCG_CALL_NO_WG, tl, env)
|
||||
#ifdef TARGET_SPARC64
|
||||
DEF_HELPER_FLAGS_1(fabsd, TCG_CALL_NO_RWG_SE, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmpd_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmpd_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmpd_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmpes_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmpes_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_1(fabsq, TCG_CALL_NO_RWG, void, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpeq_fcc1, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_1(get_fsr, TCG_CALL_NO_WG_SE, tl, env)
|
||||
DEF_HELPER_FLAGS_2(set_fsr_nofcc_noftt, TCG_CALL_NO_RWG, void, env, i32)
|
||||
DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_WG, f32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_WG, f64, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fsqrtq, TCG_CALL_NO_WG, i128, env, i128)
|
||||
DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, i32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, i32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
|
||||
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
|
||||
DEF_HELPER_2(raise_exception, noreturn, env, int)
|
||||
#define F_HELPER_0_1(name) \
|
||||
DEF_HELPER_FLAGS_1(f ## name, TCG_CALL_NO_RWG, void, env)
|
||||
|
||||
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
F_HELPER_0_1(addq)
|
||||
F_HELPER_0_1(subq)
|
||||
F_HELPER_0_1(mulq)
|
||||
F_HELPER_0_1(divq)
|
||||
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(faddq, TCG_CALL_NO_WG, i128, env, i128, i128)
|
||||
DEF_HELPER_FLAGS_3(fsubq, TCG_CALL_NO_WG, i128, env, i128, i128)
|
||||
DEF_HELPER_FLAGS_3(fmulq, TCG_CALL_NO_WG, i128, env, i128, i128)
|
||||
DEF_HELPER_FLAGS_3(fdivq, TCG_CALL_NO_WG, i128, env, i128, i128)
|
||||
|
||||
DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, void, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_WG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32)
|
||||
|
||||
DEF_HELPER_FLAGS_1(fnegs, TCG_CALL_NO_RWG_SE, f32, f32)
|
||||
DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
|
||||
DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, void, env, s32)
|
||||
DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_WG, f64, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_WG, i128, env, f64, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32)
|
||||
DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_WG, f64, env, s32)
|
||||
DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_WG, i128, env, s32)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_WG, f32, env, s32)
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
DEF_HELPER_FLAGS_1(fnegd, TCG_CALL_NO_RWG_SE, f64, f64)
|
||||
DEF_HELPER_FLAGS_1(fnegq, TCG_CALL_NO_RWG, void, env)
|
||||
DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_RWG, f32, env, s64)
|
||||
DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_RWG, f64, env, s64)
|
||||
DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
|
||||
DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_WG, f32, env, s64)
|
||||
DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_WG, f64, env, s64)
|
||||
DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_WG, i128, env, s64)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
|
||||
DEF_HELPER_FLAGS_1(fqtos, TCG_CALL_NO_RWG, f32, env)
|
||||
DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, void, env, f32)
|
||||
DEF_HELPER_FLAGS_1(fqtod, TCG_CALL_NO_RWG, f64, env)
|
||||
DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64)
|
||||
DEF_HELPER_FLAGS_1(fqtoi, TCG_CALL_NO_RWG, s32, env)
|
||||
DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_WG, f32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_WG, f64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_WG, f32, env, i128)
|
||||
DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_WG, i128, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fqtod, TCG_CALL_NO_WG, f64, env, i128)
|
||||
DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_WG, i128, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_WG, s32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_WG, s32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fqtoi, TCG_CALL_NO_WG, s32, env, i128)
|
||||
#ifdef TARGET_SPARC64
|
||||
DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_RWG, s64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_RWG, s64, env, f64)
|
||||
DEF_HELPER_FLAGS_1(fqtox, TCG_CALL_NO_RWG, s64, env)
|
||||
DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_WG, s64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_WG, s64, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_WG, s64, env, i128)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
@ -141,6 +114,5 @@ VIS_CMPHELPER(cmpeq)
|
|||
VIS_CMPHELPER(cmple)
|
||||
VIS_CMPHELPER(cmpne)
|
||||
#endif
|
||||
#undef F_HELPER_0_1
|
||||
#undef VIS_HELPER
|
||||
#undef VIS_CMPHELPER
|
||||
|
|
|
@ -66,9 +66,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define QT0 (env->qt0)
|
||||
#define QT1 (env->qt1)
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
||||
/* Calculates TSB pointer value for fault page size
|
||||
* UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers
|
||||
|
@ -690,7 +687,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
|
|||
case ASI_M_IODIAG: /* Turbosparc IOTLB Diagnostic */
|
||||
break;
|
||||
case ASI_KERNELTXT: /* Supervisor code access */
|
||||
oi = make_memop_idx(memop, cpu_mmu_index(env, true));
|
||||
oi = make_memop_idx(memop, cpu_mmu_index(env_cpu(env), true));
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = cpu_ldb_code_mmu(env, addr, oi, GETPC());
|
||||
|
|
|
@ -83,6 +83,32 @@ static const VMStateInfo vmstate_psr = {
|
|||
.put = put_psr,
|
||||
};
|
||||
|
||||
static int get_fsr(QEMUFile *f, void *opaque, size_t size,
|
||||
const VMStateField *field)
|
||||
{
|
||||
SPARCCPU *cpu = opaque;
|
||||
target_ulong val = qemu_get_betl(f);
|
||||
|
||||
cpu_put_fsr(&cpu->env, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int put_fsr(QEMUFile *f, void *opaque, size_t size,
|
||||
const VMStateField *field, JSONWriter *vmdesc)
|
||||
{
|
||||
SPARCCPU *cpu = opaque;
|
||||
target_ulong val = cpu_get_fsr(&cpu->env);
|
||||
|
||||
qemu_put_betl(f, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateInfo vmstate_fsr = {
|
||||
.name = "fsr",
|
||||
.get = get_fsr,
|
||||
.put = put_fsr,
|
||||
};
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
static int get_xcc(QEMUFile *f, void *opaque, size_t size,
|
||||
const VMStateField *field)
|
||||
|
@ -157,7 +183,6 @@ const VMStateDescription vmstate_sparc_cpu = {
|
|||
VMSTATE_UINTTL(env.npc, SPARCCPU),
|
||||
VMSTATE_UINTTL(env.y, SPARCCPU),
|
||||
{
|
||||
|
||||
.name = "psr",
|
||||
.version_id = 0,
|
||||
.size = sizeof(uint32_t),
|
||||
|
@ -165,7 +190,14 @@ const VMStateDescription vmstate_sparc_cpu = {
|
|||
.flags = VMS_SINGLE,
|
||||
.offset = 0,
|
||||
},
|
||||
VMSTATE_UINTTL(env.fsr, SPARCCPU),
|
||||
{
|
||||
.name = "fsr",
|
||||
.version_id = 0,
|
||||
.size = sizeof(target_ulong),
|
||||
.info = &vmstate_fsr,
|
||||
.flags = VMS_SINGLE,
|
||||
.offset = 0,
|
||||
},
|
||||
VMSTATE_UINTTL(env.tbr, SPARCCPU),
|
||||
VMSTATE_INT32(env.interrupt_index, SPARCCPU),
|
||||
VMSTATE_UINT32(env.pil_in, SPARCCPU),
|
||||
|
|
|
@ -901,7 +901,7 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
SPARCCPU *cpu = SPARC_CPU(cs);
|
||||
CPUSPARCState *env = &cpu->env;
|
||||
hwaddr phys_addr;
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
int mmu_idx = cpu_mmu_index(cs, false);
|
||||
|
||||
if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
|
||||
if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -89,6 +89,11 @@ static bool tricore_cpu_has_work(CPUState *cs)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int tricore_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
|
@ -194,6 +199,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
|
|||
&mcc->parent_phases);
|
||||
cc->class_by_name = tricore_cpu_class_by_name;
|
||||
cc->has_work = tricore_cpu_has_work;
|
||||
cc->mmu_index = tricore_cpu_mmu_index;
|
||||
|
||||
cc->gdb_read_register = tricore_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = tricore_cpu_gdb_write_register;
|
||||
|
|
|
@ -246,11 +246,6 @@ void fpu_set_state(CPUTriCoreState *env);
|
|||
|
||||
#define MMU_USER_IDX 2
|
||||
|
||||
static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
FIELD(TB_FLAGS, PRIV, 0, 2)
|
||||
|
|
|
@ -48,7 +48,7 @@ hwaddr tricore_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
TriCoreCPU *cpu = TRICORE_CPU(cs);
|
||||
hwaddr phys_addr;
|
||||
int prot;
|
||||
int mmu_idx = cpu_mmu_index(&cpu->env, false);
|
||||
int mmu_idx = cpu_mmu_index(cs, false);
|
||||
|
||||
if (get_physical_address(&cpu->env, &phys_addr, &prot, addr,
|
||||
MMU_DATA_LOAD, mmu_idx)) {
|
||||
|
|
|
@ -8355,7 +8355,7 @@ static void tricore_tr_init_disas_context(DisasContextBase *dcbase,
|
|||
{
|
||||
DisasContext *ctx = container_of(dcbase, DisasContext, base);
|
||||
CPUTriCoreState *env = cpu_env(cs);
|
||||
ctx->mem_idx = cpu_mmu_index(env, false);
|
||||
ctx->mem_idx = cpu_mmu_index(cs, false);
|
||||
|
||||
uint32_t tb_flags = (uint32_t)ctx->base.tb->flags;
|
||||
ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
|
||||
|
|
|
@ -74,6 +74,11 @@ static bool xtensa_cpu_has_work(CPUState *cs)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int xtensa_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||
{
|
||||
return xtensa_get_cring(cpu_env(cs));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static bool abi_call0;
|
||||
|
||||
|
@ -252,6 +257,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
cc->class_by_name = xtensa_cpu_class_by_name;
|
||||
cc->has_work = xtensa_cpu_has_work;
|
||||
cc->mmu_index = xtensa_cpu_mmu_index;
|
||||
cc->dump_state = xtensa_cpu_dump_state;
|
||||
cc->set_pc = xtensa_cpu_set_pc;
|
||||
cc->get_pc = xtensa_cpu_get_pc;
|
||||
|
|
|
@ -713,11 +713,6 @@ static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
|
|||
/* MMU modes definitions */
|
||||
#define MMU_USER_IDX 3
|
||||
|
||||
static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
|
||||
{
|
||||
return xtensa_get_cring(env);
|
||||
}
|
||||
|
||||
#define XTENSA_TBFLAG_RING_MASK 0x3
|
||||
#define XTENSA_TBFLAG_EXCM 0x4
|
||||
#define XTENSA_TBFLAG_LITBASE 0x8
|
||||
|
|
|
@ -66,7 +66,7 @@ void HELPER(itlb_hit_test)(CPUXtensaState *env, uint32_t vaddr)
|
|||
* only the side-effects (ie any MMU or other exception)
|
||||
*/
|
||||
probe_access(env, vaddr, 1, MMU_INST_FETCH,
|
||||
cpu_mmu_index(env, true), GETPC());
|
||||
cpu_mmu_index(env_cpu(env), true), GETPC());
|
||||
}
|
||||
|
||||
void HELPER(wsr_rasid)(CPUXtensaState *env, uint32_t v)
|
||||
|
|
|
@ -2327,7 +2327,7 @@ static void tcg_target_init(TCGContext *s)
|
|||
tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
|
||||
tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
|
||||
|
||||
tcg_target_call_clobber_regs = ALL_GENERAL_REGS;
|
||||
tcg_target_call_clobber_regs = ALL_GENERAL_REGS | ALL_VECTOR_REGS;
|
||||
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
|
||||
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
|
||||
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
|
||||
|
|
|
@ -20,7 +20,7 @@ def probe_proc_self_mem():
|
|||
|
||||
def run_test():
|
||||
"""Run through the tests one by one"""
|
||||
if not probe_proc_self_mem:
|
||||
if not probe_proc_self_mem():
|
||||
print("SKIP: /proc/self/mem is not usable")
|
||||
exit(0)
|
||||
gdb.Breakpoint("break_here")
|
||||
|
|
Loading…
Reference in New Issue