From nobody Tue Nov 4 18:52:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530597863119676.1222985902677; Mon, 2 Jul 2018 23:04:23 -0700 (PDT) Received: from localhost ([::1]:37957 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faEQI-000799-A8 for importer@patchew.org; Tue, 03 Jul 2018 02:04:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39762) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faEKU-0002r3-Ru for qemu-devel@nongnu.org; Tue, 03 Jul 2018 01:58:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faEKR-0006wh-Lt for qemu-devel@nongnu.org; Tue, 03 Jul 2018 01:58:22 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:38415) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faEKQ-0006td-T6; Tue, 03 Jul 2018 01:58:19 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41KYM83gLbz9s8f; Tue, 3 Jul 2018 15:58:11 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1530597492; bh=pBgLmf8ySdtTV2Y4yNdwR4wXy7YFYYyGwDZs/oPOOdU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eKC7DNEHEBkO6EWIYyCgWCGNbAaJMytAZHSolGwdUQLPABba4D7UJRVQ4ABqwiQXU Yv+BtBRcDxFEtmHYq4SKub1cLV2p5alpxVGoSkurcVgl0MEQzvCbvg2IjeiHg7/MHW u8xJOQ1NjoQu/ecS0sfVdzTEtwu42qw+3j/cexWU= From: David Gibson To: peter.maydell@linaro.org Date: Tue, 3 Jul 2018 15:57:41 +1000 Message-Id: <20180703055804.13449-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703055804.13449-1-david@gibson.dropbear.id.au> References: <20180703055804.13449-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PULL 12/35] target/ppc: Use atomic load for LQ and LQARX X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org, Richard Henderson , mdroth@linux.vnet.ibm.com, agraf@suse.de, aik@ozlabs.ru, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Richard Henderson Section 1.4 of the Power ISA v3.0B states that both of these instructions are single-copy atomic. As we cannot (yet) issue 128-bit loads within TCG, use the generic helpers provided. Since TCG cannot (yet) return a 128-bit value, add a slot within CPUPPCState for returning the high half of a 128-bit return value. This solution is preferred to the helper assigning to architectural registers directly, as it avoids clobbering all TCG live values. Signed-off-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/cpu.h | 3 ++ target/ppc/helper.h | 5 +++ target/ppc/mem_helper.c | 20 ++++++++- target/ppc/translate.c | 91 ++++++++++++++++++++++++++++++----------- 4 files changed, 94 insertions(+), 25 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index c7f3fb6b73..973cf44cda 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1015,6 +1015,9 @@ struct CPUPPCState { /* Next instruction pointer */ target_ulong nip; =20 + /* High part of 128-bit helper return. */ + uint64_t retxh; + int access_type; /* when a memory exception occurs, the access type is stored here */ =20 diff --git a/target/ppc/helper.h b/target/ppc/helper.h index d751f0e219..3f451a5d7e 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -799,3 +799,8 @@ DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32) =20 DEF_HELPER_1(tbegin, void, env) DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env) + +#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128) +DEF_HELPER_FLAGS_3(lq_le_parallel, TCG_CALL_NO_WG, i64, env, tl, i32) +DEF_HELPER_FLAGS_3(lq_be_parallel, TCG_CALL_NO_WG, i64, env, tl, i32) +#endif diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c index a34e604db3..44a8f3445a 100644 --- a/target/ppc/mem_helper.c +++ b/target/ppc/mem_helper.c @@ -21,9 +21,9 @@ #include "exec/exec-all.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" - #include "helper_regs.h" #include "exec/cpu_ldst.h" +#include "tcg.h" #include "internal.h" =20 //#define DEBUG_OP @@ -215,6 +215,24 @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulo= ng addr, uint32_t reg, return i; } =20 +#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128) +uint64_t helper_lq_le_parallel(CPUPPCState *env, target_ulong addr, + uint32_t opidx) +{ + Int128 ret =3D helper_atomic_ldo_le_mmu(env, addr, opidx, GETPC()); + env->retxh =3D int128_gethi(ret); + return int128_getlo(ret); +} + +uint64_t helper_lq_be_parallel(CPUPPCState *env, target_ulong addr, + uint32_t opidx) +{ + Int128 ret =3D helper_atomic_ldo_be_mmu(env, addr, opidx, GETPC()); + env->retxh =3D int128_gethi(ret); + return int128_getlo(ret); +} +#endif + /*************************************************************************= ****/ /* Altivec extension helpers */ #if defined(HOST_WORDS_BIGENDIAN) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 3a215a1dc6..0923cc24e3 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -2607,7 +2607,7 @@ static void gen_ld(DisasContext *ctx) static void gen_lq(DisasContext *ctx) { int ra, rd; - TCGv EA; + TCGv EA, hi, lo; =20 /* lq is a legal user mode instruction starting in ISA 2.07 */ bool legal_in_user_mode =3D (ctx->insns_flags2 & PPC2_LSQ_ISA207) !=3D= 0; @@ -2633,16 +2633,35 @@ static void gen_lq(DisasContext *ctx) EA =3D tcg_temp_new(); gen_addr_imm_index(ctx, EA, 0x0F); =20 - /* We only need to swap high and low halves. gen_qemu_ld64_i64 does - necessary 64-bit byteswap already. */ - if (unlikely(ctx->le_mode)) { - gen_qemu_ld64_i64(ctx, cpu_gpr[rd + 1], EA); + /* Note that the low part is always in RD+1, even in LE mode. */ + lo =3D cpu_gpr[rd + 1]; + hi =3D cpu_gpr[rd]; + + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { +#ifdef CONFIG_ATOMIC128 + TCGv_i32 oi =3D tcg_temp_new_i32(); + if (ctx->le_mode) { + tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx)); + gen_helper_lq_le_parallel(lo, cpu_env, EA, oi); + } else { + tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx)); + gen_helper_lq_be_parallel(lo, cpu_env, EA, oi); + } + tcg_temp_free_i32(oi); + tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh)); +#else + /* Restart with exclusive lock. */ + gen_helper_exit_atomic(cpu_env); + ctx->base.is_jmp =3D DISAS_NORETURN; +#endif + } else if (ctx->le_mode) { + tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ); gen_addr_add(ctx, EA, EA, 8); - gen_qemu_ld64_i64(ctx, cpu_gpr[rd], EA); + tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ); } else { - gen_qemu_ld64_i64(ctx, cpu_gpr[rd], EA); + tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ); gen_addr_add(ctx, EA, EA, 8); - gen_qemu_ld64_i64(ctx, cpu_gpr[rd + 1], EA); + tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ); } tcg_temp_free(EA); } @@ -3236,9 +3255,8 @@ STCX(stdcx_, DEF_MEMOP(MO_Q)) /* lqarx */ static void gen_lqarx(DisasContext *ctx) { - TCGv EA; int rd =3D rD(ctx->opcode); - TCGv gpr1, gpr2; + TCGv EA, hi, lo; =20 if (unlikely((rd & 1) || (rd =3D=3D rA(ctx->opcode)) || (rd =3D=3D rB(ctx->opcode)))) { @@ -3247,24 +3265,49 @@ static void gen_lqarx(DisasContext *ctx) } =20 gen_set_access_type(ctx, ACCESS_RES); - EA =3D tcg_temp_local_new(); + EA =3D tcg_temp_new(); gen_addr_reg_index(ctx, EA); - gen_check_align(ctx, EA, 15); - if (unlikely(ctx->le_mode)) { - gpr1 =3D cpu_gpr[rd+1]; - gpr2 =3D cpu_gpr[rd]; + + /* Note that the low part is always in RD+1, even in LE mode. */ + lo =3D cpu_gpr[rd + 1]; + hi =3D cpu_gpr[rd]; + + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { +#ifdef CONFIG_ATOMIC128 + TCGv_i32 oi =3D tcg_temp_new_i32(); + if (ctx->le_mode) { + tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16, + ctx->mem_idx)); + gen_helper_lq_le_parallel(lo, cpu_env, EA, oi); + } else { + tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16, + ctx->mem_idx)); + gen_helper_lq_be_parallel(lo, cpu_env, EA, oi); + } + tcg_temp_free_i32(oi); + tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh)); +#else + /* Restart with exclusive lock. */ + gen_helper_exit_atomic(cpu_env); + ctx->base.is_jmp =3D DISAS_NORETURN; + tcg_temp_free(EA); + return; +#endif + } else if (ctx->le_mode) { + tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ | MO_ALIGN_16); + tcg_gen_mov_tl(cpu_reserve, EA); + gen_addr_add(ctx, EA, EA, 8); + tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ); } else { - gpr1 =3D cpu_gpr[rd]; - gpr2 =3D cpu_gpr[rd+1]; + tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ | MO_ALIGN_16); + tcg_gen_mov_tl(cpu_reserve, EA); + gen_addr_add(ctx, EA, EA, 8); + tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ); } - tcg_gen_qemu_ld_i64(gpr1, EA, ctx->mem_idx, DEF_MEMOP(MO_Q)); - tcg_gen_mov_tl(cpu_reserve, EA); - gen_addr_add(ctx, EA, EA, 8); - tcg_gen_qemu_ld_i64(gpr2, EA, ctx->mem_idx, DEF_MEMOP(MO_Q)); - - tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val)); - tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2)); tcg_temp_free(EA); + + tcg_gen_st_tl(hi, cpu_env, offsetof(CPUPPCState, reserve_val)); + tcg_gen_st_tl(lo, cpu_env, offsetof(CPUPPCState, reserve_val2)); } =20 /* stqcx. */ --=20 2.17.1