From patchwork Tue Mar 25 21:17:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 333726 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BB86B1400A1 for ; Wed, 26 Mar 2014 08:46:41 +1100 (EST) Received: from localhost ([::1]:44364 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WSZB9-0000I3-06 for incoming@patchwork.ozlabs.org; Tue, 25 Mar 2014 17:46:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33388) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WSZAa-00007s-4n for qemu-devel@nongnu.org; Tue, 25 Mar 2014 17:46:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WSZAV-0007uY-OP for qemu-devel@nongnu.org; Tue, 25 Mar 2014 17:46:04 -0400 Received: from mail-pd0-x235.google.com ([2607:f8b0:400e:c02::235]:52697) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WSYiZ-0000LF-Ti for qemu-devel@nongnu.org; Tue, 25 Mar 2014 17:17:08 -0400 Received: by mail-pd0-f181.google.com with SMTP id p10so966727pdj.40 for ; Tue, 25 Mar 2014 14:17:06 -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; bh=zZ1fTXrLGtx++/0yfq4qExuWgkrpGPWqX7/3AStAfa4=; b=urkGGsTvgs+MUeKkNBz4lm2icAFtoDWrEPl/zv8NNkd5zz99fC2+O4TsXhqRqFELKr UiZYXEIrXsKq7n8GCg6Ia4WjcoYvD4nMXhvW6FmbQtFbbJ+2NZUkQmkQgy8ZdYQZByJN x2Lab0ySwLYQZbOb4BJHrzfIj04CrFT4+Sj+ThrFT7wo4a9Lsa2HpL4473IWh9BXYFYY z7rKLkZ7wQvcms8hMGXfM9BRxeT82kOPJ1GTTRm9SqdCuF3lWiEi8dkANfZ/KlJTe77d sG2S1NrLW9+p9YFgj3SKupcP41gF1twX6THzshkyq+WX6MxZwSlQfWbxuhKZqcwfxR0I DSdw== X-Received: by 10.66.144.200 with SMTP id so8mr82201030pab.15.1395782226367; Tue, 25 Mar 2014 14:17:06 -0700 (PDT) Received: from localhost.localdomain (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id my6sm48953586pbc.36.2014.03.25.14.17.04 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 25 Mar 2014 14:17:05 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 25 Mar 2014 17:17:02 -0400 Message-Id: <1395782222-9334-1-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.8.3.1 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c02::235 Cc: Peter Maydell Subject: [Qemu-devel] [PATCH for-2.0] tcg-arm: Avoid ldrd/strd for user-only emulation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The arm ldrd/strd insns must cause alignment traps, whereas at least for armv7 ldr/str must handle unaligned operations. While this is hardly the only problem facing user-only emu, this solves one problem for i386 on armv7 emulation. Cc: Peter Maydell Cc: Andrzej Zaborowski Reported-by: Huw Davies Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell --- tcg/arm/tcg-target.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index c8884b3..a65fc65 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -60,6 +60,13 @@ static int arm_arch = __ARM_ARCH; bool use_idiv_instructions; #endif +/* ??? Ought to think about changing CONFIG_SOFTMMU to always defined. */ +#ifdef CONFIG_SOFTMMU +# define USING_SOFTMMU 1 +#else +# define USING_SOFTMMU 0 +#endif + #ifndef NDEBUG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { "%r0", @@ -1404,7 +1411,9 @@ static inline void tcg_out_qemu_ld_index(TCGContext *s, TCGMemOp opc, TCGReg dl = (bswap ? datahi : datalo); TCGReg dh = (bswap ? datalo : datahi); - if (use_armv6_instructions && (dl & 1) == 0 && dh == dl + 1) { + /* Avoid ldrd for user-only emulation, to handle unaligned. */ + if (USING_SOFTMMU && use_armv6_instructions + && (dl & 1) == 0 && dh == dl + 1) { tcg_out_ldrd_r(s, COND_AL, dl, addrlo, addend); } else if (dl != addend) { tcg_out_ld32_rwb(s, COND_AL, dl, addend, addrlo); @@ -1463,7 +1472,9 @@ static inline void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg dl = (bswap ? datahi : datalo); TCGReg dh = (bswap ? datalo : datahi); - if (use_armv6_instructions && (dl & 1) == 0 && dh == dl + 1) { + /* Avoid ldrd for user-only emulation, to handle unaligned. */ + if (USING_SOFTMMU && use_armv6_instructions + && (dl & 1) == 0 && dh == dl + 1) { tcg_out_ldrd_8(s, COND_AL, dl, addrlo, 0); } else if (dl == addrlo) { tcg_out_ld32_12(s, COND_AL, dh, addrlo, bswap ? 0 : 4); @@ -1548,12 +1559,13 @@ static inline void tcg_out_qemu_st_index(TCGContext *s, int cond, TCGMemOp opc, } break; case MO_64: + /* Avoid strd for user-only emulation, to handle unaligned. */ if (bswap) { tcg_out_bswap32(s, cond, TCG_REG_R0, datahi); tcg_out_st32_rwb(s, cond, TCG_REG_R0, addend, addrlo); tcg_out_bswap32(s, cond, TCG_REG_R0, datalo); tcg_out_st32_12(s, cond, TCG_REG_R0, addend, 4); - } else if (use_armv6_instructions + } else if (USING_SOFTMMU && use_armv6_instructions && (datalo & 1) == 0 && datahi == datalo + 1) { tcg_out_strd_r(s, cond, datalo, addrlo, addend); } else { @@ -1592,12 +1604,13 @@ static inline void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, } break; case MO_64: + /* Avoid strd for user-only emulation, to handle unaligned. */ if (bswap) { tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datahi); tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 0); tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datalo); tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 4); - } else if (use_armv6_instructions + } else if (USING_SOFTMMU && use_armv6_instructions && (datalo & 1) == 0 && datahi == datalo + 1) { tcg_out_strd_8(s, COND_AL, datalo, addrlo, 0); } else {