X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/d06cddf517d2b33389c02971b353d10dd4edda1a..052bb77a47ce2508538d0e4c9a2fb4b9787a2267:/target-arm/op_helper.c diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 1892b35ecc..490111c22f 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -23,13 +23,11 @@ #define SIGNBIT (uint32_t)0x80000000 #define SIGNBIT64 ((uint64_t)1 << 63) -#if !defined(CONFIG_USER_ONLY) static void raise_exception(int tt) { env->exception_index = tt; cpu_loop_exit(env); } -#endif uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, uint32_t rn, uint32_t maxindex) @@ -75,12 +73,11 @@ uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, - void *retaddr) +void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx, + uintptr_t retaddr) { TranslationBlock *tb; - CPUState *saved_env; - unsigned long pc; + CPUARMState *saved_env; int ret; saved_env = env; @@ -89,12 +86,11 @@ void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ - pc = (unsigned long)retaddr; - tb = tb_find_pc(pc); + tb = tb_find_pc(retaddr); if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc); + cpu_restore_state(tb, env, retaddr); } } raise_exception(env->exception_index); @@ -103,7 +99,7 @@ void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, } #endif -/* FIXME: Pass an axplicit pointer to QF to CPUState, and move saturating +/* FIXME: Pass an axplicit pointer to QF to CPUARMState, and move saturating instructions into helper.c */ uint32_t HELPER(add_setq)(uint32_t a, uint32_t b) { @@ -289,6 +285,46 @@ void HELPER(set_user_reg)(uint32_t regno, uint32_t val) } } +void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value) +{ + const ARMCPRegInfo *ri = rip; + int excp = ri->writefn(env, ri, value); + if (excp) { + raise_exception(excp); + } +} + +uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip) +{ + const ARMCPRegInfo *ri = rip; + uint64_t value; + int excp = ri->readfn(env, ri, &value); + if (excp) { + raise_exception(excp); + } + return value; +} + +void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value) +{ + const ARMCPRegInfo *ri = rip; + int excp = ri->writefn(env, ri, value); + if (excp) { + raise_exception(excp); + } +} + +uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip) +{ + const ARMCPRegInfo *ri = rip; + uint64_t value; + int excp = ri->readfn(env, ri, &value); + if (excp) { + raise_exception(excp); + } + return value; +} + /* ??? Flag setting arithmetic is awkward because we need to do comparisons. The only way to do that in TCG is a conditional branch, which clobbers all our temporaries. For now implement these as helper functions. */