qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] SPARC: Add and use CPU_FEATURE_CASA


From: Fabien Chouteau
Subject: Re: [Qemu-devel] [PATCH] SPARC: Add and use CPU_FEATURE_CASA
Date: Wed, 05 Feb 2014 10:21:54 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0

On 11/26/2013 03:04 PM, Sebastian Huber wrote:
> The LEON3 processor has support for the CASA instruction which is
> normally only available for SPARC V9 processors.  Binutils 2.24
> and GCC 4.9 will support this instruction for LEON3.  GCC uses it to
> generate C11 atomic operations.

The patch looks good. I can't really test it but I assume you did. 

Thank you Sebastian.

Reviewed-by: Fabien Chouteau <address@hidden>

> ---
>  target-sparc/cpu.c         |    3 +-
>  target-sparc/cpu.h         |    4 ++-
>  target-sparc/helper.h      |    4 ++-
>  target-sparc/ldst_helper.c |   26 +++++++++++++-----------
>  target-sparc/translate.c   |   47 ++++++++++++++++++++++++++++---------------
>  5 files changed, 52 insertions(+), 32 deletions(-)
> 
> diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
> index e7f878e..5806e59 100644
> --- a/target-sparc/cpu.c
> +++ b/target-sparc/cpu.c
> @@ -458,7 +458,8 @@ static const sparc_def_t sparc_defs[] = {
>          .mmu_trcr_mask = 0xffffffff,
>          .nwindows = 8,
>          .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
> -        CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
> +        CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN |
> +        CPU_FEATURE_CASA,
>      },
>  #endif
>  };
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index 41194ec..f87d7fb 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -271,12 +271,14 @@ typedef struct sparc_def_t {
>  #define CPU_FEATURE_ASR17        (1 << 15)
>  #define CPU_FEATURE_CACHE_CTRL   (1 << 16)
>  #define CPU_FEATURE_POWERDOWN    (1 << 17)
> +#define CPU_FEATURE_CASA         (1 << 18)
>  
>  #ifndef TARGET_SPARC64
>  #define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP |  \
>                                CPU_FEATURE_MUL | CPU_FEATURE_DIV |     \
>                                CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
> -                              CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD)
> +                              CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD | \
> +                              CPU_FEATURE_CASA)
>  #else
>  #define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP |  \
>                                CPU_FEATURE_MUL | CPU_FEATURE_DIV |     \
> diff --git a/target-sparc/helper.h b/target-sparc/helper.h
> index 5e0eea1..9c4fd56 100644
> --- a/target-sparc/helper.h
> +++ b/target-sparc/helper.h
> @@ -22,7 +22,6 @@ DEF_HELPER_1(popc, tl, tl)
>  DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
>  DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
>  DEF_HELPER_5(stf_asi, void, env, tl, int, int, int)
> -DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
>  DEF_HELPER_5(casx_asi, tl, env, tl, tl, tl, i32)
>  DEF_HELPER_2(set_softint, void, env, i64)
>  DEF_HELPER_2(clear_softint, void, env, i64)
> @@ -31,6 +30,9 @@ DEF_HELPER_2(tick_set_count, void, ptr, i64)
>  DEF_HELPER_1(tick_get_count, i64, ptr)
>  DEF_HELPER_2(tick_set_limit, void, ptr, i64)
>  #endif
> +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
> +DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
> +#endif
>  DEF_HELPER_3(check_align, void, env, tl, i32)
>  DEF_HELPER_1(debug, void, env)
>  DEF_HELPER_1(save, void, env)
> diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
> index 2936b58..c51b9b0 100644
> --- a/target-sparc/ldst_helper.c
> +++ b/target-sparc/ldst_helper.c
> @@ -2224,33 +2224,35 @@ void helper_stf_asi(CPUSPARCState *env, target_ulong 
> addr, int asi, int size,
>      }
>  }
>  
> -target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
> -                            target_ulong val1, target_ulong val2, uint32_t 
> asi)
> +target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
> +                             target_ulong val1, target_ulong val2,
> +                             uint32_t asi)
>  {
>      target_ulong ret;
>  
> -    val2 &= 0xffffffffUL;
> -    ret = helper_ld_asi(env, addr, asi, 4, 0);
> -    ret &= 0xffffffffUL;
> +    ret = helper_ld_asi(env, addr, asi, 8, 0);
>      if (val2 == ret) {
> -        helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
> +        helper_st_asi(env, addr, val1, asi, 8);
>      }
>      return ret;
>  }
> +#endif /* TARGET_SPARC64 */
>  
> -target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
> -                             target_ulong val1, target_ulong val2,
> -                             uint32_t asi)
> +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
> +target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
> +                            target_ulong val1, target_ulong val2, uint32_t 
> asi)
>  {
>      target_ulong ret;
>  
> -    ret = helper_ld_asi(env, addr, asi, 8, 0);
> +    val2 &= 0xffffffffUL;
> +    ret = helper_ld_asi(env, addr, asi, 4, 0);
> +    ret &= 0xffffffffUL;
>      if (val2 == ret) {
> -        helper_st_asi(env, addr, val1, asi, 8);
> +        helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
>      }
>      return ret;
>  }
> -#endif /* TARGET_SPARC64 */
> +#endif /* !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) */
>  
>  void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
>  {
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index 38b4519..86743dc 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -2107,18 +2107,6 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv 
> hi, TCGv addr,
>      tcg_temp_free_i64(t64);
>  }
>  
> -static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
> -                               TCGv val2, int insn, int rd)
> -{
> -    TCGv val1 = gen_load_gpr(dc, rd);
> -    TCGv dst = gen_dest_gpr(dc, rd);
> -    TCGv_i32 r_asi = gen_get_asi(insn, addr);
> -
> -    gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
> -    tcg_temp_free_i32(r_asi);
> -    gen_store_gpr(dc, rd, dst);
> -}
> -
>  static inline void gen_casx_asi(DisasContext *dc, TCGv addr,
>                                  TCGv val2, int insn, int rd)
>  {
> @@ -2229,6 +2217,22 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv 
> hi, TCGv addr,
>  #endif
>  
>  #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
> +static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
> +                               TCGv val2, int insn, int rd)
> +{
> +    TCGv val1 = gen_load_gpr(dc, rd);
> +    TCGv dst = gen_dest_gpr(dc, rd);
> +#ifdef TARGET_SPARC64
> +    TCGv_i32 r_asi = gen_get_asi(insn, addr);
> +#else
> +    TCGv_i32 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
> +#endif
> +
> +    gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
> +    tcg_temp_free_i32(r_asi);
> +    gen_store_gpr(dc, rd, dst);
> +}
> +
>  static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
>  {
>      TCGv_i64 r_val;
> @@ -5103,11 +5107,6 @@ static void disas_sparc_insn(DisasContext * dc, 
> unsigned int insn)
>                      }
>                      gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
>                      break;
> -                case 0x3c: /* V9 casa */
> -                    rs2 = GET_FIELD(insn, 27, 31);
> -                    cpu_src2 = gen_load_gpr(dc, rs2);
> -                    gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
> -                    break;
>                  case 0x3e: /* V9 casxa */
>                      rs2 = GET_FIELD(insn, 27, 31);
>                      cpu_src2 = gen_load_gpr(dc, rs2);
> @@ -5120,6 +5119,20 @@ static void disas_sparc_insn(DisasContext * dc, 
> unsigned int insn)
>                  case 0x37: /* stdc */
>                      goto ncp_insn;
>  #endif
> +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
> +                case 0x3c: /* V9 or LEON3 casa */
> +                    CHECK_FPU_FEATURE(dc, CASA);
> +#ifndef TARGET_SPARC64
> +                    if (IS_IMM)
> +                        goto illegal_insn;
> +                    if (!supervisor(dc))
> +                        goto priv_insn;
> +#endif
> +                    rs2 = GET_FIELD(insn, 27, 31);
> +                    cpu_src2 = gen_load_gpr(dc, rs2);
> +                    gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
> +                    break;
> +#endif
>                  default:
>                      goto illegal_insn;
>                  }
> 




reply via email to

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