qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC][PATCH v3 2/3] tcg: Add declarations and templates


From: Blue Swirl
Subject: Re: [Qemu-devel] [RFC][PATCH v3 2/3] tcg: Add declarations and templates of extended MMU helpers
Date: Sat, 14 Jul 2012 13:08:10 +0000

On Sat, Jul 14, 2012 at 10:23 AM, Yeongkyoon Lee
<address@hidden> wrote:
> Add declarations and templates of extended MMU helpers.
> An extended helper takes an additional argument of the host address accessing
> a guest memory which differs from the address of the call site to the helper
> because helper call sites locate at the end of a generated code block.
> ---
>  softmmu_defs.h     |   64 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  softmmu_header.h   |   31 +++++++++++++++++++++++++
>  softmmu_template.h |   52 +++++++++++++++++++++++++++++++++++------
>  3 files changed, 139 insertions(+), 8 deletions(-)
>
> diff --git a/softmmu_defs.h b/softmmu_defs.h
> index 8d59f9d..505f6ba 100644
> --- a/softmmu_defs.h
> +++ b/softmmu_defs.h
> @@ -10,6 +10,8 @@
>  #define SOFTMMU_DEFS_H
>
>  #ifndef CONFIG_TCG_PASS_AREG0
> +
> +#ifndef CONFIG_QEMU_LDST_OPTIMIZATION
>  uint8_t __ldb_mmu(target_ulong addr, int mmu_idx);
>  void __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
>  uint16_t __ldw_mmu(target_ulong addr, int mmu_idx);
> @@ -28,6 +30,30 @@ void __stl_cmmu(target_ulong addr, uint32_t val, int 
> mmu_idx);
>  uint64_t __ldq_cmmu(target_ulong addr, int mmu_idx);
>  void __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
>  #else
> +/* Extended versions of MMU helpers for qemu_ld/st optimization.
> +   The additional argument is a host code address accessing guest memory */
> +uint8_t ext_ldb_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stb_mmu(target_ulong addr, uint8_t val, int mmu_idx, uintptr_t ra);
> +uint16_t ext_ldw_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stw_mmu(target_ulong addr, uint16_t val, int mmu_idx, uintptr_t ra);
> +uint32_t ext_ldl_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stl_mmu(target_ulong addr, uint32_t val, int mmu_idx, uintptr_t ra);
> +uint64_t ext_ldq_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stq_mmu(target_ulong addr, uint64_t val, int mmu_idx, uintptr_t ra);
> +
> +uint8_t ext_ldb_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx, uintptr_t ra);
> +uint16_t ext_ldw_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx, uintptr_t 
> ra);
> +uint32_t ext_ldl_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx, uintptr_t 
> ra);
> +uint64_t ext_ldq_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx, uintptr_t 
> ra);
> +#endif  /* !CONFIG_QEMU_LDST_OPTIMIZATION */
> +
> +#else
> +
> +#ifndef CONFIG_QEMU_LDST_OPTIMIZATION
>  uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
>  void helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
>                      int mmu_idx);
> @@ -53,6 +79,44 @@ void helper_stl_cmmu(CPUArchState *env, target_ulong addr, 
> uint32_t val,
>  uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
>  void helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
>                       int mmu_idx);
> +#else
> +/* Extended versions of MMU helpers for qemu_ld/st optimization.
> +   The additional argument is a host code address accessing guest memory */
> +uint8_t ext_helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx,
> +                           uintptr_t ra);
> +void ext_helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
> +                        int mmu_idx, uintptr_t ra);
> +uint16_t ext_helper_ldw_mmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                            uintptr_t ra);
> +void ext_helper_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
> +                        int mmu_idx, uintptr_t ra);
> +uint32_t ext_helper_ldl_mmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                            uintptr_t ra);
> +void ext_helper_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
> +                        int mmu_idx, uintptr_t ra);
> +uint64_t ext_helper_ldq_mmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                            uintptr_t ra);
> +void ext_helper_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
> +                        int mmu_idx, uintptr_t ra);
> +
> +uint8_t ext_helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                            uintptr_t ra);
> +void ext_helper_stb_cmmu(CPUArchState *env, target_ulong addr, uint8_t val,
> +                         int mmu_idx, uintptr_t ra);
> +uint16_t ext_helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                             uintptr_t ra);
> +void ext_helper_stw_cmmu(CPUArchState *env, target_ulong addr, uint16_t val,
> +                         int mmu_idx, uintptr_t ra);
> +uint32_t ext_helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                             uintptr_t ra);
> +void ext_helper_stl_cmmu(CPUArchState *env, target_ulong addr, uint32_t val,
> +                         int mmu_idx, uintptr_t ra);
> +uint64_t ext_helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int 
> mmu_idx,
> +                             uintptr_t ra);
> +void ext_helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
> +                         int mmu_idx, uintptr_t ra);
> +#endif  /* !CONFIG_QEMU_LDST_OPTIMIZATION */
> +
>  #endif
>
>  #endif
> diff --git a/softmmu_header.h b/softmmu_header.h
> index cf1aa38..07852c4 100644
> --- a/softmmu_header.h
> +++ b/softmmu_header.h
> @@ -82,12 +82,20 @@
>  #define ENV_PARAM
>  #define ENV_VAR
>  #define CPU_PREFIX
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +#define HELPER_PREFIX ext_
> +#else
>  #define HELPER_PREFIX __
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>  #else
>  #define ENV_PARAM CPUArchState *env,
>  #define ENV_VAR env,
>  #define CPU_PREFIX cpu_
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +#define HELPER_PREFIX ext_helper_
> +#else
>  #define HELPER_PREFIX helper_
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>  #endif
>
>  /* generic load/store macros */
> @@ -106,9 +114,16 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX), 
> MEMSUFFIX)(ENV_PARAM
>      mmu_idx = CPU_MMU_INDEX;
>      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
>                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +        /* XXX: This macro branching is due to checkpatch.pl which
> +           doesn't allow "#define RET_VAR , (uintptr_t)NULL" */

Just do it, checkpatch.pl is not infallible.

> +        res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> +                   MMUSUFFIX)(ENV_VAR addr, mmu_idx, (uintptr_t)NULL);
> +#else
>          res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_VAR
>                                                                       addr,
>                                                                       
> mmu_idx);
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>      } else {
>          uintptr_t hostaddr = addr + 
> env->tlb_table[mmu_idx][page_index].addend;
>          res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
> @@ -130,8 +145,16 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX), 
> MEMSUFFIX)(ENV_PARAM
>      mmu_idx = CPU_MMU_INDEX;
>      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
>                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +        /* XXX: This macro branching is due to checkpatch.pl which
> +           doesn't allow "#define RET_VAR , (uintptr_t)NULL" */
> +        res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> +                               MMUSUFFIX)(ENV_VAR addr, mmu_idx,
> +                                          (uintptr_t)NULL);
> +#else
>          res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
>                                 MMUSUFFIX)(ENV_VAR addr, mmu_idx);
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>      } else {
>          uintptr_t hostaddr = addr + 
> env->tlb_table[mmu_idx][page_index].addend;
>          res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
> @@ -157,8 +180,16 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX), 
> MEMSUFFIX)(ENV_PARAM target_ulong ptr,
>      mmu_idx = CPU_MMU_INDEX;
>      if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
>                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +        /* XXX: This macro branching is due to checkpatch.pl which
> +           doesn't allow "#define RET_VAR , (uintptr_t)NULL" */
> +        glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr, 
> v,
> +                                                               mmu_idx,
> +                                                               
> (uintptr_t)NULL);
> +#else
>          glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr, 
> v,
>                                                                 mmu_idx);
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>      } else {
>          uintptr_t hostaddr = addr + 
> env->tlb_table[mmu_idx][page_index].addend;
>          glue(glue(st, SUFFIX), _raw)(hostaddr, v);
> diff --git a/softmmu_template.h b/softmmu_template.h
> index b8bd700..5096c63 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -66,6 +66,21 @@
>  #define HELPER_PREFIX helper_
>  #endif
>
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +#undef HELPER_PREFIX
> +/* Redefine helper prefix */
> +#ifndef CONFIG_TCG_PASS_AREG0
> +#define HELPER_PREFIX ext_
> +#else
> +#define HELPER_PREFIX ext_helper_
> +#endif
> +/* An extended MMU helper takes one more argument which is
> +   a host address of generated code accessing guest memory */
> +#define GET_RET_ADDR() ra
> +#else
> +#define GET_RET_ADDR() GETPC()
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
> +
>  static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
>                                                          target_ulong addr,
>                                                          int mmu_idx,
> @@ -103,10 +118,20 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
>  }
>
>  /* handle all cases except unaligned access which span two pages */
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +/* XXX: This macro branching is due to checkpatch.pl which doesn't allow
> +   "#define RET_PARAM , uintptr_r ra" */
> +DATA_TYPE
> +glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
> +                                                       target_ulong addr,
> +                                                       int mmu_idx,
> +                                                       uintptr_t ra)
> +#else
>  DATA_TYPE
>  glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
>                                                         target_ulong addr,
>                                                         int mmu_idx)
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>  {
>      DATA_TYPE res;
>      int index;
> @@ -124,13 +149,13 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>              /* IO access */
>              if ((addr & (DATA_SIZE - 1)) != 0)
>                  goto do_unaligned_access;
> -            retaddr = GETPC();
> +            retaddr = GET_RET_ADDR();
>              ioaddr = env->iotlb[mmu_idx][index];
>              res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
>          } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= 
> TARGET_PAGE_SIZE) {
>              /* slow unaligned access (it spans two pages or IO) */
>          do_unaligned_access:
> -            retaddr = GETPC();
> +            retaddr = GET_RET_ADDR();
>  #ifdef ALIGNED_ONLY
>              do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, 
> retaddr);
>  #endif
> @@ -141,7 +166,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>              uintptr_t addend;
>  #ifdef ALIGNED_ONLY
>              if ((addr & (DATA_SIZE - 1)) != 0) {
> -                retaddr = GETPC();
> +                retaddr = GET_RET_ADDR();
>                  do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, 
> retaddr);
>              }
>  #endif
> @@ -151,7 +176,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>          }
>      } else {
>          /* the page is not in the TLB : fill it */
> -        retaddr = GETPC();
> +        retaddr = GET_RET_ADDR();
>  #ifdef ALIGNED_ONLY
>          if ((addr & (DATA_SIZE - 1)) != 0)
>              do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, 
> retaddr);
> @@ -253,10 +278,20 @@ static inline void glue(io_write, SUFFIX)(ENV_PARAM
>  #endif /* SHIFT > 2 */
>  }
>
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +/* XXX: This macro branching is due to checkpatch.pl which doesn't allow
> +   "#define RET_PARAM , uintptr_t ra" */
> +void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
> +                                                            target_ulong 
> addr,
> +                                                            DATA_TYPE val,
> +                                                            int mmu_idx,
> +                                                            uintptr_t ra)
> +#else
>  void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
>                                                              target_ulong 
> addr,
>                                                              DATA_TYPE val,
>                                                              int mmu_idx)
> +#endif  /* CONFIG_QEMU_LDST_OPTIMIZATION */
>  {
>      target_phys_addr_t ioaddr;
>      target_ulong tlb_addr;
> @@ -271,12 +306,12 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>              /* IO access */
>              if ((addr & (DATA_SIZE - 1)) != 0)
>                  goto do_unaligned_access;
> -            retaddr = GETPC();
> +            retaddr = GET_RET_ADDR();
>              ioaddr = env->iotlb[mmu_idx][index];
>              glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
>          } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= 
> TARGET_PAGE_SIZE) {
>          do_unaligned_access:
> -            retaddr = GETPC();
> +            retaddr = GET_RET_ADDR();
>  #ifdef ALIGNED_ONLY
>              do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
>  #endif
> @@ -287,7 +322,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>              uintptr_t addend;
>  #ifdef ALIGNED_ONLY
>              if ((addr & (DATA_SIZE - 1)) != 0) {
> -                retaddr = GETPC();
> +                retaddr = GET_RET_ADDR();
>                  do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
>              }
>  #endif
> @@ -297,7 +332,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>          }
>      } else {
>          /* the page is not in the TLB : fill it */
> -        retaddr = GETPC();
> +        retaddr = GET_RET_ADDR();
>  #ifdef ALIGNED_ONLY
>          if ((addr & (DATA_SIZE - 1)) != 0)
>              do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
> @@ -370,3 +405,4 @@ static void glue(glue(slow_st, SUFFIX), 
> MMUSUFFIX)(ENV_PARAM
>  #undef ENV_VAR
>  #undef CPU_PREFIX
>  #undef HELPER_PREFIX
> +#undef GET_RET_ADDR
> --
> 1.7.4.1
>



reply via email to

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