qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] tcg: Merge GETPC and GETRA


From: Benjamin Herrenschmidt
Subject: Re: [Qemu-devel] [PATCH] tcg: Merge GETPC and GETRA
Date: Tue, 26 Jul 2016 11:36:40 +1000

On Tue, 2016-07-26 at 06:12 +0530, Richard Henderson wrote:
> The return address argument to the softmmu template helpers was
> confused.  In the legacy case, we wanted to indicate that there
> is no return address, and so passed in NULL.  However, we then
> immediately subtracted GETPC_ADJ from NULL, resulting in a non-zero
> value, indicating the presence of an (invalid) return address.
> 
> Push the GETPC_ADJ subtraction down to the only point it's required:
> immediately before use within cpu_restore_state, after all NULL
> pointer
> checks have been completed.  This makes GETPC and GETRA identical.
> 
> Remove GETRA as the lesser used macro, replacing all uses with GETPC.
> 
> Signed-off-by: Richard Henderson <address@hidden>
> ---
> 
> Ben, this should fix the "-2" problem that you reported.  Of course,
> as also discussed in that thread, this won't fix the whole issue.

Thanks. I've fixed the rest of the issue here:

https://github.com/ozbenh/qemu/commit/5b84a90aa696a7072eaa7a2f4cf6ade7cdd10358

While I will send to the list later today hopefully, along with the
rest of my cleanups and fixes that are starting to pile up here:

https://github.com/ozbenh/qemu/commits/wip

I haven't tackled the FP exceptions yet though but that can wait.

Cheers,
Ben.

> r~
> 
> ---
>  cputlb.c                |  6 ++----
>  include/exec/exec-all.h |  9 +++------
>  softmmu_template.h      | 32 ++++++--------------------------
>  target-arm/helper.c     |  6 +++---
>  target-mips/op_helper.c | 18 +++++++++---------
>  translate-all.c         |  1 +
>  6 files changed, 24 insertions(+), 48 deletions(-)
> 
> diff --git a/cputlb.c b/cputlb.c
> index d068ee5..3c99c34 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -543,10 +543,8 @@ static bool victim_tlb_hit(CPUArchState *env,
> size_t mmu_idx, size_t index,
>  #undef MMUSUFFIX
>  
>  #define MMUSUFFIX _cmmu
> -#undef GETPC_ADJ
> -#define GETPC_ADJ 0
> -#undef GETRA
> -#define GETRA() ((uintptr_t)0)
> +#undef GETPC
> +#define GETPC() ((uintptr_t)0)
>  #define SOFTMMU_CODE_ACCESS
>  
>  #define SHIFT 0
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index acda7b6..6a317db 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -335,13 +335,12 @@ static inline void tb_add_jump(TranslationBlock
> *tb, int n,
>      tb_next->jmp_list_first = (uintptr_t)tb | n;
>  }
>  
> -/* GETRA is the true target of the return instruction that we'll
> execute,
> -   defined here for simplicity of defining the follow-up macros.  */
> +/* GETPC is the true target of the return instruction that we'll
> execute.  */
>  #if defined(CONFIG_TCG_INTERPRETER)
>  extern uintptr_t tci_tb_ptr;
> -# define GETRA() tci_tb_ptr
> +# define GETPC() tci_tb_ptr
>  #else
> -# define GETRA() \
> +# define GETPC() \
>      ((uintptr_t)__builtin_extract_return_addr(__builtin_return_addre
> ss(0)))
>  #endif
>  
> @@ -354,8 +353,6 @@ extern uintptr_t tci_tb_ptr;
>     smaller than 4 bytes, so we don't worry about special-casing
> this.  */
>  #define GETPC_ADJ   2
>  
> -#define GETPC()  (GETRA() - GETPC_ADJ)
> -
>  #if !defined(CONFIG_USER_ONLY)
>  
>  struct MemoryRegion *iotlb_to_region(CPUState *cpu,
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 284ab2c..4cbb714 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -150,9 +150,6 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env,
> target_ulong addr,
>      uintptr_t haddr;
>      DATA_TYPE res;
>  
> -    /* Adjust the given return address.  */
> -    retaddr -= GETPC_ADJ;
> -
>      if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
>          cpu_unaligned_access(ENV_GET_CPU(env), addr,
> READ_ACCESS_TYPE,
>                               mmu_idx, retaddr);
> @@ -193,10 +190,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env,
> target_ulong addr,
>      do_unaligned_access:
>          addr1 = addr & ~(DATA_SIZE - 1);
>          addr2 = addr1 + DATA_SIZE;
> -        /* Note the adjustment at the beginning of the function.
> -           Undo that for the recursion.  */
> -        res1 = helper_le_ld_name(env, addr1, oi, retaddr +
> GETPC_ADJ);
> -        res2 = helper_le_ld_name(env, addr2, oi, retaddr +
> GETPC_ADJ);
> +        res1 = helper_le_ld_name(env, addr1, oi, retaddr);
> +        res2 = helper_le_ld_name(env, addr2, oi, retaddr);
>          shift = (addr & (DATA_SIZE - 1)) * 8;
>  
>          /* Little-endian combine.  */
> @@ -224,9 +219,6 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env,
> target_ulong addr,
>      uintptr_t haddr;
>      DATA_TYPE res;
>  
> -    /* Adjust the given return address.  */
> -    retaddr -= GETPC_ADJ;
> -
>      if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
>          cpu_unaligned_access(ENV_GET_CPU(env), addr,
> READ_ACCESS_TYPE,
>                               mmu_idx, retaddr);
> @@ -267,10 +259,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env,
> target_ulong addr,
>      do_unaligned_access:
>          addr1 = addr & ~(DATA_SIZE - 1);
>          addr2 = addr1 + DATA_SIZE;
> -        /* Note the adjustment at the beginning of the function.
> -           Undo that for the recursion.  */
> -        res1 = helper_be_ld_name(env, addr1, oi, retaddr +
> GETPC_ADJ);
> -        res2 = helper_be_ld_name(env, addr2, oi, retaddr +
> GETPC_ADJ);
> +        res1 = helper_be_ld_name(env, addr1, oi, retaddr);
> +        res2 = helper_be_ld_name(env, addr2, oi, retaddr);
>          shift = (addr & (DATA_SIZE - 1)) * 8;
>  
>          /* Big-endian combine.  */
> @@ -334,9 +324,6 @@ void helper_le_st_name(CPUArchState *env,
> target_ulong addr, DATA_TYPE val,
>      int a_bits = get_alignment_bits(get_memop(oi));
>      uintptr_t haddr;
>  
> -    /* Adjust the given return address.  */
> -    retaddr -= GETPC_ADJ;
> -
>      if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
>          cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
>                               mmu_idx, retaddr);
> @@ -391,10 +378,8 @@ void helper_le_st_name(CPUArchState *env,
> target_ulong addr, DATA_TYPE val,
>          for (i = 0; i < DATA_SIZE; ++i) {
>              /* Little-endian extract.  */
>              uint8_t val8 = val >> (i * 8);
> -            /* Note the adjustment at the beginning of the function.
> -               Undo that for the recursion.  */
>              glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
> -                                            oi, retaddr +
> GETPC_ADJ);
> +                                            oi, retaddr);
>          }
>          return;
>      }
> @@ -417,9 +402,6 @@ void helper_be_st_name(CPUArchState *env,
> target_ulong addr, DATA_TYPE val,
>      int a_bits = get_alignment_bits(get_memop(oi));
>      uintptr_t haddr;
>  
> -    /* Adjust the given return address.  */
> -    retaddr -= GETPC_ADJ;
> -
>      if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
>          cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
>                               mmu_idx, retaddr);
> @@ -474,10 +456,8 @@ void helper_be_st_name(CPUArchState *env,
> target_ulong addr, DATA_TYPE val,
>          for (i = 0; i < DATA_SIZE; ++i) {
>              /* Big-endian extract.  */
>              uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
> -            /* Note the adjustment at the beginning of the function.
> -               Undo that for the recursion.  */
>              glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
> -                                            oi, retaddr +
> GETPC_ADJ);
> +                                            oi, retaddr);
>          }
>          return;
>      }
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index bdb842c..915fe0f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -8310,12 +8310,12 @@ void HELPER(dc_zva)(CPUARMState *env,
> uint64_t vaddr_in)
>               * this purpose use the actual register value passed to
> us
>               * so that we get the fault address right.
>               */
> -            helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETRA());
> +            helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
>              /* Now we can populate the other TLB entries, if any */
>              for (i = 0; i < maxidx; i++) {
>                  uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
>                  if (va != (vaddr_in & TARGET_PAGE_MASK)) {
> -                    helper_ret_stb_mmu(env, va, 0, oi, GETRA());
> +                    helper_ret_stb_mmu(env, va, 0, oi, GETPC());
>                  }
>              }
>          }
> @@ -8332,7 +8332,7 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t
> vaddr_in)
>           *    bounce buffer was in use
>           */
>          for (i = 0; i < blocklen; i++) {
> -            helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETRA());
> +            helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
>          }
>      }
>  #else
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index ea2f2ab..7af4c2f 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -4122,10 +4122,10 @@ void helper_msa_ld_ ## TYPE(CPUMIPSState
> *env, uint32_t wd,             \
>  }
>  
>  #if !defined(CONFIG_USER_ONLY)
> -MSA_LD_DF(DF_BYTE,   b, helper_ret_ldub_mmu, oi, GETRA())
> -MSA_LD_DF(DF_HALF,   h, helper_ret_lduw_mmu, oi, GETRA())
> -MSA_LD_DF(DF_WORD,   w, helper_ret_ldul_mmu, oi, GETRA())
> -MSA_LD_DF(DF_DOUBLE, d, helper_ret_ldq_mmu,  oi, GETRA())
> +MSA_LD_DF(DF_BYTE,   b, helper_ret_ldub_mmu, oi, GETPC())
> +MSA_LD_DF(DF_HALF,   h, helper_ret_lduw_mmu, oi, GETPC())
> +MSA_LD_DF(DF_WORD,   w, helper_ret_ldul_mmu, oi, GETPC())
> +MSA_LD_DF(DF_DOUBLE, d, helper_ret_ldq_mmu,  oi, GETPC())
>  #else
>  MSA_LD_DF(DF_BYTE,   b, cpu_ldub_data)
>  MSA_LD_DF(DF_HALF,   h, cpu_lduw_data)
> @@ -4161,17 +4161,17 @@ void helper_msa_st_ ## TYPE(CPUMIPSState
> *env, uint32_t wd,             \
>      int mmu_idx = cpu_mmu_index(env, false);                         
> \
>      int
> i;                                                              \
>      MEMOP_IDX(DF)                                                   
>     \
> -    ensure_writable_pages(env, addr, mmu_idx,
> GETRA());                 \
> +    ensure_writable_pages(env, addr, mmu_idx,
> GETPC());                 \
>      for (i = 0; i < DF_ELEMENTS(DF); i++)
> {                             \
>          ST_INSN(env, addr + (i << DF), pwd->TYPE[i],
> ##__VA_ARGS__);    \
>      }                                                               
>     \
>  }
>  
>  #if !defined(CONFIG_USER_ONLY)
> -MSA_ST_DF(DF_BYTE,   b, helper_ret_stb_mmu, oi, GETRA())
> -MSA_ST_DF(DF_HALF,   h, helper_ret_stw_mmu, oi, GETRA())
> -MSA_ST_DF(DF_WORD,   w, helper_ret_stl_mmu, oi, GETRA())
> -MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETRA())
> +MSA_ST_DF(DF_BYTE,   b, helper_ret_stb_mmu, oi, GETPC())
> +MSA_ST_DF(DF_HALF,   h, helper_ret_stw_mmu, oi, GETPC())
> +MSA_ST_DF(DF_WORD,   w, helper_ret_stl_mmu, oi, GETPC())
> +MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETPC())
>  #else
>  MSA_ST_DF(DF_BYTE,   b, cpu_stb_data)
>  MSA_ST_DF(DF_HALF,   h, cpu_stw_data)
> diff --git a/translate-all.c b/translate-all.c
> index 0d47c1c..644d081 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -299,6 +299,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t
> retaddr)
>  {
>      TranslationBlock *tb;
>  
> +    retaddr -= GETPC_ADJ;
>      tb = tb_find_pc(retaddr);
>      if (tb) {
>          cpu_restore_state_from_tb(cpu, tb, retaddr);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]