diff mbox

softmmu_template: POC simpler do_unl_access inline

Message ID 1452179425-11353-1-git-send-email-alex.bennee@linaro.org
State New
Headers show

Commit Message

Alex Bennée Jan. 7, 2016, 3:10 p.m. UTC
As any constant arguments will be folded by the compiler when a function
is in-lined we can squash the be/le handlers together and let the
compiler figure it out.
---
 softmmu_template.h | 68 ++++++++++++++++++++----------------------------------
 1 file changed, 25 insertions(+), 43 deletions(-)

Comments

Alvise Rigo Jan. 7, 2016, 3:21 p.m. UTC | #1
On Thu, Jan 7, 2016 at 4:10 PM, Alex Bennée <alex.bennee@linaro.org> wrote:
> As any constant arguments will be folded by the compiler when a function

I don't understand. If I look at a preprocessed cputlb.c file, I can
see both the le and be variants of the helpers.
Given this, how can little_endian be a constant?

alvise

> is in-lined we can squash the be/le handlers together and let the
> compiler figure it out.
> ---
>  softmmu_template.h | 68 ++++++++++++++++++++----------------------------------
>  1 file changed, 25 insertions(+), 43 deletions(-)
>
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 65cce0a..6d86a21 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -108,6 +108,8 @@
>  # define helper_be_st_name  glue(glue(helper_be_st, SUFFIX), MMUSUFFIX)
>  #endif
>
> +#define helper_generic_st_name glue(glue(helper_generic_st, SUFFIX), MMUSUFFIX)
> +
>  #ifdef TARGET_WORDS_BIGENDIAN
>  # define helper_te_ld_name  helper_be_ld_name
>  # define helper_te_st_name  helper_be_st_name
> @@ -378,12 +380,13 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
>                                   iotlbentry->attrs);
>  }
>
> -static inline void glue(helper_le_st_name, _do_unl_access)(CPUArchState *env,
> -                                                           DATA_TYPE val,
> -                                                           target_ulong addr,
> -                                                           TCGMemOpIdx oi,
> -                                                           unsigned mmu_idx,
> -                                                           uintptr_t retaddr)
> +static inline void glue(helper_generic_st_name, _do_unl_access)(CPUArchState *env,
> +                                                                bool little_endian,
> +                                                                DATA_TYPE val,
> +                                                                target_ulong addr,
> +                                                                TCGMemOpIdx oi,
> +                                                                unsigned mmu_idx,
> +                                                                uintptr_t retaddr)
>  {
>      int i;
>
> @@ -391,12 +394,17 @@ static inline void glue(helper_le_st_name, _do_unl_access)(CPUArchState *env,
>          cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
>                               mmu_idx, retaddr);
>      }
> -    /* XXX: not efficient, but simple */
>      /* Note: relies on the fact that tlb_fill() does not remove the
>       * previous page from the TLB cache.  */
>      for (i = DATA_SIZE - 1; i >= 0; i--) {
> -        /* Little-endian extract.  */
> -        uint8_t val8 = val >> (i * 8);
> +        uint8_t val8;
> +        if (little_endian) {
> +            /* Little-endian extract.  */
> +            val8 = val >> (i * 8);
> +        } else {
> +            /* Big-endian extract.  */
> +            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,
> @@ -415,8 +423,8 @@ static inline void glue(helper_le_st_name, _do_mmio_access)(CPUArchState *env,
>      CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
>
>      if ((addr & (DATA_SIZE - 1)) != 0) {
> -        glue(helper_le_st_name, _do_unl_access)(env, val, addr, mmu_idx,
> -                                                oi, retaddr);
> +        glue(helper_generic_st_name, _do_unl_access)(env, true, val, addr,
> +                                                     mmu_idx, oi, retaddr);
>      }
>      /* ??? Note that the io helpers always read data in the target
>         byte ordering.  We should push the LE/BE request down into io.  */
> @@ -438,8 +446,8 @@ static inline void glue(helper_le_st_name, _do_ram_access)(CPUArchState *env,
>      if (DATA_SIZE > 1
>          && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
>                       >= TARGET_PAGE_SIZE)) {
> -        glue(helper_le_st_name, _do_unl_access)(env, val, addr, oi, mmu_idx,
> -                                                retaddr);
> +        glue(helper_generic_st_name, _do_unl_access)(env, true, val, addr, oi, mmu_idx,
> +                                                     retaddr);
>          return;
>      }
>
> @@ -538,32 +546,6 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
>  }
>
>  #if DATA_SIZE > 1
> -static inline void glue(helper_be_st_name, _do_unl_access)(CPUArchState *env,
> -                                                           DATA_TYPE val,
> -                                                           target_ulong addr,
> -                                                           TCGMemOpIdx oi,
> -                                                           unsigned mmu_idx,
> -                                                           uintptr_t retaddr)
> -{
> -    int i;
> -
> -    if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
> -        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
> -                             mmu_idx, retaddr);
> -    }
> -    /* XXX: not efficient, but simple */
> -    /* Note: relies on the fact that tlb_fill() does not remove the
> -     * previous page from the TLB cache.  */
> -    for (i = DATA_SIZE - 1; i >= 0; 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);
> -    }
> -}
> -
>  static inline void glue(helper_be_st_name, _do_mmio_access)(CPUArchState *env,
>                                                              DATA_TYPE val,
>                                                              target_ulong addr,
> @@ -575,8 +557,8 @@ static inline void glue(helper_be_st_name, _do_mmio_access)(CPUArchState *env,
>      CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
>
>      if ((addr & (DATA_SIZE - 1)) != 0) {
> -        glue(helper_be_st_name, _do_unl_access)(env, val, addr, mmu_idx,
> -                                                oi, retaddr);
> +        glue(helper_generic_st_name, _do_unl_access)(env, false, val, addr, mmu_idx,
> +                                                     oi, retaddr);
>      }
>      /* ??? Note that the io helpers always read data in the target
>         byte ordering.  We should push the LE/BE request down into io.  */
> @@ -598,8 +580,8 @@ static inline void glue(helper_be_st_name, _do_ram_access)(CPUArchState *env,
>      if (DATA_SIZE > 1
>          && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
>                       >= TARGET_PAGE_SIZE)) {
> -        glue(helper_be_st_name, _do_unl_access)(env, val, addr, oi, mmu_idx,
> -                                                retaddr);
> +        glue(helper_generic_st_name, _do_unl_access)(env, false, val, addr, oi, mmu_idx,
> +                                                     retaddr);
>          return;
>      }
>
> --
> 2.6.4
>
diff mbox

Patch

diff --git a/softmmu_template.h b/softmmu_template.h
index 65cce0a..6d86a21 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -108,6 +108,8 @@ 
 # define helper_be_st_name  glue(glue(helper_be_st, SUFFIX), MMUSUFFIX)
 #endif
 
+#define helper_generic_st_name glue(glue(helper_generic_st, SUFFIX), MMUSUFFIX)
+
 #ifdef TARGET_WORDS_BIGENDIAN
 # define helper_te_ld_name  helper_be_ld_name
 # define helper_te_st_name  helper_be_st_name
@@ -378,12 +380,13 @@  static inline void glue(io_write, SUFFIX)(CPUArchState *env,
                                  iotlbentry->attrs);
 }
 
-static inline void glue(helper_le_st_name, _do_unl_access)(CPUArchState *env,
-                                                           DATA_TYPE val,
-                                                           target_ulong addr,
-                                                           TCGMemOpIdx oi,
-                                                           unsigned mmu_idx,
-                                                           uintptr_t retaddr)
+static inline void glue(helper_generic_st_name, _do_unl_access)(CPUArchState *env,
+                                                                bool little_endian,
+                                                                DATA_TYPE val,
+                                                                target_ulong addr,
+                                                                TCGMemOpIdx oi,
+                                                                unsigned mmu_idx,
+                                                                uintptr_t retaddr)
 {
     int i;
 
@@ -391,12 +394,17 @@  static inline void glue(helper_le_st_name, _do_unl_access)(CPUArchState *env,
         cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
                              mmu_idx, retaddr);
     }
-    /* XXX: not efficient, but simple */
     /* Note: relies on the fact that tlb_fill() does not remove the
      * previous page from the TLB cache.  */
     for (i = DATA_SIZE - 1; i >= 0; i--) {
-        /* Little-endian extract.  */
-        uint8_t val8 = val >> (i * 8);
+        uint8_t val8;
+        if (little_endian) {
+            /* Little-endian extract.  */
+            val8 = val >> (i * 8);
+        } else {
+            /* Big-endian extract.  */
+            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,
@@ -415,8 +423,8 @@  static inline void glue(helper_le_st_name, _do_mmio_access)(CPUArchState *env,
     CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
 
     if ((addr & (DATA_SIZE - 1)) != 0) {
-        glue(helper_le_st_name, _do_unl_access)(env, val, addr, mmu_idx,
-                                                oi, retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, true, val, addr,
+                                                     mmu_idx, oi, retaddr);
     }
     /* ??? Note that the io helpers always read data in the target
        byte ordering.  We should push the LE/BE request down into io.  */
@@ -438,8 +446,8 @@  static inline void glue(helper_le_st_name, _do_ram_access)(CPUArchState *env,
     if (DATA_SIZE > 1
         && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
                      >= TARGET_PAGE_SIZE)) {
-        glue(helper_le_st_name, _do_unl_access)(env, val, addr, oi, mmu_idx,
-                                                retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, true, val, addr, oi, mmu_idx,
+                                                     retaddr);
         return;
     }
 
@@ -538,32 +546,6 @@  void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
 }
 
 #if DATA_SIZE > 1
-static inline void glue(helper_be_st_name, _do_unl_access)(CPUArchState *env,
-                                                           DATA_TYPE val,
-                                                           target_ulong addr,
-                                                           TCGMemOpIdx oi,
-                                                           unsigned mmu_idx,
-                                                           uintptr_t retaddr)
-{
-    int i;
-
-    if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
-        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
-                             mmu_idx, retaddr);
-    }
-    /* XXX: not efficient, but simple */
-    /* Note: relies on the fact that tlb_fill() does not remove the
-     * previous page from the TLB cache.  */
-    for (i = DATA_SIZE - 1; i >= 0; 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);
-    }
-}
-
 static inline void glue(helper_be_st_name, _do_mmio_access)(CPUArchState *env,
                                                             DATA_TYPE val,
                                                             target_ulong addr,
@@ -575,8 +557,8 @@  static inline void glue(helper_be_st_name, _do_mmio_access)(CPUArchState *env,
     CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
 
     if ((addr & (DATA_SIZE - 1)) != 0) {
-        glue(helper_be_st_name, _do_unl_access)(env, val, addr, mmu_idx,
-                                                oi, retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, false, val, addr, mmu_idx,
+                                                     oi, retaddr);
     }
     /* ??? Note that the io helpers always read data in the target
        byte ordering.  We should push the LE/BE request down into io.  */
@@ -598,8 +580,8 @@  static inline void glue(helper_be_st_name, _do_ram_access)(CPUArchState *env,
     if (DATA_SIZE > 1
         && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
                      >= TARGET_PAGE_SIZE)) {
-        glue(helper_be_st_name, _do_unl_access)(env, val, addr, oi, mmu_idx,
-                                                retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, false, val, addr, oi, mmu_idx,
+                                                     retaddr);
         return;
     }