From patchwork Tue Jun 26 16:19:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 140014 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp5445216lji; Tue, 26 Jun 2018 09:22:56 -0700 (PDT) X-Google-Smtp-Source: AAOMgpf/xQwS3mg4hNItIuAcmOAhPnzCEVVHwe0EDq+dsFRz3s/hw3bDKYhN5AXhlb8nwaxzvDkG X-Received: by 2002:a37:1b41:: with SMTP id b62-v6mr1920569qkb.343.1530030176340; Tue, 26 Jun 2018 09:22:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530030176; cv=none; d=google.com; s=arc-20160816; b=SDOeNYJ10JwYqaUijMGnhfbok5Zg8+eu2BARLqcuJwsgUpiPR80KU+xlh6VmHrMOEN 5YI0ghY0fYNzStyvZ+rd+StUqNuatr6pF4DwChy3PubwxjW2xq5GeORlLtGOFBzpbpt7 14nMzXk7hXWsDuFdvknLYlMr/uZjFhLqIVB6ge/rfx/DCeFvUo5J+/Dl2vuvR5quDVGH sHnLYRHoQ4M6ZVz0WMY2TxfXndlzEkSRm3GahozR7nTzP7oXJYmGoAsg/KXWUyZz4yzc zPVxhSBVHjCHTk7Qg3/qiFtf2TIlmx1EmLhR/VKXBkiPqhm0xbpT4Hlc6IBrvSfhkMWY DlIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=WOYcyxwnPL/xtD/5GTSRIornVsPuNrgBFi3p9AwKaiI=; b=qv9GWZbqAJfVw35AbIpE8MzuxpMrGwSzkihwHM+Z0cnEViKE5izqNjBHc/FvrqO0ux 5ezGL+Nh0nPai0oQnDDhwQW9ugz2QKjYkK3t9dr76IzHRTtkLjzHYFtSWED2BjMjZys/ UW1vzAhsXNcCW65ZtW2cwCkUPIWmNmokACDY9lnBrzX3hPKAkBWJ0md4V5yKJrQ/nUTh GgoQxjIWWGROdBgqsCiYia7GaZTFlfqXZWx3Z94wwNkOmGLfBOriPyW60arlD775pVjE 5CzyY5Fq1RUVfn2MMtVjgHbGLPYZrmCtio79CfLK+0J6n70CyFj2DUNEpfIwgbutjUKe UEyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=D0yLALaB; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 7-v6si1945345qtt.114.2018.06.26.09.22.56 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 26 Jun 2018 09:22:56 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=D0yLALaB; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:53767 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fXqk3-0003Wd-J8 for patch@linaro.org; Tue, 26 Jun 2018 12:22:55 -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) 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-Received: by 2002:a17:902:321:: with SMTP id 30-v6mr2401447pld.122.1530029966250; Tue, 26 Jun 2018 09:19:26 -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) 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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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(-) -- 2.17.1 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; + /* High part of 128-bit helper return. */ + uint64_t retxh; + int access_type; /* when a memory exception occurs, the access type is stored here */ 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) 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" //#define DEBUG_OP @@ -215,6 +215,24 @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg, return i; } +#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128) +uint64_t helper_lq_le_parallel(CPUPPCState *env, target_ulong addr, + uint32_t opidx) +{ + Int128 ret = helper_atomic_ldo_le_mmu(env, addr, opidx, GETPC()); + env->retxh = int128_gethi(ret); + return int128_getlo(ret); +} + +uint64_t helper_lq_be_parallel(CPUPPCState *env, target_ulong addr, + uint32_t opidx) +{ + Int128 ret = helper_atomic_ldo_be_mmu(env, addr, opidx, GETPC()); + env->retxh = 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; /* lq is a legal user mode instruction starting in ISA 2.07 */ bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; @@ -2633,16 +2633,35 @@ static void gen_lq(DisasContext *ctx) EA = tcg_temp_new(); gen_addr_imm_index(ctx, EA, 0x0F); - /* 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 = cpu_gpr[rd + 1]; + hi = cpu_gpr[rd]; + + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { +#ifdef CONFIG_ATOMIC128 + TCGv_i32 oi = 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 = 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 = rD(ctx->opcode); - TCGv gpr1, gpr2; + TCGv EA, hi, lo; if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) || (rd == rB(ctx->opcode)))) { @@ -3247,24 +3265,49 @@ static void gen_lqarx(DisasContext *ctx) } gen_set_access_type(ctx, ACCESS_RES); - EA = tcg_temp_local_new(); + EA = tcg_temp_new(); gen_addr_reg_index(ctx, EA); - gen_check_align(ctx, EA, 15); - if (unlikely(ctx->le_mode)) { - gpr1 = cpu_gpr[rd+1]; - gpr2 = cpu_gpr[rd]; - } else { - gpr1 = cpu_gpr[rd]; - gpr2 = 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)); - 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 = cpu_gpr[rd + 1]; + hi = cpu_gpr[rd]; + + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { +#ifdef CONFIG_ATOMIC128 + TCGv_i32 oi = 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 = 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)); } /* stqcx. */