From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47082) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGrc7-0000VY-81 for qemu-devel@nongnu.org; Wed, 06 Jan 2016 12:11:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aGrc2-0005SO-HQ for qemu-devel@nongnu.org; Wed, 06 Jan 2016 12:11:11 -0500 Received: from mail-wm0-x232.google.com ([2a00:1450:400c:c09::232]:37122) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGrc1-0005QN-VP for qemu-devel@nongnu.org; Wed, 06 Jan 2016 12:11:06 -0500 Received: by mail-wm0-x232.google.com with SMTP id f206so85113556wmf.0 for ; Wed, 06 Jan 2016 09:11:04 -0800 (PST) References: <1450082498-27109-1-git-send-email-a.rigo@virtualopensystems.com> <1450082498-27109-8-git-send-email-a.rigo@virtualopensystems.com> From: Alex =?utf-8?Q?Benn=C3=A9e?= In-reply-to: <1450082498-27109-8-git-send-email-a.rigo@virtualopensystems.com> Date: Wed, 06 Jan 2016 17:11:02 +0000 Message-ID: <878u42d461.fsf@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [RFC v6 07/14] target-arm: translate: Use ld/st excl for atomic insns List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alvise Rigo Cc: mttcg@listserver.greensocs.com, claudio.fontana@huawei.com, qemu-devel@nongnu.org, pbonzini@redhat.com, jani.kokkonen@huawei.com, tech@virtualopensystems.com, rth@twiddle.net Alvise Rigo writes: > Use the new LL/SC runtime helpers to handle the ARM atomic > instructions in softmmu_llsc_template.h. > > In general, the helper generator > gen_helper_{ldlink,stcond}_aa32_i{8,16,32,64}() calls the function > helper_{le,be}_{ldlink,stcond}{ub,uw,ulq}_mmu() implemented in > softmmu_llsc_template.h. > > Suggested-by: Jani Kokkonen > Suggested-by: Claudio Fontana > Signed-off-by: Alvise Rigo > --- > target-arm/translate.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 97 insertions(+), 4 deletions(-) > > diff --git a/target-arm/translate.c b/target-arm/translate.c > index 5d22879..e88d8a3 100644 > --- a/target-arm/translate.c > +++ b/target-arm/translate.c > @@ -64,8 +64,10 @@ TCGv_ptr cpu_env; > static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; > static TCGv_i32 cpu_R[16]; > TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF; > +#ifndef CONFIG_TCG_USE_LDST_EXCL > TCGv_i64 cpu_exclusive_addr; > TCGv_i64 cpu_exclusive_val; > +#endif > #ifdef CONFIG_USER_ONLY > TCGv_i64 cpu_exclusive_test; > TCGv_i32 cpu_exclusive_info; > @@ -98,10 +100,12 @@ void arm_translate_init(void) > cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF"); > cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF"); > > +#ifndef CONFIG_TCG_USE_LDST_EXCL > cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0, > offsetof(CPUARMState, exclusive_addr), "exclusive_addr"); > cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0, > offsetof(CPUARMState, exclusive_val), "exclusive_val"); > +#endif > #ifdef CONFIG_USER_ONLY > cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0, > offsetof(CPUARMState, exclusive_test), "exclusive_test"); > @@ -7414,15 +7418,59 @@ static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi) > tcg_gen_or_i32(cpu_ZF, lo, hi); > } > > -/* Load/Store exclusive instructions are implemented by remembering > +/* If the softmmu is enabled, the translation of Load/Store exclusive > + * instructions will rely on the gen_helper_{ldlink,stcond} helpers, > + * offloading most of the work to the softmmu_llsc_template.h functions. > + > + Otherwise, these instructions are implemented by remembering > the value/address loaded, and seeing if these are the same > when the store is performed. This should be sufficient to implement > the architecturally mandated semantics, and avoids having to monitor > regular stores. > > - In system emulation mode only one CPU will be running at once, so > - this sequence is effectively atomic. In user emulation mode we > - throw an exception and handle the atomic operation elsewhere. */ > + In user emulation mode we throw an exception and handle the atomic > + operation elsewhere. */ > +#ifdef CONFIG_TCG_USE_LDST_EXCL > +static void gen_load_exclusive(DisasContext *s, int rt, int rt2, > + TCGv_i32 addr, int size) > + { > + TCGv_i32 tmp = tcg_temp_new_i32(); > + TCGv_i32 mem_idx = tcg_temp_new_i32(); > + > + tcg_gen_movi_i32(mem_idx, get_mem_index(s)); > + > + if (size != 3) { > + switch (size) { > + case 0: > + gen_helper_ldlink_aa32_i8(tmp, cpu_env, addr, mem_idx); > + break; > + case 1: > + gen_helper_ldlink_aa32_i16(tmp, cpu_env, addr, mem_idx); > + break; > + case 2: > + gen_helper_ldlink_aa32_i32(tmp, cpu_env, addr, mem_idx); > + break; > + default: > + abort(); > + } > + > + store_reg(s, rt, tmp); > + } else { > + TCGv_i64 tmp64 = tcg_temp_new_i64(); > + TCGv_i32 tmph = tcg_temp_new_i32(); > + > + gen_helper_ldlink_aa32_i64(tmp64, cpu_env, addr, mem_idx); > + tcg_gen_extr_i64_i32(tmp, tmph, tmp64); > + > + store_reg(s, rt, tmp); > + store_reg(s, rt2, tmph); > + > + tcg_temp_free_i64(tmp64); > + } > + > + tcg_temp_free_i32(mem_idx); > +} > +#else > static void gen_load_exclusive(DisasContext *s, int rt, int rt2, > TCGv_i32 addr, int size) > { > @@ -7461,10 +7509,14 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2, > store_reg(s, rt, tmp); > tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr); > } > +#endif > > static void gen_clrex(DisasContext *s) > { > +#ifdef CONFIG_TCG_USE_LDST_EXCL I don't think it would be correct to ignore clrex in softmmu mode. Assuming the code path had used it we may well be creating slow-path transitions for no reason. > +#else > tcg_gen_movi_i64(cpu_exclusive_addr, -1); > +#endif > } > > #ifdef CONFIG_USER_ONLY > @@ -7476,6 +7528,47 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, > size | (rd << 4) | (rt << 8) | (rt2 << 12)); > gen_exception_internal_insn(s, 4, EXCP_STREX); > } > +#elif defined CONFIG_TCG_USE_LDST_EXCL > +static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, > + TCGv_i32 addr, int size) > +{ > + TCGv_i32 tmp, mem_idx; > + > + mem_idx = tcg_temp_new_i32(); > + > + tcg_gen_movi_i32(mem_idx, get_mem_index(s)); > + tmp = load_reg(s, rt); > + > + if (size != 3) { > + switch (size) { > + case 0: > + gen_helper_stcond_aa32_i8(cpu_R[rd], cpu_env, addr, tmp, mem_idx); > + break; > + case 1: > + gen_helper_stcond_aa32_i16(cpu_R[rd], cpu_env, addr, tmp, mem_idx); > + break; > + case 2: > + gen_helper_stcond_aa32_i32(cpu_R[rd], cpu_env, addr, tmp, mem_idx); > + break; > + default: > + abort(); > + } > + } else { > + TCGv_i64 tmp64; > + TCGv_i32 tmp2; > + > + tmp64 = tcg_temp_new_i64(); > + tmp2 = load_reg(s, rt2); > + tcg_gen_concat_i32_i64(tmp64, tmp, tmp2); > + gen_helper_stcond_aa32_i64(cpu_R[rd], cpu_env, addr, tmp64, mem_idx); > + > + tcg_temp_free_i32(tmp2); > + tcg_temp_free_i64(tmp64); > + } > + > + tcg_temp_free_i32(tmp); > + tcg_temp_free_i32(mem_idx); > +} > #else > static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, > TCGv_i32 addr, int size) -- Alex Bennée