diff options
Diffstat (limited to 'target/sparc')
-rw-r--r-- | target/sparc/cpu.c | 63 | ||||
-rw-r--r-- | target/sparc/cpu.h | 43 | ||||
-rw-r--r-- | target/sparc/int32_helper.c | 2 | ||||
-rw-r--r-- | target/sparc/ldst_helper.c | 3 | ||||
-rw-r--r-- | target/sparc/translate.c | 32 | ||||
-rw-r--r-- | target/sparc/translate.h | 17 |
6 files changed, 88 insertions, 72 deletions
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index a65a646..373a335 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -23,10 +23,12 @@ #include "qemu/module.h" #include "qemu/qemu-print.h" #include "exec/exec-all.h" +#include "exec/translation-block.h" #include "hw/qdev-properties.h" #include "qapi/visitor.h" #include "tcg/tcg.h" #include "fpu/softfloat.h" +#include "target/sparc/translate.h" //#define DEBUG_FEATURES @@ -713,6 +715,67 @@ static void sparc_cpu_synchronize_from_tb(CPUState *cs, cpu->env.npc = tb->cs_base; } +void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc, + uint64_t *cs_base, uint32_t *pflags) +{ + uint32_t flags; + *pc = env->pc; + *cs_base = env->npc; + flags = cpu_mmu_index(env_cpu(env), false); +#ifndef CONFIG_USER_ONLY + if (cpu_supervisor_mode(env)) { + flags |= TB_FLAG_SUPER; + } +#endif +#ifdef TARGET_SPARC64 +#ifndef CONFIG_USER_ONLY + if (cpu_hypervisor_mode(env)) { + flags |= TB_FLAG_HYPER; + } +#endif + if (env->pstate & PS_AM) { + flags |= TB_FLAG_AM_ENABLED; + } + if ((env->pstate & PS_PEF) && (env->fprs & FPRS_FEF)) { + flags |= TB_FLAG_FPU_ENABLED; + } + flags |= env->asi << TB_FLAG_ASI_SHIFT; +#else + if (env->psref) { + flags |= TB_FLAG_FPU_ENABLED; + } +#ifndef CONFIG_USER_ONLY + if (env->fsr_qne) { + flags |= TB_FLAG_FSR_QNE; + } +#endif /* !CONFIG_USER_ONLY */ +#endif /* TARGET_SPARC64 */ + *pflags = flags; +} + +static void sparc_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + CPUSPARCState *env = cpu_env(cs); + target_ulong pc = data[0]; + target_ulong npc = data[1]; + + env->pc = pc; + if (npc == DYNAMIC_PC) { + /* dynamic NPC: already stored */ + } else if (npc & JUMP_PC) { + /* jump PC: use 'cond' and the jump targets of the translation */ + if (env->cond) { + env->npc = npc & ~3; + } else { + env->npc = pc + 4; + } + } else { + env->npc = npc; + } +} + static bool sparc_cpu_has_work(CPUState *cs) { return (cs->interrupt_request & CPU_INTERRUPT_HARD) && diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index f517e5a..5c98123 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -607,12 +607,8 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, uint8_t *buf, int len, bool is_write); #endif - /* translate.c */ void sparc_tcg_init(void); -void sparc_restore_state_to_opc(CPUState *cs, - const TranslationBlock *tb, - const uint64_t *data); /* fop_helper.c */ target_ulong cpu_get_fsr(CPUSPARCState *); @@ -747,43 +743,8 @@ trap_state* cpu_tsptr(CPUSPARCState* env); #define TB_FLAG_FSR_QNE (1 << 8) #define TB_FLAG_ASI_SHIFT 24 -static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) -{ - uint32_t flags; - *pc = env->pc; - *cs_base = env->npc; - flags = cpu_mmu_index(env_cpu(env), false); -#ifndef CONFIG_USER_ONLY - if (cpu_supervisor_mode(env)) { - flags |= TB_FLAG_SUPER; - } -#endif -#ifdef TARGET_SPARC64 -#ifndef CONFIG_USER_ONLY - if (cpu_hypervisor_mode(env)) { - flags |= TB_FLAG_HYPER; - } -#endif - if (env->pstate & PS_AM) { - flags |= TB_FLAG_AM_ENABLED; - } - if ((env->pstate & PS_PEF) && (env->fprs & FPRS_FEF)) { - flags |= TB_FLAG_FPU_ENABLED; - } - flags |= env->asi << TB_FLAG_ASI_SHIFT; -#else - if (env->psref) { - flags |= TB_FLAG_FPU_ENABLED; - } -#ifndef CONFIG_USER_ONLY - if (env->fsr_qne) { - flags |= TB_FLAG_FSR_QNE; - } -#endif /* !CONFIG_USER_ONLY */ -#endif /* TARGET_SPARC64 */ - *pflags = flags; -} +void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc, + uint64_t *cs_base, uint32_t *pflags); static inline bool tb_fpu_enabled(int tb_flags) { diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c index f2dd8bc..f026606 100644 --- a/target/sparc/int32_helper.c +++ b/target/sparc/int32_helper.c @@ -23,7 +23,7 @@ #include "trace.h" #include "exec/cpu_ldst.h" #include "exec/log.h" -#include "sysemu/runstate.h" +#include "system/runstate.h" static const char * const excp_names[0x80] = { [TT_TFAULT] = "Instruction Access Fault", diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c index d92c9f1..4c54e45 100644 --- a/target/sparc/ldst_helper.c +++ b/target/sparc/ldst_helper.c @@ -26,6 +26,9 @@ #include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/cpu_ldst.h" +#ifdef CONFIG_USER_ONLY +#include "user/page-protection.h" +#endif #include "asi.h" //#define DEBUG_MMU diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 322319a..9be26c8 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -27,9 +27,11 @@ #include "tcg/tcg-op-gvec.h" #include "exec/helper-gen.h" #include "exec/translator.h" +#include "exec/translation-block.h" #include "exec/log.h" #include "fpu/softfloat.h" #include "asi.h" +#include "target/sparc/translate.h" #define HELPER_H "helper.h" #include "exec/helper-info.c.inc" @@ -101,13 +103,6 @@ # define MAXTL_MASK 0 #endif -/* Dynamic PC, must exit to main loop. */ -#define DYNAMIC_PC 1 -/* Dynamic PC, one of two values according to jump_pc[T2]. */ -#define JUMP_PC 2 -/* Dynamic PC, may lookup next TB. */ -#define DYNAMIC_PC_LOOKUP 3 - #define DISAS_EXIT DISAS_TARGET_0 /* global register indexes */ @@ -5881,26 +5876,3 @@ void sparc_tcg_init(void) gregnames[i]); } } - -void sparc_restore_state_to_opc(CPUState *cs, - const TranslationBlock *tb, - const uint64_t *data) -{ - CPUSPARCState *env = cpu_env(cs); - target_ulong pc = data[0]; - target_ulong npc = data[1]; - - env->pc = pc; - if (npc == DYNAMIC_PC) { - /* dynamic NPC: already stored */ - } else if (npc & JUMP_PC) { - /* jump PC: use 'cond' and the jump targets of the translation */ - if (env->cond) { - env->npc = npc & ~3; - } else { - env->npc = pc + 4; - } - } else { - env->npc = npc; - } -} diff --git a/target/sparc/translate.h b/target/sparc/translate.h new file mode 100644 index 0000000..a46fa4f --- /dev/null +++ b/target/sparc/translate.h @@ -0,0 +1,17 @@ +/* + * QEMU translation definitions for SPARC + * + * Copyright (c) 2024 Linaro, Ltd + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef SPARC_TRANSLATION_H +#define SPARC_TRANSLATION_H + +/* Dynamic PC, must exit to main loop. */ +#define DYNAMIC_PC 1 +/* Dynamic PC, one of two values according to jump_pc[T2]. */ +#define JUMP_PC 2 +/* Dynamic PC, may lookup next TB. */ +#define DYNAMIC_PC_LOOKUP 3 + +#endif |