[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;
> }
>
- Re: [Qemu-devel] [PATCH] SPARC: Add and use CPU_FEATURE_CASA,
Fabien Chouteau <=