From patchwork Sat May 18 19:01:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 164446 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3703464ili; Sat, 18 May 2019 12:07:46 -0700 (PDT) X-Google-Smtp-Source: APXvYqxhUnOLywPIuPkTwFrQ8iGJQHdR1KboLAsmU8GmGkoJRv/yXxvIW5F00zg49TE2yez42lBv X-Received: by 2002:a17:906:1315:: with SMTP id w21mr15204165ejb.193.1558206466486; Sat, 18 May 2019 12:07:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558206466; cv=none; d=google.com; s=arc-20160816; b=J6b1WdSeRM+bj4Ti3yKv2r5lV3o6NsAtq9TQ4nhG2NhqNNCj2qQgkvI0wtZqkZQoJq HuKIRd4faKNJviOQ9SYBO9X41WZHV7RCfdSvvgHascGFMzMezwjf+9gWTWvo3F4D8V4B AHe6or+HqzljJvuwWnnSp/o+DcpaCjoVweul+tl0DkFVX4gAmlYLpj+cnBsKY2E/WOeI +tBTF8vlnlXLWNFyec4IU9pMZBn+1xkiUaoKufRBHQhGpNurjCU9wMLcodIB0YuR3pVk 4EJ+va2Qrbn6S51M+VAK95gwYHyfFjB2SNyU1XqyVWKMkygnOA28CyuZAJ1EFvgi+9Fp 8Eyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=/D6aLozHwnS1sPI8iNsL3pMxewPkp4IUhb3tHD+DOe4=; b=Nx45bb8fs+R3ds0m3fIB4RbzanA93Aylv5Eb94AOPPYRNp0wR7Wujal6eo/K8eso7J /ialMOAKkL+TJZVSqJev2weI5WyfQAx1K9sQimBWtgpJmB+V1wSA49ca5giVNJpXyX2Y xhPm/mFwz3t8GeANu8OchD8/DoC1SRjPetUp0HC50sSOYv5RO44tdZI82KuM/y6ksH6s jf85RhnK614lZkE/AZBgVg2EBuyLOfVl+Fez0WWlzSjMBgcjqbNZlZMaDhM8/RXqmFcY c1kMG00dWCeywINfsHpMqtEhmH/pJtkicmcD7n9gu09b2pbPHss7EUqYIzcXADBFKBe0 Ai+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=DX98WC+w; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id i21si141380ejh.204.2019.05.18.12.07.46 for (version=TLS1 cipher=AES128-SHA bits=128/128); Sat, 18 May 2019 12:07:46 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=DX98WC+w; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:37609 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hS4gL-0005jv-9l for patch@linaro.org; Sat, 18 May 2019 15:07:45 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59166) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hS4dM-0002lS-Tm for qemu-devel@nongnu.org; Sat, 18 May 2019 15:04:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hS4b5-0002kL-S5 for qemu-devel@nongnu.org; Sat, 18 May 2019 15:02:21 -0400 Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]:34614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hS4b4-0002iU-4L for qemu-devel@nongnu.org; Sat, 18 May 2019 15:02:19 -0400 Received: by mail-pf1-x444.google.com with SMTP id n19so5269665pfa.1 for ; Sat, 18 May 2019 12:02:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=/D6aLozHwnS1sPI8iNsL3pMxewPkp4IUhb3tHD+DOe4=; b=DX98WC+w6H36YBm5EDtBPEhzGilvTj4uIwQ9+YO9lP0LLRhpO7KtG4L/fqqkIpuF5b 8uSa4ytNJiNTh/0+dFzuB/v+kbaokbyrShOsd1fLa0KNO2/1d979NH2+MQZaVEPSOgEh qZVAVnlxbmVrF0yrVyZFSCF8uUPBiS8Qgkl8xmUg35qCVpcJWv/E4f4dSPcxhGrzIInH G4WwATWsYJGX95MDYS9c1M30vholRxwjGsM+zVS/MepbMP+nQNaiKSyxEdTi1+myMCEQ uQRMWiyM6wdvjNAaGrFfYlYsEIaLwpiJlyNG+dWKZm+oNr8r0q6rU9fYESYPH/57jvAU IBug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=/D6aLozHwnS1sPI8iNsL3pMxewPkp4IUhb3tHD+DOe4=; b=uasVNDWUifvjb+T+awO7euS4AiCpcKoVxPNf3lOpBxrZCg8KJEOBXEvuYFAEIea7S7 Co2VoM43YkCWCjFzogHkbWJ7B+K935yu9Dfe25T8Q5y2IP1/Lt03rPXQ7ngw1y0EsbHB KmK+BFhxHVqnCi+cH8bILvdmwCkVogkKVt+ZtOoZ5Uf5bYuaWpolcWZzOq5Cjxd3H6QW 52lDLRGqKX62YQgJoiY1xXwkfMJNiPya/MvddL3qXZuPKwNc2dx4RZz19+ZcawTfi1Ma I0AJGfM+NXVjTZukE3hUXzoT6jW9/kS+xTx8K9ARQr58GvOj3DVCOuOcxxhoWAjdAupQ RZ2g== X-Gm-Message-State: APjAAAWfSvb4fQzuqctrMXDIlvWwyneXHs0cPfxzU9w9X608ZcNnDT3u iskdHdVeJ0aujuILiJSPeJeQUPkwxio= X-Received: by 2002:a65:60c7:: with SMTP id r7mr63134180pgv.22.1558206135452; Sat, 18 May 2019 12:02:15 -0700 (PDT) Received: from localhost.localdomain (97-113-13-231.tukw.qwest.net. [97.113.13.231]) by smtp.gmail.com with ESMTPSA id m9sm2751274pgd.23.2019.05.18.12.02.14 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 18 May 2019 12:02:14 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 18 May 2019 12:01:53 -0700 Message-Id: <20190518190157.21255-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190518190157.21255-1-richard.henderson@linaro.org> References: <20190518190157.21255-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::444 Subject: [Qemu-devel] [PATCH 12/16] tcg/aarch64: Split up is_fimm X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" There are several sub-classes of vector immediate, and only MOVI can use them all. This will enable usage of MVNI and ORRI, which use progressively fewer sub-classes. This patch adds no new functionality, merely splits the function and moves part of the logic into tcg_out_dupi_vec. Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.inc.c | 205 ++++++++++++++++++++--------------- 1 file changed, 120 insertions(+), 85 deletions(-) -- 2.17.1 diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c index e99149cda7..1422dfebe2 100644 --- a/tcg/aarch64/tcg-target.inc.c +++ b/tcg/aarch64/tcg-target.inc.c @@ -190,103 +190,86 @@ static inline bool is_limm(uint64_t val) return (val & (val - 1)) == 0; } -/* Match a constant that is valid for vectors. */ -static bool is_fimm(uint64_t v64, int *op, int *cmode, int *imm8) +/* Return true if v16 is a valid 16-bit shifted immediate. */ +static bool is_shimm16(uint16_t v16, int *cmode, int *imm8) { - int i; - - *op = 0; - /* Match replication across 8 bits. */ - if (v64 == dup_const(MO_8, v64)) { - *cmode = 0xe; - *imm8 = v64 & 0xff; + if (v16 == (v16 & 0xff)) { + *cmode = 0x8; + *imm8 = v16 & 0xff; + return true; + } else if (v16 == (v16 & 0xff00)) { + *cmode = 0xa; + *imm8 = v16 >> 8; return true; } - /* Match replication across 16 bits. */ - if (v64 == dup_const(MO_16, v64)) { - uint16_t v16 = v64; + return false; +} - if (v16 == (v16 & 0xff)) { - *cmode = 0x8; - *imm8 = v16 & 0xff; - return true; - } else if (v16 == (v16 & 0xff00)) { - *cmode = 0xa; - *imm8 = v16 >> 8; - return true; - } +/* Return true if v32 is a valid 32-bit shifted immediate. */ +static bool is_shimm32(uint32_t v32, int *cmode, int *imm8) +{ + if (v32 == (v32 & 0xff)) { + *cmode = 0x0; + *imm8 = v32 & 0xff; + return true; + } else if (v32 == (v32 & 0xff00)) { + *cmode = 0x2; + *imm8 = (v32 >> 8) & 0xff; + return true; + } else if (v32 == (v32 & 0xff0000)) { + *cmode = 0x4; + *imm8 = (v32 >> 16) & 0xff; + return true; + } else if (v32 == (v32 & 0xff000000)) { + *cmode = 0x6; + *imm8 = v32 >> 24; + return true; } - /* Match replication across 32 bits. */ - if (v64 == dup_const(MO_32, v64)) { - uint32_t v32 = v64; + return false; +} - if (v32 == (v32 & 0xff)) { - *cmode = 0x0; - *imm8 = v32 & 0xff; - return true; - } else if (v32 == (v32 & 0xff00)) { - *cmode = 0x2; - *imm8 = (v32 >> 8) & 0xff; - return true; - } else if (v32 == (v32 & 0xff0000)) { - *cmode = 0x4; - *imm8 = (v32 >> 16) & 0xff; - return true; - } else if (v32 == (v32 & 0xff000000)) { - *cmode = 0x6; - *imm8 = v32 >> 24; - return true; - } else if ((v32 & 0xffff00ff) == 0xff) { - *cmode = 0xc; - *imm8 = (v32 >> 8) & 0xff; - return true; - } else if ((v32 & 0xff00ffff) == 0xffff) { - *cmode = 0xd; - *imm8 = (v32 >> 16) & 0xff; - return true; - } - /* Match forms of a float32. */ - if (extract32(v32, 0, 19) == 0 - && (extract32(v32, 25, 6) == 0x20 - || extract32(v32, 25, 6) == 0x1f)) { - *cmode = 0xf; - *imm8 = (extract32(v32, 31, 1) << 7) - | (extract32(v32, 25, 1) << 6) - | extract32(v32, 19, 6); - return true; - } +/* Return true if v32 is a valid 32-bit shifting ones immediate. */ +static bool is_soimm32(uint32_t v32, int *cmode, int *imm8) +{ + if ((v32 & 0xffff00ff) == 0xff) { + *cmode = 0xc; + *imm8 = (v32 >> 8) & 0xff; + return true; + } else if ((v32 & 0xff00ffff) == 0xffff) { + *cmode = 0xd; + *imm8 = (v32 >> 16) & 0xff; + return true; } - /* Match forms of a float64. */ + return false; +} + +/* Return true if v32 is a valid float32 immediate. */ +static bool is_fimm32(uint32_t v32, int *cmode, int *imm8) +{ + if (extract32(v32, 0, 19) == 0 + && (extract32(v32, 25, 6) == 0x20 + || extract32(v32, 25, 6) == 0x1f)) { + *cmode = 0xf; + *imm8 = (extract32(v32, 31, 1) << 7) + | (extract32(v32, 25, 1) << 6) + | extract32(v32, 19, 6); + return true; + } + return false; +} + +/* Return true if v64 is a valid float64 immediate. */ +static bool is_fimm64(uint64_t v64, int *cmode, int *imm8) +{ if (extract64(v64, 0, 48) == 0 && (extract64(v64, 54, 9) == 0x100 || extract64(v64, 54, 9) == 0x0ff)) { *cmode = 0xf; - *op = 1; *imm8 = (extract64(v64, 63, 1) << 7) | (extract64(v64, 54, 1) << 6) | extract64(v64, 48, 6); return true; } - /* Match bytes of 0x00 and 0xff. */ - for (i = 0; i < 64; i += 8) { - uint64_t byte = extract64(v64, i, 8); - if (byte != 0 && byte != 0xff) { - break; - } - } - if (i == 64) { - *cmode = 0xe; - *op = 1; - *imm8 = (extract64(v64, 0, 1) << 0) - | (extract64(v64, 8, 1) << 1) - | (extract64(v64, 16, 1) << 2) - | (extract64(v64, 24, 1) << 3) - | (extract64(v64, 32, 1) << 4) - | (extract64(v64, 40, 1) << 5) - | (extract64(v64, 48, 1) << 6) - | (extract64(v64, 56, 1) << 7); - return true; - } return false; } @@ -817,11 +800,63 @@ static void tcg_out_logicali(TCGContext *s, AArch64Insn insn, TCGType ext, static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg rd, tcg_target_long v64) { - int op, cmode, imm8; + bool q = type == TCG_TYPE_V128; + int cmode, imm8, i; - if (is_fimm(v64, &op, &cmode, &imm8)) { - tcg_out_insn(s, 3606, MOVI, type == TCG_TYPE_V128, rd, op, cmode, imm8); - } else if (type == TCG_TYPE_V128) { + /* Test all bytes equal first. */ + if (v64 == dup_const(MO_8, v64)) { + imm8 = (uint8_t)v64; + tcg_out_insn(s, 3606, MOVI, q, rd, 0, 0xe, imm8); + return; + } + + /* + * Test all bytes 0x00 or 0xff second. This can match cases that + * might otherwise take 2 or 3 insns for MO_16 or MO_32 below. + */ + for (i = imm8 = 0; i < 8; i++) { + uint8_t byte = v64 >> (i * 8); + if (byte == 0xff) { + imm8 |= 1 << i; + } else if (byte != 0) { + goto fail_bytes; + } + } + tcg_out_insn(s, 3606, MOVI, q, rd, 1, 0xe, imm8); + return; + fail_bytes: + + /* + * Tests for various replications. For each element width, if we + * cannot find an expansion there's no point checking a larger + * width because we already know by replication it cannot match. + */ + if (v64 == dup_const(MO_16, v64)) { + uint16_t v16 = v64; + + if (is_shimm16(v16, &cmode, &imm8)) { + tcg_out_insn(s, 3606, MOVI, q, rd, 0, cmode, imm8); + return; + } + } else if (v64 == dup_const(MO_32, v64)) { + uint32_t v32 = v64; + + if (is_shimm32(v32, &cmode, &imm8) || + is_soimm32(v32, &cmode, &imm8) || + is_fimm32(v32, &cmode, &imm8)) { + tcg_out_insn(s, 3606, MOVI, q, rd, 0, cmode, imm8); + return; + } + } else if (is_fimm64(v64, &cmode, &imm8)) { + tcg_out_insn(s, 3606, MOVI, q, rd, 1, cmode, imm8); + return; + } + + /* + * As a last resort, load from the constant pool. Sadly there + * is no LD1R (literal), so store the full 16-byte vector. + */ + if (type == TCG_TYPE_V128) { new_pool_l2(s, R_AARCH64_CONDBR19, s->code_ptr, 0, v64, v64); tcg_out_insn(s, 3305, LDR_v128, 0, rd); } else {