From patchwork Thu Jan 6 21:54:34 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 77812 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 31166B6F07 for ; Fri, 7 Jan 2011 09:04:11 +1100 (EST) Received: from localhost ([127.0.0.1]:41505 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PaxwB-0000DM-3N for incoming@patchwork.ozlabs.org; Thu, 06 Jan 2011 17:04:03 -0500 Received: from [140.186.70.92] (port=33297 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PaxnD-00053i-EI for qemu-devel@nongnu.org; Thu, 06 Jan 2011 16:54:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PaxnB-0008G2-JE for qemu-devel@nongnu.org; Thu, 06 Jan 2011 16:54:47 -0500 Received: from hall.aurel32.net ([88.191.126.93]:43453) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PaxnB-0008Fq-Br for qemu-devel@nongnu.org; Thu, 06 Jan 2011 16:54:45 -0500 Received: from [2001:470:d4ed:0:5e26:aff:fe2b:6f5b] (helo=volta.aurel32.net) by hall.aurel32.net with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1PaxnA-0004fA-Mk; Thu, 06 Jan 2011 22:54:44 +0100 Received: from aurel32 by volta.aurel32.net with local (Exim 4.72) (envelope-from ) id 1Paxn3-0001nk-Ff; Thu, 06 Jan 2011 22:54:37 +0100 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Thu, 6 Jan 2011 22:54:34 +0100 Message-Id: <1294350874-6885-3-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1294350874-6885-1-git-send-email-aurelien@aurel32.net> References: <1294350874-6885-1-git-send-email-aurelien@aurel32.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Andrzej Zaborowski , Aurelien Jarno Subject: [Qemu-devel] [PATCH 3/3] tcg/arm: improve constant loading X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Improve constant loading in two ways: - On all ARM versions, it's possible to load 0xffffff00 = -0x100 using the mvn rd, #0. Fix the conditions. - On <= ARMv6 versions, where movw and movt are not available, load the constants using mov and orr with rotations depending on the constant to load. This is very useful for example to load constants where the low byte is 0. This reduce the generated code size by about 7%. Also fix the coding style at the same time. Cc: Andrzej Zaborowski Signed-off-by: Aurelien Jarno --- tcg/arm/tcg-target.c | 39 +++++++++++++++++++++------------------ 1 files changed, 21 insertions(+), 18 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 08c44c1..1eb5605 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -406,35 +406,38 @@ static inline void tcg_out_dat_imm(TCGContext *s, } static inline void tcg_out_movi32(TCGContext *s, - int cond, int rd, int32_t arg) + int cond, int rd, uint32_t arg) { /* TODO: This is very suboptimal, we can easily have a constant * pool somewhere after all the instructions. */ - - if (arg < 0 && arg > -0x100) - return tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0, (~arg) & 0xff); - - if (use_armv7_instructions) { + if ((int)arg < 0 && (int)arg >= -0x100) { + tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0, (~arg) & 0xff); + } else if (use_armv7_instructions) { /* use movw/movt */ /* movw */ tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12) | ((arg << 4) & 0x000f0000) | (arg & 0xfff)); - if (arg & 0xffff0000) + if (arg & 0xffff0000) { /* movt */ tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12) | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff)); - } else { - tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0, arg & 0xff); - if (arg & 0x0000ff00) - tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, - ((arg >> 8) & 0xff) | 0xc00); - if (arg & 0x00ff0000) - tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, - ((arg >> 16) & 0xff) | 0x800); - if (arg & 0xff000000) - tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, - ((arg >> 24) & 0xff) | 0x400); } + } else { + int opc = ARITH_MOV; + int rn = 0; + + do { + int i, rot; + + i = ctz32(arg) & ~1; + rot = ((32 - i) << 7) & 0xf00; + tcg_out_dat_imm(s, cond, opc, rd, rn, ((arg >> i) & 0xff) | rot); + arg &= ~(0xff << i); + + opc = ARITH_ORR; + rn = rd; + } while (arg); + } } static inline void tcg_out_mul32(TCGContext *s,