From patchwork Tue Jul 12 19:02:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9226003 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5A93A6086B for ; Tue, 12 Jul 2016 19:19:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 46C6126220 for ; Tue, 12 Jul 2016 19:19:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 39A5527DCD; Tue, 12 Jul 2016 19:19:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6C5E926220 for ; Tue, 12 Jul 2016 19:19:39 +0000 (UTC) Received: from localhost ([::1]:42856 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN3DV-0007gX-VI for patchwork-qemu-devel@patchwork.kernel.org; Tue, 12 Jul 2016 15:19:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56405) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2xW-00052G-E5 for qemu-devel@nongnu.org; Tue, 12 Jul 2016 15:03:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bN2xT-0002cz-Ud for qemu-devel@nongnu.org; Tue, 12 Jul 2016 15:03:05 -0400 Received: from mail-qk0-x241.google.com ([2607:f8b0:400d:c09::241]:35518) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2xT-0002cn-QI for qemu-devel@nongnu.org; Tue, 12 Jul 2016 15:03:03 -0400 Received: by mail-qk0-x241.google.com with SMTP id q62so1524018qkf.2 for ; Tue, 12 Jul 2016 12:03:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=h/EkLM6QK7/cZshoDHHaKr/erfhV65SV18gYH76tf+w=; b=vadDto5OIWqRhDjjDfey1bGGP5zNKCaLlEVFzO/IVa01ifZUrN23pslu8Gvf0aQzeJ dRMeQJrFl9yF9ARhXXWNQuBGektZaJRmpvfUxo15utDgeSr7rys5QtDHH9nHBZAxFVoe r9BhIhKM/FjsNl9xiBJUqBo6AGrFitz1feveKJaHwXsDVe2xZiyCLIGfBsltWnjoeyvE +4gmbXpajPGXoPSHnzIVNuShs/YkLf4J5DRbFo0JSJHYnZDAVBz4I5fDZ289I71+Zrmh GJswT91JNomK22eumg3jbAS5B2l35Z9JGSbzUqxJvfqX8eDO8uJsxbjZTbDe8CsoLQUO Jv5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=h/EkLM6QK7/cZshoDHHaKr/erfhV65SV18gYH76tf+w=; b=IMpQ7zm9F0IvkLekFEI/CTkJCnWFzG3/tdigy7eWsfd7TMLnCBa8TckOVzXIZz1ib/ b2MGF9GZktM5gVl/4KFbYVOFLnNb096uDybP/gyf0xdXcmDC1oxUM0SGTCfW5ViKfvjm LzVKUzBVru4/6abATQF+4NM8kWurKQe+cyIc9+nPDZ9n4N/OUyQnsvUHy2vVbE3rJO5w kUlh77FPN4gQqJH/yJj+Do9bT/ry920Z4d5pVht3HML98MgFIdg9kS4KA7AsBgn7scuD gFKJwXjqJzRgmXkTsQbT8Sj2bYSoZ/YTeULNZJ9QbRjihJ7r6AtQcPr5l57CVgRKW3E2 Qh8A== X-Gm-Message-State: ALyK8tIws5lw0/CEKmR/4GQLPikG72/x3473XCkGVJsuKYxF9OXtxkt4IBZfPW3KyGn5oA== X-Received: by 10.55.68.81 with SMTP id r78mr4993521qka.129.1468350183352; Tue, 12 Jul 2016 12:03:03 -0700 (PDT) Received: from bigtime.com (71-37-54-227.tukw.qwest.net. [71.37.54.227]) by smtp.gmail.com with ESMTPSA id u87sm1209716qkl.30.2016.07.12.12.03.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Jul 2016 12:03:02 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 12 Jul 2016 12:02:06 -0700 Message-Id: <1468350138-9736-13-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468350138-9736-1-git-send-email-rth@twiddle.net> References: <1468350138-9736-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c09::241 Subject: [Qemu-devel] [PULL 12/24] target-sparc: Directly implement easy ld/st asis 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: peter.maydell@linaro.org, mark.cave-ayland@ilande.co.uk Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Tested-by: Mark Cave-Ayland Signed-off-by: Richard Henderson --- target-sparc/translate.c | 104 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 14 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 8865864..55364ad 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1980,17 +1980,21 @@ static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs, typedef enum { GET_ASI_HELPER, GET_ASI_EXCP, + GET_ASI_DIRECT, } ASIType; typedef struct { ASIType type; int asi; + int mem_idx; + TCGMemOp memop; } DisasASI; -static DisasASI get_asi(DisasContext *dc, int insn) +static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop) { int asi = GET_FIELD(insn, 19, 26); ASIType type = GET_ASI_HELPER; + int mem_idx = dc->mem_idx; #ifndef TARGET_SPARC64 /* Before v9, all asis are immediate and privileged. */ @@ -2004,6 +2008,16 @@ static DisasASI get_asi(DisasContext *dc, int insn) for LEON, which is incorrect. */ || (asi == ASI_USERDATA && (dc->def->features & CPU_FEATURE_CASA))) { + switch (asi) { + case ASI_USERDATA: /* User data access */ + mem_idx = MMU_USER_IDX; + type = GET_ASI_DIRECT; + break; + case ASI_KERNELDATA: /* Supervisor data access */ + mem_idx = MMU_KERNEL_IDX; + type = GET_ASI_DIRECT; + break; + } } else { gen_exception(dc, TT_PRIV_INSN); type = GET_ASI_EXCP; @@ -2012,19 +2026,77 @@ static DisasASI get_asi(DisasContext *dc, int insn) if (IS_IMM) { asi = dc->asi; } + /* With v9, all asis below 0x80 are privileged. */ + /* ??? We ought to check cpu_has_hypervisor, but we didn't copy + down that bit into DisasContext. For the moment that's ok, + since the direct implementations below doesn't have any ASIs + in the restricted [0x30, 0x7f] range, and the check will be + done properly in the helper. */ + if (!supervisor(dc) && asi < 0x80) { + gen_exception(dc, TT_PRIV_ACT); + type = GET_ASI_EXCP; + } else { + switch (asi) { + case ASI_N: /* Nucleus */ + case ASI_NL: /* Nucleus LE */ + mem_idx = MMU_NUCLEUS_IDX; + break; + case ASI_AIUP: /* As if user primary */ + case ASI_AIUPL: /* As if user primary LE */ + mem_idx = MMU_USER_IDX; + break; + case ASI_AIUS: /* As if user secondary */ + case ASI_AIUSL: /* As if user secondary LE */ + mem_idx = MMU_USER_SECONDARY_IDX; + break; + case ASI_S: /* Secondary */ + case ASI_SL: /* Secondary LE */ + if (mem_idx == MMU_USER_IDX) { + mem_idx = MMU_USER_SECONDARY_IDX; + } else if (mem_idx == MMU_KERNEL_IDX) { + mem_idx = MMU_KERNEL_SECONDARY_IDX; + } + break; + case ASI_P: /* Primary */ + case ASI_PL: /* Primary LE */ + break; + } + switch (asi) { + case ASI_N: + case ASI_NL: + case ASI_AIUP: + case ASI_AIUPL: + case ASI_AIUS: + case ASI_AIUSL: + case ASI_S: + case ASI_SL: + case ASI_P: + case ASI_PL: + type = GET_ASI_DIRECT; + break; + } + /* The little-endian asis all have bit 3 set. */ + if (asi & 8) { + memop ^= MO_BSWAP; + } + } #endif - return (DisasASI){ type, asi }; + return (DisasASI){ type, asi, mem_idx, memop }; } static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, TCGMemOp memop) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, memop); switch (da.type) { case GET_ASI_EXCP: break; + case GET_ASI_DIRECT: + gen_address_mask(dc, addr); + tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop); + break; default: { TCGv_i32 r_asi = tcg_const_i32(da.asi); @@ -2053,11 +2125,15 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, TCGMemOp memop) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, memop); switch (da.type) { case GET_ASI_EXCP: break; + case GET_ASI_DIRECT: + gen_address_mask(dc, addr); + tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop); + break; default: { TCGv_i32 r_asi = tcg_const_i32(da.asi); @@ -2087,7 +2163,7 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src, TCGv addr, int insn) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_TEUL); switch (da.type) { case GET_ASI_EXCP: @@ -2121,7 +2197,7 @@ static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src, static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv val2, int insn, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_TEUL); TCGv val1, dst; TCGv_i32 r_asi; @@ -2140,7 +2216,7 @@ static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv val2, static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_UB); switch (da.type) { case GET_ASI_EXCP: @@ -2175,7 +2251,7 @@ static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn) static void gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ)); switch (da.type) { case GET_ASI_EXCP: @@ -2199,7 +2275,7 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr, static void gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ)); switch (da.type) { case GET_ASI_EXCP: @@ -2223,7 +2299,7 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr, static void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_TEQ); switch (da.type) { case GET_ASI_EXCP: @@ -2245,7 +2321,7 @@ static void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr, static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_TEQ); TCGv lo = gen_load_gpr(dc, rd + 1); switch (da.type) { @@ -2273,7 +2349,7 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv val2, int insn, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_TEQ); TCGv val1 = gen_load_gpr(dc, rd); TCGv dst = gen_dest_gpr(dc, rd); TCGv_i32 r_asi; @@ -2297,9 +2373,9 @@ static void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr, whereby "rd + 1" elicits "error: array subscript is above array". Since we have already asserted that rd is even, the semantics are unchanged. */ - DisasASI da = get_asi(dc, insn); TCGv lo = gen_dest_gpr(dc, rd | 1); TCGv_i64 t64 = tcg_temp_new_i64(); + DisasASI da = get_asi(dc, insn, MO_TEQ); switch (da.type) { case GET_ASI_EXCP: @@ -2329,7 +2405,7 @@ static void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr, static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd) { - DisasASI da = get_asi(dc, insn); + DisasASI da = get_asi(dc, insn, MO_TEQ); TCGv lo = gen_load_gpr(dc, rd + 1); TCGv_i64 t64 = tcg_temp_new_i64();