From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47795) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c2I5E-0002oC-E0 for qemu-devel@nongnu.org; Thu, 03 Nov 2016 09:29:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c2I5A-0002Ll-E9 for qemu-devel@nongnu.org; Thu, 03 Nov 2016 09:29:32 -0400 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:33003) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1c2I5A-0002LV-7b for qemu-devel@nongnu.org; Thu, 03 Nov 2016 09:29:28 -0400 Received: by mail-wm0-x244.google.com with SMTP id u144so8062787wmu.0 for ; Thu, 03 Nov 2016 06:29:28 -0700 (PDT) Sender: Paolo Bonzini References: <1478178763-12189-1-git-send-email-laurent@vivier.eu> From: Paolo Bonzini Message-ID: <2906e69f-b54d-aaa4-c728-c1c750eb1072@redhat.com> Date: Thu, 3 Nov 2016 14:29:23 +0100 MIME-Version: 1.0 In-Reply-To: <1478178763-12189-1-git-send-email-laurent@vivier.eu> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [PATCH] target-sh4: add atomic tas List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Laurent Vivier , Aurelien Jarno Cc: John Paul Adrian Glaubitz , qemu-devel@nongnu.org, Richard Henderson On 03/11/2016 14:12, Laurent Vivier wrote: > Implement real atomic tas. > > As tas is: > > When (Rn) = 0, 1 -> T > Otherwise, 0 -> T > In both cases, 1 -> MSB of (Rn) > > It can't be implemented using cmpxchg(). Why not? This is essentially movi temp0, 0x80 atomic_fetch_or_i32 temp1, Rn, temp0, ctx->memidx, MO_UB setcondi_i32 cpu_sr_t, TCG_COND_EQ, temp1, 0 But the patch looks good anyway. Paolo > So we use an helper and "parallel_cpus"+cpu_loop_exit_atomic(). > > Tested with image from: > http://wiki.qemu.org/download/sh-test-0.2.tar.bz2 > > This image contains a "tas_test" that runs without > error with this change. > > Signed-off-by: Laurent Vivier > --- > target-sh4/helper.h | 1 + > target-sh4/op_helper.c | 24 ++++++++++++++++++++++++ > target-sh4/translate.c | 13 +------------ > 3 files changed, 26 insertions(+), 12 deletions(-) > > diff --git a/target-sh4/helper.h b/target-sh4/helper.h > index dce859c..4bfa98c 100644 > --- a/target-sh4/helper.h > +++ b/target-sh4/helper.h > @@ -6,6 +6,7 @@ DEF_HELPER_1(raise_slot_fpu_disable, noreturn, env) > DEF_HELPER_1(debug, noreturn, env) > DEF_HELPER_1(sleep, noreturn, env) > DEF_HELPER_2(trapa, noreturn, env, i32) > +DEF_HELPER_2(tas, void, env, i32) > > DEF_HELPER_3(movcal, void, env, i32, i32) > DEF_HELPER_1(discard_movcal_backup, void, env) > diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c > index 684d3f3..17afa92 100644 > --- a/target-sh4/op_helper.c > +++ b/target-sh4/op_helper.c > @@ -105,6 +105,30 @@ void helper_trapa(CPUSH4State *env, uint32_t tra) > raise_exception(env, 0x160, 0); > } > > +void helper_tas(CPUSH4State *env, uint32_t addr) > +{ > + uint8_t l; > + uintptr_t ra = GETPC(); > + > + if (parallel_cpus) { > + /* Tell the main loop we need to serialize this insn. */ > + cpu_loop_exit_atomic(ENV_GET_CPU(env), ra); > + } else { > + /* We're executing in a serial context -- no need to be atomic. */ > +#ifdef CONFIG_USER_ONLY > + uint8_t *haddr = g2h(addr); > + l = ldub_p(haddr); > + stb_p(haddr, l | 0x80); > +#else > + int mmu_idx = cpu_mmu_index(env, 0); > + TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx); > + l = helper_ret_ldub_mmu(env, addr, oi, ra); > + helper_ret_stb_mmu(env, addr, l | 0x80, oi, ra); > +#endif > + env->sr_t = l == 0; > + } > +} > + > void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value) > { > if (cpu_sh4_is_cached (env, address)) > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > index c89a147..44238fc 100644 > --- a/target-sh4/translate.c > +++ b/target-sh4/translate.c > @@ -1640,18 +1640,7 @@ static void _decode_opc(DisasContext * ctx) > tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16); > return; > case 0x401b: /* tas.b @Rn */ > - { > - TCGv addr, val; > - addr = tcg_temp_local_new(); > - tcg_gen_mov_i32(addr, REG(B11_8)); > - val = tcg_temp_local_new(); > - tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB); > - tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0); > - tcg_gen_ori_i32(val, val, 0x80); > - tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB); > - tcg_temp_free(val); > - tcg_temp_free(addr); > - } > + gen_helper_tas(cpu_env, REG(B11_8)); > return; > case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */ > CHECK_FPU_ENABLED >