diff mbox

[v3,1/3] softmmu: add helper function to pass through retaddr

Message ID 20150618132822.9200.64725.stgit@PASHA-ISP.def.inno
State New
Headers show

Commit Message

Pavel Dovgalyuk June 18, 2015, 1:28 p.m. UTC
This patch introduces several helpers to pass return address
which points to the TB. Correct return address allows correct
restoring of the guest PC and icount. These functions should be used when
helpers embedded into TB invoke memory operations.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 include/exec/cpu_ldst_template.h |   48 ++++++++++++++++++++++++++++++++------
 softmmu_template.h               |    6 -----
 tcg/tcg.h                        |   23 ++++++++++++++++++
 3 files changed, 63 insertions(+), 14 deletions(-)

Comments

Aurelien Jarno June 23, 2015, 10:53 p.m. UTC | #1
On 2015-06-18 16:28, Pavel Dovgalyuk wrote:
> This patch introduces several helpers to pass return address
> which points to the TB. Correct return address allows correct
> restoring of the guest PC and icount. These functions should be used when
> helpers embedded into TB invoke memory operations.
> 
> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
> ---
>  include/exec/cpu_ldst_template.h |   48 ++++++++++++++++++++++++++++++++------
>  softmmu_template.h               |    6 -----
>  tcg/tcg.h                        |   23 ++++++++++++++++++
>  3 files changed, 63 insertions(+), 14 deletions(-)
> 
> diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
> index 95ab750..35df753 100644
> --- a/include/exec/cpu_ldst_template.h
> +++ b/include/exec/cpu_ldst_template.h
> @@ -54,15 +54,21 @@
>  #ifdef SOFTMMU_CODE_ACCESS
>  #define ADDR_READ addr_code
>  #define MMUSUFFIX _cmmu
> +#define URETSUFFIX SUFFIX
> +#define SRETSUFFIX SUFFIX
>  #else
>  #define ADDR_READ addr_read
>  #define MMUSUFFIX _mmu
> +#define URETSUFFIX USUFFIX
> +#define SRETSUFFIX glue(s, SUFFIX)
>  #endif
>  
>  /* generic load/store macros */
>  
>  static inline RES_TYPE
> -glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> +glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> +                                                  target_ulong ptr,
> +                                                  uintptr_t retaddr)
>  {
>      int page_index;
>      RES_TYPE res;
> @@ -74,7 +80,8 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
>      mmu_idx = CPU_MMU_INDEX;
>      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
>                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> -        res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
> +        res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
> +                                                            mmu_idx, retaddr);

helper_ret_ld doesn't take a int for the mmu_idx, but rather a
TCGMemOpIdx (we should add more type checking). They differ by the fact
that TCGMemOpIdx also encodes the size of the operation (plus the
alignement, but that's out of scope here). This currently doesn't make a
difference, but it's better to pass the correct value in case we change
the code later.

>      } else {
>          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
>          res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
> @@ -82,9 +89,17 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
>      return res;
>  }
>  
> +static inline RES_TYPE
> +glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> +{
> +    return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
> +}
> +
>  #if DATA_SIZE <= 2
>  static inline int
> -glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> +glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> +                                                  target_ulong ptr,
> +                                                  uintptr_t retaddr)
>  {
>      int res, page_index;
>      target_ulong addr;
> @@ -95,14 +110,20 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
>      mmu_idx = CPU_MMU_INDEX;
>      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
>                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> -        res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
> -                               MMUSUFFIX)(env, addr, mmu_idx);
> +        res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
> +                               MMUSUFFIX)(env, addr, mmu_idx, retaddr);
>      } else {
>          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
>          res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
>      }
>      return res;
>  }
> +
> +static inline int
> +glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> +{
> +    return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
> +}
>  #endif
>  
>  #ifndef SOFTMMU_CODE_ACCESS
> @@ -110,8 +131,9 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
>  /* generic store macro */
>  
>  static inline void
> -glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
> -                                      RES_TYPE v)
> +glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> +                                                 target_ulong ptr,
> +                                                 RES_TYPE v, uintptr_t retaddr)
>  {
>      int page_index;
>      target_ulong addr;
> @@ -122,13 +144,21 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 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))))) {
> -        glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
> +        glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx,
> +                                                     retaddr);
>      } else {
>          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
>          glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
>      }
>  }
>  
> +static inline void
> +glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
> +                                      RES_TYPE v)
> +{
> +    glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
> +}
> +
>  #endif /* !SOFTMMU_CODE_ACCESS */
>  
>  #undef RES_TYPE
> @@ -139,3 +169,5 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
>  #undef DATA_SIZE
>  #undef MMUSUFFIX
>  #undef ADDR_READ
> +#undef URETSUFFIX
> +#undef SRETSUFFIX
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 39f571b..1d59e55 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -165,9 +165,6 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
>  }
>  #endif
>  
> -#ifdef SOFTMMU_CODE_ACCESS
> -static __attribute__((unused))
> -#endif
>  WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
>                              TCGMemOpIdx oi, uintptr_t retaddr)
>  {
> @@ -252,9 +249,6 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
>  }
>  
>  #if DATA_SIZE > 1
> -#ifdef SOFTMMU_CODE_ACCESS
> -static __attribute__((unused))
> -#endif
>  WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
>                              TCGMemOpIdx oi, uintptr_t retaddr)
>  {
> diff --git a/tcg/tcg.h b/tcg/tcg.h
> index 8098f82..31bd419 100644
> --- a/tcg/tcg.h
> +++ b/tcg/tcg.h
> @@ -981,25 +981,48 @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
>  void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
>                         TCGMemOpIdx oi, uintptr_t retaddr);
>  
> +uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
> +                            TCGMemOpIdx oi, uintptr_t retaddr);
> +
>  /* Temporary aliases until backends are converted.  */
>  #ifdef TARGET_WORDS_BIGENDIAN
>  # define helper_ret_ldsw_mmu  helper_be_ldsw_mmu
>  # define helper_ret_lduw_mmu  helper_be_lduw_mmu
>  # define helper_ret_ldsl_mmu  helper_be_ldsl_mmu
>  # define helper_ret_ldul_mmu  helper_be_ldul_mmu
> +# define helper_ret_ldl_mmu   helper_be_ldul_mmu
>  # define helper_ret_ldq_mmu   helper_be_ldq_mmu
>  # define helper_ret_stw_mmu   helper_be_stw_mmu
>  # define helper_ret_stl_mmu   helper_be_stl_mmu
>  # define helper_ret_stq_mmu   helper_be_stq_mmu
> +# define helper_ret_ldw_cmmu  helper_be_ldw_cmmu
> +# define helper_ret_ldl_cmmu  helper_be_ldl_cmmu
> +# define helper_ret_ldq_cmmu  helper_be_ldq_cmmu

As said in the comment above, these are temporary aliases that will
disappear at some point. It's probably better to not rely on them and
call helper_te_ld_name/helper_te_st_name directly.

>  #else
>  # define helper_ret_ldsw_mmu  helper_le_ldsw_mmu
>  # define helper_ret_lduw_mmu  helper_le_lduw_mmu
>  # define helper_ret_ldsl_mmu  helper_le_ldsl_mmu
>  # define helper_ret_ldul_mmu  helper_le_ldul_mmu
> +# define helper_ret_ldl_mmu   helper_le_ldul_mmu
>  # define helper_ret_ldq_mmu   helper_le_ldq_mmu
>  # define helper_ret_stw_mmu   helper_le_stw_mmu
>  # define helper_ret_stl_mmu   helper_le_stl_mmu
>  # define helper_ret_stq_mmu   helper_le_stq_mmu
> +# define helper_ret_ldw_cmmu  helper_le_ldw_cmmu
> +# define helper_ret_ldl_cmmu  helper_le_ldl_cmmu
> +# define helper_ret_ldq_cmmu  helper_le_ldq_cmmu
>  #endif
>  
>  #endif /* CONFIG_SOFTMMU */
> 
>
Pavel Dovgalyuk June 25, 2015, 11:28 a.m. UTC | #2
> From: Aurelien Jarno [mailto:aurelien@aurel32.net]
> On 2015-06-18 16:28, Pavel Dovgalyuk wrote:
> > This patch introduces several helpers to pass return address
> > which points to the TB. Correct return address allows correct
> > restoring of the guest PC and icount. These functions should be used when
> > helpers embedded into TB invoke memory operations.
> >
> > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
> > ---
> >  include/exec/cpu_ldst_template.h |   48 ++++++++++++++++++++++++++++++++------
> >  softmmu_template.h               |    6 -----
> >  tcg/tcg.h                        |   23 ++++++++++++++++++
> >  3 files changed, 63 insertions(+), 14 deletions(-)
> >
> > diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
> > index 95ab750..35df753 100644
> > --- a/include/exec/cpu_ldst_template.h
> > +++ b/include/exec/cpu_ldst_template.h
> > @@ -54,15 +54,21 @@
> >  #ifdef SOFTMMU_CODE_ACCESS
> >  #define ADDR_READ addr_code
> >  #define MMUSUFFIX _cmmu
> > +#define URETSUFFIX SUFFIX
> > +#define SRETSUFFIX SUFFIX
> >  #else
> >  #define ADDR_READ addr_read
> >  #define MMUSUFFIX _mmu
> > +#define URETSUFFIX USUFFIX
> > +#define SRETSUFFIX glue(s, SUFFIX)
> >  #endif
> >
> >  /* generic load/store macros */
> >
> >  static inline RES_TYPE
> > -glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > +glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> > +                                                  target_ulong ptr,
> > +                                                  uintptr_t retaddr)
> >  {
> >      int page_index;
> >      RES_TYPE res;
> > @@ -74,7 +80,8 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> ptr)
> >      mmu_idx = CPU_MMU_INDEX;
> >      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
> >                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> > -        res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
> > +        res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
> > +                                                            mmu_idx, retaddr);
> 
> helper_ret_ld doesn't take a int for the mmu_idx, but rather a
> TCGMemOpIdx (we should add more type checking). They differ by the fact
> that TCGMemOpIdx also encodes the size of the operation (plus the
> alignement, but that's out of scope here). This currently doesn't make a
> difference, but it's better to pass the correct value in case we change
> the code later.

Ok.

> >      } else {
> >          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
> >          res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
> > @@ -82,9 +89,17 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> ptr)
> >      return res;
> >  }
> >
> > +static inline RES_TYPE
> > +glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > +{
> > +    return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
> > +}
> > +
> >  #if DATA_SIZE <= 2
> >  static inline int
> > -glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > +glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> > +                                                  target_ulong ptr,
> > +                                                  uintptr_t retaddr)
> >  {
> >      int res, page_index;
> >      target_ulong addr;
> > @@ -95,14 +110,20 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> ptr)
> >      mmu_idx = CPU_MMU_INDEX;
> >      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
> >                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> > -        res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
> > -                               MMUSUFFIX)(env, addr, mmu_idx);
> > +        res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
> > +                               MMUSUFFIX)(env, addr, mmu_idx, retaddr);
> >      } else {
> >          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
> >          res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
> >      }
> >      return res;
> >  }
> > +
> > +static inline int
> > +glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > +{
> > +    return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
> > +}
> >  #endif
> >
> >  #ifndef SOFTMMU_CODE_ACCESS
> > @@ -110,8 +131,9 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> ptr)
> >  /* generic store macro */
> >
> >  static inline void
> > -glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
> > -                                      RES_TYPE v)
> > +glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> > +                                                 target_ulong ptr,
> > +                                                 RES_TYPE v, uintptr_t retaddr)
> >  {
> >      int page_index;
> >      target_ulong addr;
> > @@ -122,13 +144,21 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 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))))) {
> > -        glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
> > +        glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx,
> > +                                                     retaddr);
> >      } else {
> >          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
> >          glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
> >      }
> >  }
> >
> > +static inline void
> > +glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
> > +                                      RES_TYPE v)
> > +{
> > +    glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
> > +}
> > +
> >  #endif /* !SOFTMMU_CODE_ACCESS */
> >
> >  #undef RES_TYPE
> > @@ -139,3 +169,5 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> ptr,
> >  #undef DATA_SIZE
> >  #undef MMUSUFFIX
> >  #undef ADDR_READ
> > +#undef URETSUFFIX
> > +#undef SRETSUFFIX
> > diff --git a/softmmu_template.h b/softmmu_template.h
> > index 39f571b..1d59e55 100644
> > --- a/softmmu_template.h
> > +++ b/softmmu_template.h
> > @@ -165,9 +165,6 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
> >  }
> >  #endif
> >
> > -#ifdef SOFTMMU_CODE_ACCESS
> > -static __attribute__((unused))
> > -#endif
> >  WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
> >                              TCGMemOpIdx oi, uintptr_t retaddr)
> >  {
> > @@ -252,9 +249,6 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
> >  }
> >
> >  #if DATA_SIZE > 1
> > -#ifdef SOFTMMU_CODE_ACCESS
> > -static __attribute__((unused))
> > -#endif
> >  WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
> >                              TCGMemOpIdx oi, uintptr_t retaddr)
> >  {
> > diff --git a/tcg/tcg.h b/tcg/tcg.h
> > index 8098f82..31bd419 100644
> > --- a/tcg/tcg.h
> > +++ b/tcg/tcg.h
> > @@ -981,25 +981,48 @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t
> val,
> >  void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
> >                         TCGMemOpIdx oi, uintptr_t retaddr);
> >
> > +uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
> > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > +
> >  /* Temporary aliases until backends are converted.  */
> >  #ifdef TARGET_WORDS_BIGENDIAN
> >  # define helper_ret_ldsw_mmu  helper_be_ldsw_mmu
> >  # define helper_ret_lduw_mmu  helper_be_lduw_mmu
> >  # define helper_ret_ldsl_mmu  helper_be_ldsl_mmu
> >  # define helper_ret_ldul_mmu  helper_be_ldul_mmu
> > +# define helper_ret_ldl_mmu   helper_be_ldul_mmu
> >  # define helper_ret_ldq_mmu   helper_be_ldq_mmu
> >  # define helper_ret_stw_mmu   helper_be_stw_mmu
> >  # define helper_ret_stl_mmu   helper_be_stl_mmu
> >  # define helper_ret_stq_mmu   helper_be_stq_mmu
> > +# define helper_ret_ldw_cmmu  helper_be_ldw_cmmu
> > +# define helper_ret_ldl_cmmu  helper_be_ldl_cmmu
> > +# define helper_ret_ldq_cmmu  helper_be_ldq_cmmu
> 
> As said in the comment above, these are temporary aliases that will
> disappear at some point. It's probably better to not rely on them and
> call helper_te_ld_name/helper_te_st_name directly.

These functions cannot be called directly.
helper_te_ld_name/helper_te_st_name are defined in softmmu_template.h and not declared anywhere.
cpu_ldst.h can be included without softmmu_template.h or before it and does not see these #defines.

Pavel Dovgalyuk
Aurelien Jarno July 1, 2015, 4:15 p.m. UTC | #3
On 2015-06-25 14:28, Pavel Dovgaluk wrote:
> > From: Aurelien Jarno [mailto:aurelien@aurel32.net]
> > On 2015-06-18 16:28, Pavel Dovgalyuk wrote:
> > > This patch introduces several helpers to pass return address
> > > which points to the TB. Correct return address allows correct
> > > restoring of the guest PC and icount. These functions should be used when
> > > helpers embedded into TB invoke memory operations.
> > >
> > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
> > > ---
> > >  include/exec/cpu_ldst_template.h |   48 ++++++++++++++++++++++++++++++++------
> > >  softmmu_template.h               |    6 -----
> > >  tcg/tcg.h                        |   23 ++++++++++++++++++
> > >  3 files changed, 63 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
> > > index 95ab750..35df753 100644
> > > --- a/include/exec/cpu_ldst_template.h
> > > +++ b/include/exec/cpu_ldst_template.h
> > > @@ -54,15 +54,21 @@
> > >  #ifdef SOFTMMU_CODE_ACCESS
> > >  #define ADDR_READ addr_code
> > >  #define MMUSUFFIX _cmmu
> > > +#define URETSUFFIX SUFFIX
> > > +#define SRETSUFFIX SUFFIX
> > >  #else
> > >  #define ADDR_READ addr_read
> > >  #define MMUSUFFIX _mmu
> > > +#define URETSUFFIX USUFFIX
> > > +#define SRETSUFFIX glue(s, SUFFIX)
> > >  #endif
> > >
> > >  /* generic load/store macros */
> > >
> > >  static inline RES_TYPE
> > > -glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > > +glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> > > +                                                  target_ulong ptr,
> > > +                                                  uintptr_t retaddr)
> > >  {
> > >      int page_index;
> > >      RES_TYPE res;
> > > @@ -74,7 +80,8 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> > ptr)
> > >      mmu_idx = CPU_MMU_INDEX;
> > >      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
> > >                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> > > -        res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
> > > +        res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
> > > +                                                            mmu_idx, retaddr);
> > 
> > helper_ret_ld doesn't take a int for the mmu_idx, but rather a
> > TCGMemOpIdx (we should add more type checking). They differ by the fact
> > that TCGMemOpIdx also encodes the size of the operation (plus the
> > alignement, but that's out of scope here). This currently doesn't make a
> > difference, but it's better to pass the correct value in case we change
> > the code later.
> 
> Ok.
> 
> > >      } else {
> > >          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
> > >          res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
> > > @@ -82,9 +89,17 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> > ptr)
> > >      return res;
> > >  }
> > >
> > > +static inline RES_TYPE
> > > +glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > > +{
> > > +    return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
> > > +}
> > > +
> > >  #if DATA_SIZE <= 2
> > >  static inline int
> > > -glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > > +glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> > > +                                                  target_ulong ptr,
> > > +                                                  uintptr_t retaddr)
> > >  {
> > >      int res, page_index;
> > >      target_ulong addr;
> > > @@ -95,14 +110,20 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> > ptr)
> > >      mmu_idx = CPU_MMU_INDEX;
> > >      if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
> > >                   (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> > > -        res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
> > > -                               MMUSUFFIX)(env, addr, mmu_idx);
> > > +        res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
> > > +                               MMUSUFFIX)(env, addr, mmu_idx, retaddr);
> > >      } else {
> > >          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
> > >          res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
> > >      }
> > >      return res;
> > >  }
> > > +
> > > +static inline int
> > > +glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
> > > +{
> > > +    return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
> > > +}
> > >  #endif
> > >
> > >  #ifndef SOFTMMU_CODE_ACCESS
> > > @@ -110,8 +131,9 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> > ptr)
> > >  /* generic store macro */
> > >
> > >  static inline void
> > > -glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
> > > -                                      RES_TYPE v)
> > > +glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
> > > +                                                 target_ulong ptr,
> > > +                                                 RES_TYPE v, uintptr_t retaddr)
> > >  {
> > >      int page_index;
> > >      target_ulong addr;
> > > @@ -122,13 +144,21 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 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))))) {
> > > -        glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
> > > +        glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx,
> > > +                                                     retaddr);
> > >      } else {
> > >          uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
> > >          glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
> > >      }
> > >  }
> > >
> > > +static inline void
> > > +glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
> > > +                                      RES_TYPE v)
> > > +{
> > > +    glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
> > > +}
> > > +
> > >  #endif /* !SOFTMMU_CODE_ACCESS */
> > >
> > >  #undef RES_TYPE
> > > @@ -139,3 +169,5 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong
> > ptr,
> > >  #undef DATA_SIZE
> > >  #undef MMUSUFFIX
> > >  #undef ADDR_READ
> > > +#undef URETSUFFIX
> > > +#undef SRETSUFFIX
> > > diff --git a/softmmu_template.h b/softmmu_template.h
> > > index 39f571b..1d59e55 100644
> > > --- a/softmmu_template.h
> > > +++ b/softmmu_template.h
> > > @@ -165,9 +165,6 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
> > >  }
> > >  #endif
> > >
> > > -#ifdef SOFTMMU_CODE_ACCESS
> > > -static __attribute__((unused))
> > > -#endif
> > >  WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
> > >                              TCGMemOpIdx oi, uintptr_t retaddr)
> > >  {
> > > @@ -252,9 +249,6 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
> > >  }
> > >
> > >  #if DATA_SIZE > 1
> > > -#ifdef SOFTMMU_CODE_ACCESS
> > > -static __attribute__((unused))
> > > -#endif
> > >  WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
> > >                              TCGMemOpIdx oi, uintptr_t retaddr)
> > >  {
> > > diff --git a/tcg/tcg.h b/tcg/tcg.h
> > > index 8098f82..31bd419 100644
> > > --- a/tcg/tcg.h
> > > +++ b/tcg/tcg.h
> > > @@ -981,25 +981,48 @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t
> > val,
> > >  void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
> > >                         TCGMemOpIdx oi, uintptr_t retaddr);
> > >
> > > +uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
> > > +                            TCGMemOpIdx oi, uintptr_t retaddr);
> > > +
> > >  /* Temporary aliases until backends are converted.  */
> > >  #ifdef TARGET_WORDS_BIGENDIAN
> > >  # define helper_ret_ldsw_mmu  helper_be_ldsw_mmu
> > >  # define helper_ret_lduw_mmu  helper_be_lduw_mmu
> > >  # define helper_ret_ldsl_mmu  helper_be_ldsl_mmu
> > >  # define helper_ret_ldul_mmu  helper_be_ldul_mmu
> > > +# define helper_ret_ldl_mmu   helper_be_ldul_mmu
> > >  # define helper_ret_ldq_mmu   helper_be_ldq_mmu
> > >  # define helper_ret_stw_mmu   helper_be_stw_mmu
> > >  # define helper_ret_stl_mmu   helper_be_stl_mmu
> > >  # define helper_ret_stq_mmu   helper_be_stq_mmu
> > > +# define helper_ret_ldw_cmmu  helper_be_ldw_cmmu
> > > +# define helper_ret_ldl_cmmu  helper_be_ldl_cmmu
> > > +# define helper_ret_ldq_cmmu  helper_be_ldq_cmmu
> > 
> > As said in the comment above, these are temporary aliases that will
> > disappear at some point. It's probably better to not rely on them and
> > call helper_te_ld_name/helper_te_st_name directly.
> 
> These functions cannot be called directly.
> helper_te_ld_name/helper_te_st_name are defined in softmmu_template.h and not declared anywhere.
> cpu_ldst.h can be included without softmmu_template.h or before it and does not see these #defines.

Ok, I found it's a pitty that we add more temporary code, but OTOH I
understand it's not your job to fix that.
diff mbox

Patch

diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index 95ab750..35df753 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -54,15 +54,21 @@ 
 #ifdef SOFTMMU_CODE_ACCESS
 #define ADDR_READ addr_code
 #define MMUSUFFIX _cmmu
+#define URETSUFFIX SUFFIX
+#define SRETSUFFIX SUFFIX
 #else
 #define ADDR_READ addr_read
 #define MMUSUFFIX _mmu
+#define URETSUFFIX USUFFIX
+#define SRETSUFFIX glue(s, SUFFIX)
 #endif
 
 /* generic load/store macros */
 
 static inline RES_TYPE
-glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
+                                                  target_ulong ptr,
+                                                  uintptr_t retaddr)
 {
     int page_index;
     RES_TYPE res;
@@ -74,7 +80,8 @@  glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
     mmu_idx = CPU_MMU_INDEX;
     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
-        res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
+        res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
+                                                            mmu_idx, retaddr);
     } else {
         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
         res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
@@ -82,9 +89,17 @@  glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
     return res;
 }
 
+static inline RES_TYPE
+glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+{
+    return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
+}
+
 #if DATA_SIZE <= 2
 static inline int
-glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
+                                                  target_ulong ptr,
+                                                  uintptr_t retaddr)
 {
     int res, page_index;
     target_ulong addr;
@@ -95,14 +110,20 @@  glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
     mmu_idx = CPU_MMU_INDEX;
     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
-        res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
-                               MMUSUFFIX)(env, addr, mmu_idx);
+        res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
+                               MMUSUFFIX)(env, addr, mmu_idx, retaddr);
     } else {
         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
         res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
     }
     return res;
 }
+
+static inline int
+glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+{
+    return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
+}
 #endif
 
 #ifndef SOFTMMU_CODE_ACCESS
@@ -110,8 +131,9 @@  glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 /* generic store macro */
 
 static inline void
-glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
-                                      RES_TYPE v)
+glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
+                                                 target_ulong ptr,
+                                                 RES_TYPE v, uintptr_t retaddr)
 {
     int page_index;
     target_ulong addr;
@@ -122,13 +144,21 @@  glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 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))))) {
-        glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
+        glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx,
+                                                     retaddr);
     } else {
         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
         glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
     }
 }
 
+static inline void
+glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
+                                      RES_TYPE v)
+{
+    glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
+}
+
 #endif /* !SOFTMMU_CODE_ACCESS */
 
 #undef RES_TYPE
@@ -139,3 +169,5 @@  glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
 #undef DATA_SIZE
 #undef MMUSUFFIX
 #undef ADDR_READ
+#undef URETSUFFIX
+#undef SRETSUFFIX
diff --git a/softmmu_template.h b/softmmu_template.h
index 39f571b..1d59e55 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -165,9 +165,6 @@  static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
 }
 #endif
 
-#ifdef SOFTMMU_CODE_ACCESS
-static __attribute__((unused))
-#endif
 WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
                             TCGMemOpIdx oi, uintptr_t retaddr)
 {
@@ -252,9 +249,6 @@  WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
 }
 
 #if DATA_SIZE > 1
-#ifdef SOFTMMU_CODE_ACCESS
-static __attribute__((unused))
-#endif
 WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
                             TCGMemOpIdx oi, uintptr_t retaddr)
 {
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 8098f82..31bd419 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -981,25 +981,48 @@  void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
 void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
                        TCGMemOpIdx oi, uintptr_t retaddr);
 
+uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
+                            TCGMemOpIdx oi, uintptr_t retaddr);
+
 /* Temporary aliases until backends are converted.  */
 #ifdef TARGET_WORDS_BIGENDIAN
 # define helper_ret_ldsw_mmu  helper_be_ldsw_mmu
 # define helper_ret_lduw_mmu  helper_be_lduw_mmu
 # define helper_ret_ldsl_mmu  helper_be_ldsl_mmu
 # define helper_ret_ldul_mmu  helper_be_ldul_mmu
+# define helper_ret_ldl_mmu   helper_be_ldul_mmu
 # define helper_ret_ldq_mmu   helper_be_ldq_mmu
 # define helper_ret_stw_mmu   helper_be_stw_mmu
 # define helper_ret_stl_mmu   helper_be_stl_mmu
 # define helper_ret_stq_mmu   helper_be_stq_mmu
+# define helper_ret_ldw_cmmu  helper_be_ldw_cmmu
+# define helper_ret_ldl_cmmu  helper_be_ldl_cmmu
+# define helper_ret_ldq_cmmu  helper_be_ldq_cmmu
 #else
 # define helper_ret_ldsw_mmu  helper_le_ldsw_mmu
 # define helper_ret_lduw_mmu  helper_le_lduw_mmu
 # define helper_ret_ldsl_mmu  helper_le_ldsl_mmu
 # define helper_ret_ldul_mmu  helper_le_ldul_mmu
+# define helper_ret_ldl_mmu   helper_le_ldul_mmu
 # define helper_ret_ldq_mmu   helper_le_ldq_mmu
 # define helper_ret_stw_mmu   helper_le_stw_mmu
 # define helper_ret_stl_mmu   helper_le_stl_mmu
 # define helper_ret_stq_mmu   helper_le_stq_mmu
+# define helper_ret_ldw_cmmu  helper_le_ldw_cmmu
+# define helper_ret_ldl_cmmu  helper_le_ldl_cmmu
+# define helper_ret_ldq_cmmu  helper_le_ldq_cmmu
 #endif
 
 #endif /* CONFIG_SOFTMMU */