cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb()
Where no extra implementation is needed, fall back to CPUClass::set_pc(). Acked-by: Michael Walle <michael@walle.cc> (for lm32) Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
b42eab27be
commit
bdf7ae5bbd
@ -59,8 +59,14 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
|
|||||||
* counter hit zero); we must restore the guest PC to the address
|
* counter hit zero); we must restore the guest PC to the address
|
||||||
* of the start of the TB.
|
* of the start of the TB.
|
||||||
*/
|
*/
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
|
TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
|
||||||
cpu_pc_from_tb(env, tb);
|
if (cc->synchronize_from_tb) {
|
||||||
|
cc->synchronize_from_tb(cpu, tb);
|
||||||
|
} else {
|
||||||
|
assert(cc->set_pc);
|
||||||
|
cc->set_pc(cpu, tb->pc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
|
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
|
||||||
/* We were asked to stop executing TBs (probably a pending
|
/* We were asked to stop executing TBs (probably a pending
|
||||||
|
@ -60,6 +60,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
|
|||||||
bool is_write, bool is_exec, int opaque,
|
bool is_write, bool is_exec, int opaque,
|
||||||
unsigned size);
|
unsigned size);
|
||||||
|
|
||||||
|
struct TranslationBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPUClass:
|
* CPUClass:
|
||||||
* @class_by_name: Callback to map -cpu command line model name to an
|
* @class_by_name: Callback to map -cpu command line model name to an
|
||||||
@ -74,6 +76,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
|
|||||||
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
|
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
|
||||||
* @get_memory_mapping: Callback for obtaining the memory mappings.
|
* @get_memory_mapping: Callback for obtaining the memory mappings.
|
||||||
* @set_pc: Callback for setting the Program Counter register.
|
* @set_pc: Callback for setting the Program Counter register.
|
||||||
|
* @synchronize_from_tb: Callback for synchronizing state from a TCG
|
||||||
|
* #TranslationBlock.
|
||||||
* @vmsd: State description for migration.
|
* @vmsd: State description for migration.
|
||||||
*
|
*
|
||||||
* Represents a CPU family or model.
|
* Represents a CPU family or model.
|
||||||
@ -98,6 +102,7 @@ typedef struct CPUClass {
|
|||||||
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
|
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
void (*set_pc)(CPUState *cpu, vaddr value);
|
void (*set_pc)(CPUState *cpu, vaddr value);
|
||||||
|
void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
|
||||||
|
|
||||||
const struct VMStateDescription *vmsd;
|
const struct VMStateDescription *vmsd;
|
||||||
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||||
|
@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !defined (__CPU_ALPHA_H__) */
|
#endif /* !defined (__CPU_ALPHA_H__) */
|
||||||
|
@ -797,11 +797,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->regs[15] = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load an instruction and return it in the standard little-endian order */
|
/* Load an instruction and return it in the standard little-endian order */
|
||||||
static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
||||||
bool do_swap)
|
bool do_swap)
|
||||||
|
@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2513,6 +2513,13 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value)
|
|||||||
cpu->env.eip = value;
|
cpu->env.eip = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.eip = tb->pc - tb->cs_base;
|
||||||
|
}
|
||||||
|
|
||||||
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
X86CPUClass *xcc = X86_CPU_CLASS(oc);
|
X86CPUClass *xcc = X86_CPU_CLASS(oc);
|
||||||
@ -2530,6 +2537,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
|||||||
cc->do_interrupt = x86_cpu_do_interrupt;
|
cc->do_interrupt = x86_cpu_do_interrupt;
|
||||||
cc->dump_state = x86_cpu_dump_state;
|
cc->dump_state = x86_cpu_dump_state;
|
||||||
cc->set_pc = x86_cpu_set_pc;
|
cc->set_pc = x86_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
|
||||||
cc->get_arch_id = x86_cpu_get_arch_id;
|
cc->get_arch_id = x86_cpu_get_arch_id;
|
||||||
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
|
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
@ -1148,11 +1148,6 @@ static inline bool cpu_has_work(CPUState *cs)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->eip = tb->pc - tb->cs_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
@ -232,9 +232,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPULM32State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -260,9 +260,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -365,9 +365,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUMBState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->sregs[SR_PC] = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,6 +35,16 @@ static void mips_cpu_set_pc(CPUState *cs, vaddr value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
MIPSCPU *cpu = MIPS_CPU(cs);
|
||||||
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->active_tc.PC = tb->pc;
|
||||||
|
env->hflags &= ~MIPS_HFLAG_BMASK;
|
||||||
|
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void mips_cpu_reset(CPUState *s)
|
static void mips_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
@ -90,6 +100,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
|
|||||||
cc->dump_state = mips_cpu_dump_state;
|
cc->dump_state = mips_cpu_dump_state;
|
||||||
cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
|
cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
|
||||||
cc->set_pc = mips_cpu_set_pc;
|
cc->set_pc = mips_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo mips_cpu_type_info = {
|
static const TypeInfo mips_cpu_type_info = {
|
||||||
|
@ -732,13 +732,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->active_tc.PC = tb->pc;
|
|
||||||
env->hflags &= ~MIPS_HFLAG_BMASK;
|
|
||||||
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void compute_hflags(CPUMIPSState *env)
|
static inline void compute_hflags(CPUMIPSState *env)
|
||||||
{
|
{
|
||||||
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
||||||
|
@ -143,11 +143,6 @@ static inline int cpu_mmu_index(CPUMoxieState *env)
|
|||||||
#include "exec/cpu-all.h"
|
#include "exec/cpu-all.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUMoxieState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
@ -428,9 +428,4 @@ static inline target_ulong cpu_get_pc(CPUOpenRISCState *env)
|
|||||||
return env->pc;
|
return env->pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CPU_OPENRISC_H */
|
#endif /* CPU_OPENRISC_H */
|
||||||
|
@ -2144,11 +2144,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->nip = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
|
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
|
||||||
|
|
||||||
#endif /* !defined (__CPU_PPC_H__) */
|
#endif /* !defined (__CPU_PPC_H__) */
|
||||||
|
@ -1041,11 +1041,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
(env->psw.mask & PSW_MASK_EXT);
|
(env->psw.mask & PSW_MASK_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
|
|
||||||
{
|
|
||||||
env->psw.addr = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fpu_helper.c */
|
/* fpu_helper.c */
|
||||||
uint32_t set_cc_nz_f32(float32 v);
|
uint32_t set_cc_nz_f32(float32 v);
|
||||||
uint32_t set_cc_nz_f64(float64 v);
|
uint32_t set_cc_nz_f64(float64 v);
|
||||||
|
@ -31,6 +31,14 @@ static void superh_cpu_set_pc(CPUState *cs, vaddr value)
|
|||||||
cpu->env.pc = value;
|
cpu->env.pc = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
SuperHCPU *cpu = SUPERH_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = tb->pc;
|
||||||
|
cpu->env.flags = tb->flags;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void superh_cpu_reset(CPUState *s)
|
static void superh_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
@ -277,6 +285,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
|
|||||||
cc->do_interrupt = superh_cpu_do_interrupt;
|
cc->do_interrupt = superh_cpu_do_interrupt;
|
||||||
cc->dump_state = superh_cpu_dump_state;
|
cc->dump_state = superh_cpu_dump_state;
|
||||||
cc->set_pc = superh_cpu_set_pc;
|
cc->set_pc = superh_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
|
||||||
dc->vmsd = &vmstate_sh_cpu;
|
dc->vmsd = &vmstate_sh_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,10 +359,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUSH4State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
env->flags = tb->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _CPU_SH4_H */
|
#endif /* _CPU_SH4_H */
|
||||||
|
@ -731,6 +731,14 @@ static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
|
|||||||
cpu->env.npc = value + 4;
|
cpu->env.npc = value + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
SPARCCPU *cpu = SPARC_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = tb->pc;
|
||||||
|
cpu->env.npc = tb->cs_base;
|
||||||
|
}
|
||||||
|
|
||||||
static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
|
static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
|
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
|
||||||
@ -776,6 +784,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
|
|||||||
cc->dump_state = sparc_cpu_dump_state;
|
cc->dump_state = sparc_cpu_dump_state;
|
||||||
cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
|
cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
|
||||||
cc->set_pc = sparc_cpu_set_pc;
|
cc->set_pc = sparc_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo sparc_cpu_type_info = {
|
static const TypeInfo sparc_cpu_type_info = {
|
||||||
|
@ -759,10 +759,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
|||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUSPARCState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
env->npc = tb->cs_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,11 +146,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env)
|
|||||||
#include "cpu-qom.h"
|
#include "cpu-qom.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->regs[31] = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
@ -522,9 +522,4 @@ static inline int cpu_has_work(CPUState *cpu)
|
|||||||
return env->pending_irq_level;
|
return env->pending_irq_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUXtensaState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user