From patchwork Mon Aug 12 18:44:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 266622 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (unknown [IPv6:2001:4830:134:3::12]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 34A6E2C007C for ; Tue, 13 Aug 2013 04:57:23 +1000 (EST) Received: from localhost ([::1]:50556 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V8xAe-0003eV-So for incoming@patchwork.ozlabs.org; Mon, 12 Aug 2013 14:48:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53887) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V8x7R-0007Ij-0m for qemu-devel@nongnu.org; Mon, 12 Aug 2013 14:45:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V8x7I-0005Ui-CB for qemu-devel@nongnu.org; Mon, 12 Aug 2013 14:45:28 -0400 Received: from mail-pa0-x231.google.com ([2607:f8b0:400e:c03::231]:45868) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V8x7I-0005Tq-4j for qemu-devel@nongnu.org; Mon, 12 Aug 2013 14:45:20 -0400 Received: by mail-pa0-f49.google.com with SMTP id ld10so3301847pab.36 for ; Mon, 12 Aug 2013 11:45:19 -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=dFL2qCWWbkE/Ve7dBBMN7o6CNFobcrp30U7GBSrTZdU=; b=RLqZn4QkFSwcNItd6jxwdooczf6/MoE+0EBQGhAaTo6qimR2JGjm9GMsX+5uDSxkEW NSL5wLnrBYKwEUvL43p93qA38yzKHouk4y9zN6JAmfHCr/G00uE4ji1nDSS7ayBUozKQ lVqSVaJimypLKnATaslIx6jnav4FQvfxHB87J1HvdCKGDFey+ujMaWtHzic4Ubi/Jt7M DyImvwrs9G5MTAD3Y24Os0w0fQGpdSYwWv78Wp/3pdjywbp8ffZYQCHU+i2FyqHYF8Yj Fn7jK7sywWoUNHxnu7xRzN2kufsJ9RzI4ZRfnQ7nhERvbDynh8b3wIf0UVdBJfiI0F+S mUJw== X-Received: by 10.68.125.226 with SMTP id mt2mr89204pbb.115.1376333119339; Mon, 12 Aug 2013 11:45:19 -0700 (PDT) Received: from pebble.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id vz4sm5165448pab.11.2013.08.12.11.45.17 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 12 Aug 2013 11:45:18 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 12 Aug 2013 11:44:52 -0700 Message-Id: <1376333095-24385-12-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1376333095-24385-1-git-send-email-rth@twiddle.net> References: <1376333095-24385-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c03::231 Cc: claudio.fontana@huawei.com, Richard Henderson Subject: [Qemu-devel] [RFC 11/14] tcg-aarch64: Improve tcg_out_movi 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 Handle small positive and negative numbers early. Check for logical immediates. Check if using MOVN for the first set helps. Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 85 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 920c63c..02ab278 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -511,32 +511,79 @@ static inline void tcg_out_movr(TCGContext *s, AArch64Ext ext, tcg_out_aimm(s, INSN_ADDI, ext, dest, src, 0); } +static inline void tcg_out_movwi(TCGContext *s, AArch64Insn insn, + AArch64Ext ext, TCGReg rd, + uint16_t value, int shift) +{ + tcg_out32(s, insn | ext | shift << 17 | value << 5 | rd); +} + static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, tcg_target_long value) { - AArch64Insn insn = INSN_MOVZ; + tcg_target_long valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull); + AArch64Insn insn; + AArch64Ext ext; + int i, wantinv, shift; + + value &= valid; + + /* Check small positive values. */ + if ((value & ~0xffff) == 0) { + tcg_out_movwi(s, INSN_MOVZ, E32, rd, value, 0); + return; + } + + /* Check small negative values. */ + if ((~value & valid & ~0xffff) == 0) { + tcg_out_movwi(s, INSN_MOVN, EXT(type == TCG_TYPE_I64), rd, ~value, 0); + return; + } + + /* Check for bitfield immediates. */ + if ((value & ~0xffffffffull) == 0) { + i = find_bitmask32(value); + ext = E32; + } else { + i = find_bitmask64(value); + ext = E64; + } + if (i >= 0) { + tcg_out32(s, INSN_ORRI | TCG_REG_XZR << 5 | ext + | bitmask_enc[i] << 10 | rd); + return; + } - if (type == TCG_TYPE_I32) { - value = (uint32_t)value; + /* Would it take fewer insns to load the inverse? */ + wantinv = 0; + for (i = 0; i < 64; i += 16) { + if (((value >> i) & 0xffff) == 0) { + wantinv--; + } + if (((~value >> i) & 0xffff) == 0) { + wantinv++; + } } - /* Construct halfwords of the immediate with MOVZ/MOVK with LSL. - Count trailing zeros in 16 bit steps, mapping 64 to 0. Emit the - first MOVZ with the half-word immediate skipping the zeros, with - a shift (LSL) equal to this number. Then all other insns are MOVKs. - Zero the processed half-word in the value, continue until empty. - We build the final result 16bits at a time with up to 4 instructions, - but do not emit instructions for 16bit zero holes. */ - do { - unsigned shift = ctz64(value) & (63 & -16); - unsigned half = (value >> shift) & 0xffff; - AArch64Ext ext = EXT(shift >= 32); - - tcg_out32(s, insn | ext | shift << 17 | half << 5 | rd); - - insn = INSN_MOVK; + if (wantinv > 0) { + value = ~value; + insn = INSN_MOVN; + valid = -1; + } else { + insn = INSN_MOVZ; + valid = 0; + } + + /* Perform the first round specially, to handle the inverse. */ + shift = ctz64(value) & (63 & -16); + tcg_out_movwi(s, insn, ext, rd, value >> shift, shift); + value &= ~(0xffffUL << shift); + + while (value) { + shift = ctz64(value) & (63 & -16); + tcg_out_movwi(s, INSN_MOVK, ext, rd, (value ^ valid) >> shift, shift); value &= ~(0xffffUL << shift); - } while (value); + } } static inline void tcg_out_ldst_r(TCGContext *s,