From nobody Fri May 17 10:13:16 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1643768715; cv=none; d=zohomail.com; s=zohoarc; b=FIikYaWuN45gg7jPChvZ5cp0BqDL0MXlGiEmHuX84RL4afBpdPoK4Why55NcRQKbvi+LfHmqhVXrWYOvXpNUiDEXS5fxfNb8ZWghJHIeqoynEa92f8iUoUfEcan79ttYH+s4zEcAL500bsuJ72Hbs31HGq6Jo1wDt/cZY1hXp3A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1643768715; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=OWhXhgRGQOPTnQccWQOSBixr23TWkhM+7ZQ2ZKDnHo8=; b=BXXKrq0Qd82+ydR51Y7qX6Qsb+KhHXlczbNlF0aGzNPHyq94bUnvZvXXw9a4gs9m6hULFcGe4EiIhGpZVXuO2Tv4ZIvzP9KVebkIcZ1aueYKveQNuwf5bzLwmz3xyqM5tidOCfV6NA7HVKbuTTlMu6wMNKn7a6SgOecaD/sHLbs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1643768715573550.5935574834076; Tue, 1 Feb 2022 18:25:15 -0800 (PST) Received: from localhost ([::1]:39760 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nF5Kc-0006Oq-J6 for importer@patchew.org; Tue, 01 Feb 2022 21:25:14 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58906) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nF2m9-00016r-De for qemu-devel@nongnu.org; Tue, 01 Feb 2022 18:41:29 -0500 Received: from [2607:f8b0:4864:20::531] (port=38493 helo=mail-pg1-x531.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nF2m6-00072q-H3 for qemu-devel@nongnu.org; Tue, 01 Feb 2022 18:41:28 -0500 Received: by mail-pg1-x531.google.com with SMTP id 132so5799326pga.5 for ; Tue, 01 Feb 2022 15:41:17 -0800 (PST) Received: from stoup.modem ([2001:8003:3a49:fd00:91e3:5d6a:70ac:f94c]) by smtp.gmail.com with ESMTPSA id g9sm16495641pgi.84.2022.02.01.15.41.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 15:41:15 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=OWhXhgRGQOPTnQccWQOSBixr23TWkhM+7ZQ2ZKDnHo8=; b=CuxaqECEsWqgX6anhTvQgcWSiBSbJElpgtl5CGiFwFHkAM4RxqrwBesjGJD7euMv/C hVzu5i3fcxNwe56/qw2fyJiIsIAFEn1pDwojTquH4sd//aDbz8MWYPywFSiNtc93hk6o MO/Fj+xbmfO9PhL1jrIBqGUiM6Ef52cy22YclB6C0FNbyfoSXZSM1kMChFOuCqrh/7np cmzY5CBTnuTTq/sSQv4n3ic0HBrJCrp/l47kI+8hgbmgYKgbTEHoatp3XulkwwDVQ5Yb OO31sqflrEIQDJk//AFxt42gNXR8KXzpF0IduntsIu/KTkatiohSPgoBRJyqq2gSLG2U elRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OWhXhgRGQOPTnQccWQOSBixr23TWkhM+7ZQ2ZKDnHo8=; b=GjT3NCesX/vovuil3Mo2dq8zYlcimRugtPNgxQhpiwoi1wiE0+rfMmeLhAP5UyQK4P X9N+RTkMky9y3Sf2fbXGuJ/29AlJxKVCSsR3aHaipo/InoGLGE1Nnbs79LwSvN90h7sR Kc2a4RFdAaWCva9iIPdZ2LQALE0h4cm0xlZnWIUK6FlzMoMxQGSXseWh7q/jE+TT/o+/ /lVN8rpqqk3z4wB5vk47sl6a5mKAuBI6Fn9V8enfXCJdsP/fNykbJ2Klr8oHho/V8Juo C96jLqYN99rWTvyg9kUKoH9ApQhEg5u+B7F05OLo4jrWxpVs2MJIUtb+AIG7el3CRzHM 5cXw== X-Gm-Message-State: AOAM531YXop3d5cXhUTMukcTI+Zs067jkk4FeY2KZ7ZZALTkISsYmVJS l9/FsUjuglcOgRrvORlvvcxGxqXNwmDCOcs9 X-Google-Smtp-Source: ABdhPJyzQgu08j0EOrEx80Xx9VjhYwsBmAxMVYE7uBxW9PliDIk55b9zlMkenlrbUhuT6uvhCrG7/g== X-Received: by 2002:a63:8548:: with SMTP id u69mr17577787pgd.282.1643758875835; Tue, 01 Feb 2022 15:41:15 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v5 1/2] tcg/mips: Support unaligned access for user-only Date: Wed, 2 Feb 2022 10:41:06 +1100 Message-Id: <20220201234107.316487-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220201234107.316487-1-richard.henderson@linaro.org> References: <20220201234107.316487-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::531 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x531.google.com X-Spam_score_int: -12 X-Spam_score: -1.3 X-Spam_bar: - X-Spam_report: (-1.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, f4bug@amsat.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1643768717770100001 Content-Type: text/plain; charset="utf-8" This is kinda sorta the opposite of the other tcg hosts, where we get (normal) alignment checks for free with host SIGBUS and need to add code to support unaligned accesses. Fortunately, the ISA contains pairs of instructions that are used to implement unaligned memory accesses. Use them. Signed-off-by: Richard Henderson Reviewed-by: Jiaxun Yang Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Jiaxun Yang --- tcg/mips/tcg-target.h | 2 - tcg/mips/tcg-target.c.inc | 334 +++++++++++++++++++++++++++++++++++++- 2 files changed, 328 insertions(+), 8 deletions(-) diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index c366fdf74b..7669213175 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -207,8 +207,6 @@ extern bool use_mips32r2_instructions; void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t) QEMU_ERROR("code path is reachable"); =20 -#ifdef CONFIG_SOFTMMU #define TCG_TARGET_NEED_LDST_LABELS -#endif =20 #endif diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 27b020e66c..7d706df39c 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -24,6 +24,8 @@ * THE SOFTWARE. */ =20 +#include "../tcg-ldst.c.inc" + #ifdef HOST_WORDS_BIGENDIAN # define MIPS_BE 1 #else @@ -230,16 +232,26 @@ typedef enum { OPC_ORI =3D 015 << 26, OPC_XORI =3D 016 << 26, OPC_LUI =3D 017 << 26, + OPC_BNEL =3D 025 << 26, + OPC_BNEZALC_R6 =3D 030 << 26, OPC_DADDIU =3D 031 << 26, + OPC_LDL =3D 032 << 26, + OPC_LDR =3D 033 << 26, OPC_LB =3D 040 << 26, OPC_LH =3D 041 << 26, + OPC_LWL =3D 042 << 26, OPC_LW =3D 043 << 26, OPC_LBU =3D 044 << 26, OPC_LHU =3D 045 << 26, + OPC_LWR =3D 046 << 26, OPC_LWU =3D 047 << 26, OPC_SB =3D 050 << 26, OPC_SH =3D 051 << 26, + OPC_SWL =3D 052 << 26, OPC_SW =3D 053 << 26, + OPC_SDL =3D 054 << 26, + OPC_SDR =3D 055 << 26, + OPC_SWR =3D 056 << 26, OPC_LD =3D 067 << 26, OPC_SD =3D 077 << 26, =20 @@ -1015,8 +1027,6 @@ static void tcg_out_call(TCGContext *s, const tcg_ins= n_unit *arg) } =20 #if defined(CONFIG_SOFTMMU) -#include "../tcg-ldst.c.inc" - static void * const qemu_ld_helpers[(MO_SSIZE | MO_BSWAP) + 1] =3D { [MO_UB] =3D helper_ret_ldub_mmu, [MO_SB] =3D helper_ret_ldsb_mmu, @@ -1324,7 +1334,82 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,= TCGLabelQemuLdst *l) tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); return true; } -#endif + +#else + +static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addrl= o, + TCGReg addrhi, unsigned a_bits) +{ + unsigned a_mask =3D (1 << a_bits) - 1; + TCGLabelQemuLdst *l =3D new_ldst_label(s); + + l->is_ld =3D is_ld; + l->addrlo_reg =3D addrlo; + l->addrhi_reg =3D addrhi; + + /* We are expecting a_bits to max out at 7, much lower than ANDI. */ + tcg_debug_assert(a_bits < 16); + tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addrlo, a_mask); + + l->label_ptr[0] =3D s->code_ptr; + if (use_mips32r6_instructions) { + tcg_out_opc_br(s, OPC_BNEZALC_R6, TCG_REG_ZERO, TCG_TMP0); + } else { + tcg_out_opc_br(s, OPC_BNEL, TCG_TMP0, TCG_REG_ZERO); + tcg_out_nop(s); + } + + l->raddr =3D tcg_splitwx_to_rx(s->code_ptr); +} + +static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l) +{ + void *target; + + if (!reloc_pc16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { + return false; + } + + if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { + /* A0 is env, A1 is skipped, A2:A3 is the uint64_t address. */ + TCGReg a2 =3D MIPS_BE ? l->addrhi_reg : l->addrlo_reg; + TCGReg a3 =3D MIPS_BE ? l->addrlo_reg : l->addrhi_reg; + + if (a3 !=3D TCG_REG_A2) { + tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_A2, a2); + tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_A3, a3); + } else if (a2 !=3D TCG_REG_A3) { + tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_A3, a3); + tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_A2, a2); + } else { + tcg_out_mov(s, TCG_TYPE_I32, TCG_TMP0, TCG_REG_A2); + tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_A2, TCG_REG_A3); + tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_A3, TCG_TMP0); + } + } else { + tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg); + } + tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); + + /* + * Tail call to the helper, with the return address back inline. + * We have arrived here via BNEL, so $31 is already set. + */ + target =3D (l->is_ld ? helper_unaligned_ld : helper_unaligned_st); + tcg_out_call_int(s, target, true); + return true; +} + +static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) +{ + return tcg_out_fail_alignment(s, l); +} + +static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) +{ + return tcg_out_fail_alignment(s, l); +} +#endif /* SOFTMMU */ =20 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, TCGReg base, MemOp opc, bool is_64) @@ -1430,6 +1515,127 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, T= CGReg lo, TCGReg hi, } } =20 +static void __attribute__((unused)) +tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi, + TCGReg base, MemOp opc, bool is_64) +{ + const MIPSInsn lw1 =3D MIPS_BE ? OPC_LWL : OPC_LWR; + const MIPSInsn lw2 =3D MIPS_BE ? OPC_LWR : OPC_LWL; + const MIPSInsn ld1 =3D MIPS_BE ? OPC_LDL : OPC_LDR; + const MIPSInsn ld2 =3D MIPS_BE ? OPC_LDR : OPC_LDL; + + bool sgn =3D (opc & MO_SIGN); + + switch (opc & (MO_SSIZE | MO_BSWAP)) { + case MO_SW | MO_BE: + case MO_UW | MO_BE: + tcg_out_opc_imm(s, sgn ? OPC_LB : OPC_LBU, TCG_TMP0, base, 0); + tcg_out_opc_imm(s, OPC_LBU, lo, base, 1); + if (use_mips32r2_instructions) { + tcg_out_opc_bf(s, OPC_INS, lo, TCG_TMP0, 31, 8); + } else { + tcg_out_opc_sa(s, OPC_SLL, TCG_TMP0, TCG_TMP0, 8); + tcg_out_opc_reg(s, OPC_OR, lo, TCG_TMP0, TCG_TMP1); + } + break; + + case MO_SW | MO_LE: + case MO_UW | MO_LE: + if (use_mips32r2_instructions && lo !=3D base) { + tcg_out_opc_imm(s, OPC_LBU, lo, base, 0); + tcg_out_opc_imm(s, sgn ? OPC_LB : OPC_LBU, TCG_TMP0, base, 1); + tcg_out_opc_bf(s, OPC_INS, lo, TCG_TMP0, 31, 8); + } else { + tcg_out_opc_imm(s, OPC_LBU, TCG_TMP0, base, 0); + tcg_out_opc_imm(s, sgn ? OPC_LB : OPC_LBU, TCG_TMP1, base, 1); + tcg_out_opc_sa(s, OPC_SLL, TCG_TMP1, TCG_TMP1, 8); + tcg_out_opc_reg(s, OPC_OR, lo, TCG_TMP0, TCG_TMP1); + } + break; + + case MO_SL: + case MO_UL: + tcg_out_opc_imm(s, lw1, lo, base, 0); + tcg_out_opc_imm(s, lw2, lo, base, 3); + if (TCG_TARGET_REG_BITS =3D=3D 64 && is_64 && !sgn) { + tcg_out_ext32u(s, lo, lo); + } + break; + + case MO_UL | MO_BSWAP: + case MO_SL | MO_BSWAP: + if (use_mips32r2_instructions) { + tcg_out_opc_imm(s, lw1, lo, base, 0); + tcg_out_opc_imm(s, lw2, lo, base, 3); + tcg_out_bswap32(s, lo, lo, + TCG_TARGET_REG_BITS =3D=3D 64 && is_64 + ? (sgn ? TCG_BSWAP_OS : TCG_BSWAP_OZ) : 0); + } else { + const tcg_insn_unit *subr =3D + (TCG_TARGET_REG_BITS =3D=3D 64 && is_64 && !sgn + ? bswap32u_addr : bswap32_addr); + + tcg_out_opc_imm(s, lw1, TCG_TMP0, base, 0); + tcg_out_bswap_subr(s, subr); + /* delay slot */ + tcg_out_opc_imm(s, lw2, TCG_TMP0, base, 3); + tcg_out_mov(s, is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32, lo, TCG_TM= P3); + } + break; + + case MO_UQ: + if (TCG_TARGET_REG_BITS =3D=3D 64) { + tcg_out_opc_imm(s, ld1, lo, base, 0); + tcg_out_opc_imm(s, ld2, lo, base, 7); + } else { + tcg_out_opc_imm(s, lw1, MIPS_BE ? hi : lo, base, 0 + 0); + tcg_out_opc_imm(s, lw2, MIPS_BE ? hi : lo, base, 0 + 3); + tcg_out_opc_imm(s, lw1, MIPS_BE ? lo : hi, base, 4 + 0); + tcg_out_opc_imm(s, lw2, MIPS_BE ? lo : hi, base, 4 + 3); + } + break; + + case MO_UQ | MO_BSWAP: + if (TCG_TARGET_REG_BITS =3D=3D 64) { + if (use_mips32r2_instructions) { + tcg_out_opc_imm(s, ld1, lo, base, 0); + tcg_out_opc_imm(s, ld2, lo, base, 7); + tcg_out_bswap64(s, lo, lo); + } else { + tcg_out_opc_imm(s, ld1, TCG_TMP0, base, 0); + tcg_out_bswap_subr(s, bswap64_addr); + /* delay slot */ + tcg_out_opc_imm(s, ld2, TCG_TMP0, base, 7); + tcg_out_mov(s, TCG_TYPE_I64, lo, TCG_TMP3); + } + } else if (use_mips32r2_instructions) { + tcg_out_opc_imm(s, lw1, TCG_TMP0, base, 0 + 0); + tcg_out_opc_imm(s, lw2, TCG_TMP0, base, 0 + 3); + tcg_out_opc_imm(s, lw1, TCG_TMP1, base, 4 + 0); + tcg_out_opc_imm(s, lw2, TCG_TMP1, base, 4 + 3); + tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, TCG_TMP0); + tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, TCG_TMP1); + tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? lo : hi, TCG_TMP0, 16); + tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? hi : lo, TCG_TMP1, 16); + } else { + tcg_out_opc_imm(s, lw1, TCG_TMP0, base, 0 + 0); + tcg_out_bswap_subr(s, bswap32_addr); + /* delay slot */ + tcg_out_opc_imm(s, lw2, TCG_TMP0, base, 0 + 3); + tcg_out_opc_imm(s, lw1, TCG_TMP0, base, 4 + 0); + tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? lo : hi, TCG_TMP3); + tcg_out_bswap_subr(s, bswap32_addr); + /* delay slot */ + tcg_out_opc_imm(s, lw2, TCG_TMP0, base, 4 + 3); + tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? hi : lo, TCG_TMP3); + } + break; + + default: + g_assert_not_reached(); + } +} + static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg addr_regl, addr_regh __attribute__((unused)); @@ -1438,6 +1644,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGA= rg *args, bool is_64) MemOp opc; #if defined(CONFIG_SOFTMMU) tcg_insn_unit *label_ptr[2]; +#else + unsigned a_bits, s_bits; #endif TCGReg base =3D TCG_REG_A0; =20 @@ -1467,7 +1675,27 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCG= Arg *args, bool is_64) } else { tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl= ); } - tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64); + a_bits =3D get_alignment_bits(opc); + s_bits =3D opc & MO_SIZE; + /* + * R6 removes the left/right instructions but requires the + * system to support misaligned memory accesses. + */ + if (use_mips32r6_instructions) { + if (a_bits) { + tcg_out_test_alignment(s, true, addr_regl, addr_regh, a_bits); + } + tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64); + } else { + if (a_bits && a_bits !=3D s_bits) { + tcg_out_test_alignment(s, true, addr_regl, addr_regh, a_bits); + } + if (a_bits >=3D s_bits) { + tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_= 64); + } else { + tcg_out_qemu_ld_unalign(s, data_regl, data_regh, base, opc, is= _64); + } + } #endif } =20 @@ -1532,6 +1760,79 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TC= GReg lo, TCGReg hi, } } =20 +static void __attribute__((unused)) +tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi, + TCGReg base, MemOp opc) +{ + const MIPSInsn sw1 =3D MIPS_BE ? OPC_SWL : OPC_SWR; + const MIPSInsn sw2 =3D MIPS_BE ? OPC_SWR : OPC_SWL; + const MIPSInsn sd1 =3D MIPS_BE ? OPC_SDL : OPC_SDR; + const MIPSInsn sd2 =3D MIPS_BE ? OPC_SDR : OPC_SDL; + + /* Don't clutter the code below with checks to avoid bswapping ZERO. = */ + if ((lo | hi) =3D=3D 0) { + opc &=3D ~MO_BSWAP; + } + + switch (opc & (MO_SIZE | MO_BSWAP)) { + case MO_16 | MO_BE: + tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, lo, 8); + tcg_out_opc_imm(s, OPC_SB, TCG_TMP0, base, 0); + tcg_out_opc_imm(s, OPC_SB, lo, base, 1); + break; + + case MO_16 | MO_LE: + tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, lo, 8); + tcg_out_opc_imm(s, OPC_SB, lo, base, 0); + tcg_out_opc_imm(s, OPC_SB, TCG_TMP0, base, 1); + break; + + case MO_32 | MO_BSWAP: + tcg_out_bswap32(s, TCG_TMP3, lo, 0); + lo =3D TCG_TMP3; + /* fall through */ + case MO_32: + tcg_out_opc_imm(s, sw1, lo, base, 0); + tcg_out_opc_imm(s, sw2, lo, base, 3); + break; + + case MO_64 | MO_BSWAP: + if (TCG_TARGET_REG_BITS =3D=3D 64) { + tcg_out_bswap64(s, TCG_TMP3, lo); + lo =3D TCG_TMP3; + } else if (use_mips32r2_instructions) { + tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, MIPS_BE ? hi : lo); + tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, MIPS_BE ? lo : hi); + tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP0, TCG_TMP0, 16); + tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP1, TCG_TMP1, 16); + hi =3D MIPS_BE ? TCG_TMP0 : TCG_TMP1; + lo =3D MIPS_BE ? TCG_TMP1 : TCG_TMP0; + } else { + tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? lo : hi, 0); + tcg_out_opc_imm(s, sw1, TCG_TMP3, base, 0); + tcg_out_opc_imm(s, sw2, TCG_TMP3, base, 3); + tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? hi : lo, 0); + tcg_out_opc_imm(s, sw1, TCG_TMP3, base, 4); + tcg_out_opc_imm(s, sw2, TCG_TMP3, base, 7); + break; + } + /* fall through */ + case MO_64: + if (TCG_TARGET_REG_BITS =3D=3D 64) { + tcg_out_opc_imm(s, sd1, lo, base, 0); + tcg_out_opc_imm(s, sd2, lo, base, 7); + } else { + tcg_out_opc_imm(s, sw1, MIPS_BE ? hi : lo, base, 0); + tcg_out_opc_imm(s, sw2, MIPS_BE ? hi : lo, base, 3); + tcg_out_opc_imm(s, sw1, MIPS_BE ? lo : hi, base, 4); + tcg_out_opc_imm(s, sw2, MIPS_BE ? lo : hi, base, 7); + } + break; + + default: + tcg_abort(); + } +} static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg addr_regl, addr_regh __attribute__((unused)); @@ -1540,6 +1841,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGA= rg *args, bool is_64) MemOp opc; #if defined(CONFIG_SOFTMMU) tcg_insn_unit *label_ptr[2]; +#else + unsigned a_bits, s_bits; #endif TCGReg base =3D TCG_REG_A0; =20 @@ -1558,7 +1861,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGA= rg *args, bool is_64) data_regl, data_regh, addr_regl, addr_regh, s->code_ptr, label_ptr); #else - base =3D TCG_REG_A0; if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { tcg_out_ext32u(s, base, addr_regl); addr_regl =3D base; @@ -1570,7 +1872,27 @@ static void tcg_out_qemu_st(TCGContext *s, const TCG= Arg *args, bool is_64) } else { tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl= ); } - tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); + a_bits =3D get_alignment_bits(opc); + s_bits =3D opc & MO_SIZE; + /* + * R6 removes the left/right instructions but requires the + * system to support misaligned memory accesses. + */ + if (use_mips32r6_instructions) { + if (a_bits) { + tcg_out_test_alignment(s, true, addr_regl, addr_regh, a_bits); + } + tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); + } else { + if (a_bits && a_bits !=3D s_bits) { + tcg_out_test_alignment(s, true, addr_regl, addr_regh, a_bits); + } + if (a_bits >=3D s_bits) { + tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); + } else { + tcg_out_qemu_st_unalign(s, data_regl, data_regh, base, opc); + } + } #endif } =20 --=20 2.25.1 From nobody Fri May 17 10:13:16 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1643772770; cv=none; d=zohomail.com; s=zohoarc; b=oKKgGVzJTL+jqWbd63YPdVBo293ZO6/YGfVOPWv/uhH+JBwdtq+2Y0caqbxibJj58bJ+wy5tEQhcoGPf26/N6gPuWoZSiymCwSwUqtOrjsRy08QR7wtIXMwtOqZzruQ0ZATLMBPksmcnrYQgN4Ydox/aq3OjmH0L5LjGUc5tW9U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1643772770; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=AWk5arwzigx4IYhCFhEdBD+ecvW8WIrSGYvBp6HbTEY=; b=lVSZwKtwrKunWAiuXWqbs6ppLV79GfMuIa3NlxtHTJUW3tHE1I4qIv2c6uW1RtUc3LlzoV6bn+trmvBiU/Zn0H+d74x+j0j3Z/FNv+KbAXDmH54JYAlQzVRlkyPPQRu0ySOL3aaIOMJ+Jq0E9EpJIgHah0IMZSlB1UW5pGIKqMA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1643772770642440.8604244475654; Tue, 1 Feb 2022 19:32:50 -0800 (PST) Received: from localhost ([::1]:42684 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nF6O1-0000ON-Jc for importer@patchew.org; Tue, 01 Feb 2022 22:32:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58934) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nF2mA-0001Ak-RH for qemu-devel@nongnu.org; Tue, 01 Feb 2022 18:41:32 -0500 Received: from [2607:f8b0:4864:20::533] (port=36473 helo=mail-pg1-x533.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nF2m6-000730-TY for qemu-devel@nongnu.org; Tue, 01 Feb 2022 18:41:30 -0500 Received: by mail-pg1-x533.google.com with SMTP id e9so16830806pgb.3 for ; Tue, 01 Feb 2022 15:41:19 -0800 (PST) Received: from stoup.modem ([2001:8003:3a49:fd00:91e3:5d6a:70ac:f94c]) by smtp.gmail.com with ESMTPSA id g9sm16495641pgi.84.2022.02.01.15.41.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 15:41:17 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=AWk5arwzigx4IYhCFhEdBD+ecvW8WIrSGYvBp6HbTEY=; b=s0F1RaJlJHb+3FLuvSBN1o8g9/tS5q31NCDYXlXhMi+ruseHvXacwDav5GgpKREYzt B0tRPiMFf+N0ESqvji+ESjb2BwJq3CMpJ5Crq/HvGKhptm0lYsW4HTeitJMQUJ4Uf2F7 FSG4DmYH6lIwytJiR87RPr/91xyA6eC498gMIHpW+Z0IXCmaaQ75r6qN/g4eQliiejkk b3HgyjqHZCdmjkuphXvAjvWDHPlERWHzrickPge4wlt0Tk7VspjoyNeeGjWFUJcDwcxJ fX3ijo9k1f8kRBbM3pqJoKn4OlK1qmMXq8cvZhiOuFZntEhRf45w74Ypfoe68ermvwOX E7Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AWk5arwzigx4IYhCFhEdBD+ecvW8WIrSGYvBp6HbTEY=; b=HVXk9gzNxkW1MxhaEC/5mSLZ+QIvFU+LWDrXqn8YWxH2FcQEPU9vinPnrO3zTAg8Iv 7sb89KaQ2PD9k8T7qyv01vuy+kK3APU+G2ezDxxF2mONtP43/Spbn2JE6b/3eQuySvaO j8+fjzxg19Q3tsb2WkgB59Rpl+QoiWleq9dn0coOvnEyjQ10i15M0ZbO0GFUkdp/rQWw 9HraU8FYNYhQxRkYEgylKBFbsNmebUzPnyH8wGHgAjql/0WUEsK+dTM12UPRjdNKFr+u q0I8Ar7BiC/00CjhWVnYQTI6IBWwxNaZH/RnCe7E7YycydNpeeMLJ4nbM1t7J26tqOMR s+iw== X-Gm-Message-State: AOAM530l3im6i8GZAHjpakCukQ1+J4h3A3BC3m5Xkw8ND43iQN9f4qgH OdjMcgDyy4wx4d1Xiy7aJAeAZAjysY/UfC0r X-Google-Smtp-Source: ABdhPJzrftUNF68mYynNqzUU8z7NaMggaUgtpplkVb1mnX//zztkqaFLB7Pwor/UlUChboeIICljNw== X-Received: by 2002:a63:565f:: with SMTP id g31mr22489007pgm.167.1643758878272; Tue, 01 Feb 2022 15:41:18 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v5 2/2] tcg/mips: Support unaligned access for softmmu Date: Wed, 2 Feb 2022 10:41:07 +1100 Message-Id: <20220201234107.316487-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220201234107.316487-1-richard.henderson@linaro.org> References: <20220201234107.316487-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::533 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x533.google.com X-Spam_score_int: -12 X-Spam_score: -1.3 X-Spam_bar: - X-Spam_report: (-1.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, f4bug@amsat.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1643772772987100001 Content-Type: text/plain; charset="utf-8" We can use the routines just added for user-only to emit unaligned accesses in softmmu mode too. Signed-off-by: Richard Henderson Reviewed-by: Jiaxun Yang Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Jiaxun Yang --- tcg/mips/tcg-target.c.inc | 91 ++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 7d706df39c..3bf29c2f77 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -1134,8 +1134,10 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg b= ase, TCGReg addrl, tcg_insn_unit *label_ptr[2], bool is_load) { MemOp opc =3D get_memop(oi); - unsigned s_bits =3D opc & MO_SIZE; unsigned a_bits =3D get_alignment_bits(opc); + unsigned s_bits =3D opc & MO_SIZE; + unsigned a_mask =3D (1 << a_bits) - 1; + unsigned s_mask =3D (1 << s_bits) - 1; int mem_index =3D get_mmuidx(oi); int fast_off =3D TLB_MASK_TABLE_OFS(mem_index); int mask_off =3D fast_off + offsetof(CPUTLBDescFast, mask); @@ -1143,7 +1145,7 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg ba= se, TCGReg addrl, int add_off =3D offsetof(CPUTLBEntry, addend); int cmp_off =3D (is_load ? offsetof(CPUTLBEntry, addr_read) : offsetof(CPUTLBEntry, addr_write)); - target_ulong mask; + target_ulong tlb_mask; =20 /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */ tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off); @@ -1157,27 +1159,13 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg = base, TCGReg addrl, /* Add the tlb_table pointer, creating the CPUTLBEntry address in TMP3= . */ tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP3, TCG_TMP3, TCG_TMP1); =20 - /* We don't currently support unaligned accesses. - We could do so with mips32r6. */ - if (a_bits < s_bits) { - a_bits =3D s_bits; - } - - /* Mask the page bits, keeping the alignment bits to compare against. = */ - mask =3D (target_ulong)TARGET_PAGE_MASK | ((1 << a_bits) - 1); - /* Load the (low-half) tlb comparator. */ if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { - tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3, cmp_off + LO_OFF); - tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1, mask); + tcg_out_ldst(s, OPC_LW, TCG_TMP0, TCG_TMP3, cmp_off + LO_OFF); } else { tcg_out_ldst(s, (TARGET_LONG_BITS =3D=3D 64 ? OPC_LD : TCG_TARGET_REG_BITS =3D=3D 64 ? OPC_LWU : OPC_L= W), TCG_TMP0, TCG_TMP3, cmp_off); - tcg_out_movi(s, TCG_TYPE_TL, TCG_TMP1, mask); - /* No second compare is required here; - load the tlb addend for the fast path. */ - tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_TMP3, add_off); } =20 /* Zero extend a 32-bit guest address for a 64-bit host. */ @@ -1185,7 +1173,25 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg b= ase, TCGReg addrl, tcg_out_ext32u(s, base, addrl); addrl =3D base; } - tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl); + + /* + * Mask the page bits, keeping the alignment bits to compare against. + * For unaligned accesses, compare against the end of the access to + * verify that it does not cross a page boundary. + */ + tlb_mask =3D (target_ulong)TARGET_PAGE_MASK | a_mask; + tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1, tlb_mask); + if (a_mask >=3D s_mask) { + tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl); + } else { + tcg_out_opc_imm(s, ALIAS_PADDI, TCG_TMP2, addrl, s_mask - a_mask); + tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP2); + } + + if (TCG_TARGET_REG_BITS >=3D TARGET_LONG_BITS) { + /* Load the tlb addend for the fast path. */ + tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_TMP3, add_off); + } =20 label_ptr[0] =3D s->code_ptr; tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0); @@ -1193,7 +1199,7 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg ba= se, TCGReg addrl, /* Load and test the high half tlb comparator. */ if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { /* delay slot */ - tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3, cmp_off + HI_OFF); + tcg_out_ldst(s, OPC_LW, TCG_TMP0, TCG_TMP3, cmp_off + HI_OFF); =20 /* Load the tlb addend for the fast path. */ tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_TMP3, add_off); @@ -1515,8 +1521,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCG= Reg lo, TCGReg hi, } } =20 -static void __attribute__((unused)) -tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi, +static void tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi, TCGReg base, MemOp opc, bool is_64) { const MIPSInsn lw1 =3D MIPS_BE ? OPC_LWL : OPC_LWR; @@ -1645,8 +1650,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGA= rg *args, bool is_64) #if defined(CONFIG_SOFTMMU) tcg_insn_unit *label_ptr[2]; #else - unsigned a_bits, s_bits; #endif + unsigned a_bits, s_bits; TCGReg base =3D TCG_REG_A0; =20 data_regl =3D *args++; @@ -1655,10 +1660,20 @@ static void tcg_out_qemu_ld(TCGContext *s, const TC= GArg *args, bool is_64) addr_regh =3D (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); oi =3D *args++; opc =3D get_memop(oi); + a_bits =3D get_alignment_bits(opc); + s_bits =3D opc & MO_SIZE; =20 + /* + * R6 removes the left/right instructions but requires the + * system to support misaligned memory accesses. + */ #if defined(CONFIG_SOFTMMU) tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 1); - tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64); + if (use_mips32r6_instructions || a_bits >=3D s_bits) { + tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64); + } else { + tcg_out_qemu_ld_unalign(s, data_regl, data_regh, base, opc, is_64); + } add_qemu_ldst_label(s, 1, oi, (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32), data_regl, data_regh, addr_regl, addr_regh, @@ -1675,12 +1690,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCG= Arg *args, bool is_64) } else { tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl= ); } - a_bits =3D get_alignment_bits(opc); - s_bits =3D opc & MO_SIZE; - /* - * R6 removes the left/right instructions but requires the - * system to support misaligned memory accesses. - */ if (use_mips32r6_instructions) { if (a_bits) { tcg_out_test_alignment(s, true, addr_regl, addr_regh, a_bits); @@ -1760,8 +1769,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCG= Reg lo, TCGReg hi, } } =20 -static void __attribute__((unused)) -tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi, +static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi, TCGReg base, MemOp opc) { const MIPSInsn sw1 =3D MIPS_BE ? OPC_SWL : OPC_SWR; @@ -1841,9 +1849,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGA= rg *args, bool is_64) MemOp opc; #if defined(CONFIG_SOFTMMU) tcg_insn_unit *label_ptr[2]; -#else - unsigned a_bits, s_bits; #endif + unsigned a_bits, s_bits; TCGReg base =3D TCG_REG_A0; =20 data_regl =3D *args++; @@ -1852,10 +1859,20 @@ static void tcg_out_qemu_st(TCGContext *s, const TC= GArg *args, bool is_64) addr_regh =3D (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); oi =3D *args++; opc =3D get_memop(oi); + a_bits =3D get_alignment_bits(opc); + s_bits =3D opc & MO_SIZE; =20 + /* + * R6 removes the left/right instructions but requires the + * system to support misaligned memory accesses. + */ #if defined(CONFIG_SOFTMMU) tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 0); - tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); + if (use_mips32r6_instructions || a_bits >=3D s_bits) { + tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); + } else { + tcg_out_qemu_st_unalign(s, data_regl, data_regh, base, opc); + } add_qemu_ldst_label(s, 0, oi, (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32), data_regl, data_regh, addr_regl, addr_regh, @@ -1872,12 +1889,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCG= Arg *args, bool is_64) } else { tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl= ); } - a_bits =3D get_alignment_bits(opc); - s_bits =3D opc & MO_SIZE; - /* - * R6 removes the left/right instructions but requires the - * system to support misaligned memory accesses. - */ if (use_mips32r6_instructions) { if (a_bits) { tcg_out_test_alignment(s, true, addr_regl, addr_regh, a_bits); --=20 2.25.1