From nobody Tue Nov 4 15:26:25 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; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530030118639164.9062971248278; Tue, 26 Jun 2018 09:21:58 -0700 (PDT) Received: from localhost ([::1]:53759 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fXqj7-0002Nt-QV for importer@patchew.org; Tue, 26 Jun 2018 12:21:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42456) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fXqgo-0000vU-EW for qemu-devel@nongnu.org; Tue, 26 Jun 2018 12:19:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fXqgh-0005s1-M8 for qemu-devel@nongnu.org; Tue, 26 Jun 2018 12:19:34 -0400 Received: from mail-pl0-x243.google.com ([2607:f8b0:400e:c01::243]:32934) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fXqgh-0005rX-Dl for qemu-devel@nongnu.org; Tue, 26 Jun 2018 12:19:27 -0400 Received: by mail-pl0-x243.google.com with SMTP id 6-v6so8787020plb.0 for ; Tue, 26 Jun 2018 09:19:27 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id 67-v6sm5054306pfm.171.2018.06.26.09.19.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 09:19:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WOYcyxwnPL/xtD/5GTSRIornVsPuNrgBFi3p9AwKaiI=; b=D0yLALaBrkn/ij2yCUYF1zHfJTVs87SHjGQnvINNUof5xBJjt5srj4kWEVEo9Kyim2 t83d3vxyXYZCgCVHy04MXWXgGFNUIR+7I9KUEVQljIQ5lhpl6D3GgXyd7UIQ5i55obfe z5NARFQRkoO2KDTehfreNvAQTrJ3ua6Mrh0wk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WOYcyxwnPL/xtD/5GTSRIornVsPuNrgBFi3p9AwKaiI=; b=n709gJMnpXi2N/gVK7PMpPnq9hSWQy/KgelogtxErc94YarsQSq4Njxmk8NWBghOif chCy3ucH+kIwXNh6E8laL8L9/TfnI1KPhiTzEN4vEHzbrEzAmMiECgJlW+yG1I17tJd4 75VQbp6Zg+RuAl+pDBBA4kLIwMas1nOFrU36CSUSUA69c63+zH0hAam9LtxdcZo/pUdT iCVBPBF+Sm1whCNJtvZHaSAfaUjpqun1artC7+Ug71ssqt6xqNTraXytXXkN64B3rlXZ BGHVVtMtExOjIv7mzuIPKSpM+t/AjbWc4cQSNv9fmgnCXdb31geoK6pOyVk8W9O8drWV 5KYg== X-Gm-Message-State: APt69E2NIpZLfG3IcteHZXjozUZ+5RosXZY3Jmz7AUuR0uQJErVvwoYi pN0EbcuHlnaV/ur48+Dh2ixkBUEuKZM= X-Google-Smtp-Source: ADUXVKL5YoYxRhVH5f0a7kHv8CiZIekknqx+m5o2cycAz3FbVlvFtlxmC84Y5SXNiYrXt3hJWNPTog== X-Received: by 2002:a17:902:321:: with SMTP id 30-v6mr2401447pld.122.1530029966250; Tue, 26 Jun 2018 09:19:26 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 26 Jun 2018 09:19:10 -0700 Message-Id: <20180626161921.27941-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626161921.27941-1-richard.henderson@linaro.org> References: <20180626161921.27941-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::243 Subject: [Qemu-devel] [PATCH 02/13] 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-ppc@nongnu.org, david@gibson.dropbear.id.au 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" 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 --- target/ppc/cpu.h | 3 ++ target/ppc/helper.h | 5 +++ target/ppc/mem_helper.c | 20 ++++++++- target/ppc/translate.c | 93 ++++++++++++++++++++++++++++++----------- 4 files changed, 95 insertions(+), 26 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]; - } else { - gpr1 =3D cpu_gpr[rd]; - gpr2 =3D cpu_gpr[rd+1]; - } - 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)); =20 - tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val)); - tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2)); + /* 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 { + 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_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