From patchwork Mon Nov 5 07:29:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 197154 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A88E12C00DC for ; Mon, 5 Nov 2012 18:33:55 +1100 (EST) Received: from localhost ([::1]:43952 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVH9A-0007hF-OL for incoming@patchwork.ozlabs.org; Mon, 05 Nov 2012 02:31:00 -0500 Received: from eggs.gnu.org ([208.118.235.92]:35935) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVH8G-0005FR-6F for qemu-devel@nongnu.org; Mon, 05 Nov 2012 02:30:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TVH8D-0005Aj-AL for qemu-devel@nongnu.org; Mon, 05 Nov 2012 02:30:03 -0500 Received: from hall.aurel32.net ([2001:470:1f15:c4f::1]:49882) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVH8D-0005Aa-3V for qemu-devel@nongnu.org; Mon, 05 Nov 2012 02:30:01 -0500 Received: from 37-8-191-163.coucou-networks.fr ([37.8.191.163] helo=ohm.aurel32.net) by hall.aurel32.net with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1TVH8B-0003C8-8V; Mon, 05 Nov 2012 08:29:59 +0100 Received: from aurel32 by ohm.aurel32.net with local (Exim 4.80) (envelope-from ) id 1TVH7z-00055G-RH; Mon, 05 Nov 2012 08:29:47 +0100 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Mon, 5 Nov 2012 08:29:44 +0100 Message-Id: <1352100585-19415-3-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1352100585-19415-1-git-send-email-aurelien@aurel32.net> References: <1352100585-19415-1-git-send-email-aurelien@aurel32.net> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:470:1f15:c4f::1 Cc: Peter Maydell , qemu-stable@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PATCH v3 for 1.3 2/3] tcg/arm: fix cross-endian qemu_st16 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 bswap16 TCG opcode assumes that the high bytes of the temp equal to 0 before calling it. The ARM backend implementation takes this assumption to slightly optimize the generated code. The same implementation is called for implementing the cross-endian qemu_st16 opcode, where this assumption is not true anymore. One way to fix that would be to zero the high bytes before calling it. Given the store instruction just ignore them, it is possible to provide a slightly more optimized version. With ARMv6+ the rev16 instruction does the work correctly. For lower ARM versions the patch provides a version which behaves correctly with non-zero high bytes, but fill them with junk. Cc: Andrzej Zaborowski Cc: Peter Maydell Cc: qemu-stable@nongnu.org Reviewed-by: Peter Maydell Signed-off-by: Aurelien Jarno --- tcg/arm/tcg-target.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 9550102..47612fe 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -611,6 +611,22 @@ static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn) } } +/* swap the two low bytes assuming that the two high input bytes and the + two high output bit can hold any value. */ +static inline void tcg_out_bswap16st(TCGContext *s, int cond, int rd, int rn) +{ + if (use_armv6_instructions) { + /* rev16 */ + tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn); + } else { + tcg_out_dat_reg(s, cond, ARITH_MOV, + TCG_REG_R8, 0, rn, SHIFT_IMM_LSR(8)); + tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R8, TCG_REG_R8, 0xff); + tcg_out_dat_reg(s, cond, ARITH_ORR, + rd, TCG_REG_R8, rn, SHIFT_IMM_LSL(8)); + } +} + static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn) { if (use_armv6_instructions) { @@ -1367,7 +1383,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) break; case 1: if (bswap) { - tcg_out_bswap16(s, COND_EQ, TCG_REG_R0, data_reg); + tcg_out_bswap16st(s, COND_EQ, TCG_REG_R0, data_reg); tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1); } else { tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1); @@ -1453,7 +1469,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) break; case 1: if (bswap) { - tcg_out_bswap16(s, COND_AL, TCG_REG_R0, data_reg); + tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, data_reg); tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0); } else { tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);