From patchwork Wed May 22 22:28:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 164915 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp1420200ili; Wed, 22 May 2019 15:40:45 -0700 (PDT) X-Google-Smtp-Source: APXvYqz3q0sPiYXoCYY5du3CUfs392vmQF3oMSxhNgUwwa+Dnt+eesKvxMSRMAZZQPD9pIEdnmRx X-Received: by 2002:a17:906:e101:: with SMTP id gj1mr37350911ejb.54.1558564844928; Wed, 22 May 2019 15:40:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558564844; cv=none; d=google.com; s=arc-20160816; b=EK0hHpWNU+3u4TktjFdgKz7Z025E1tvUIGAs4O2cu/fIPr/zIneExqHVlYBzRSIira PHMhyVexMZycY/cxhdK83qhh2YRfjw7+1tA5OgWA1egyt+EnZv8KlXlad+hbfsA4JFbz JHpCrvrjKzG6hfI3TljhxEDzy1P1Gw2Uv2anPXuLLgQPPhInYiUay1z9AoWH1kStlG2X nocZJhFgU2YZeGEur5EX8Nf0ZNeF7jGlKU6QgamotBVvfxF9rka91r1d5OH4vs/Mhpow lekTjoyzjxTuFJe2OXqWmUTylKVQ1YcMVYP/qpk698u4Tr2HGJ1zZof/reAp7QMzpPRK Ubyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc: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=n7M0uz/A3z/BhKhkkib1STG/Q4u6AYELqZ7Cr1KPOjCSfVqByJJPaIP2VOpUssBL0X OzlCjJt77DF6/BFSRbZOpo7rvJ3LAqKtBgytnmxvlejw1Mdgyb7q6o2SeBlvDiUcDmot x5Y/Lt8ZK4NndJYvCVnygfZCIcs1aeiA5k8yazYBkmkg6DdQGm05f2nbUPqxYosb9GhE lrOk52Bk+3k6GMJy4uoKmFUWlmfaoKp1A5QmAO+BUmf3oMVSaHN4Wfhpg60SUKZJ98k+ 0KQkSVl+O8rDHE2MAf8obV4nXHE/h12V3V0j1Is/1nvVagVf9ph2XUgBb1042Zwysas5 i/PA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=VEiP8vmV; 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 ov1si2043046ejb.320.2019.05.22.15.40.44 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 22 May 2019 15:40:44 -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=VEiP8vmV; 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]:52677 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTZud-0003mv-Rj for patch@linaro.org; Wed, 22 May 2019 18:40:43 -0400 Received: from eggs.gnu.org ([209.51.188.92]:49948) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTZj5-0003AX-8J for qemu-devel@nongnu.org; Wed, 22 May 2019 18:28:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hTZj3-0007Rh-Pe for qemu-devel@nongnu.org; Wed, 22 May 2019 18:28:47 -0400 Received: from mail-yb1-xb42.google.com ([2607:f8b0:4864:20::b42]:35999) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hTZj3-0007Na-ID for qemu-devel@nongnu.org; Wed, 22 May 2019 18:28:45 -0400 Received: by mail-yb1-xb42.google.com with SMTP id v66so1503158ybb.3 for ; Wed, 22 May 2019 15:28:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/D6aLozHwnS1sPI8iNsL3pMxewPkp4IUhb3tHD+DOe4=; b=VEiP8vmV0RQmXxrJLn9yHrrDOSw7ynQuiJjAXkCBfBYy5hVPFpV5oWV5XuSZ4ulvrw bFtpqLHkf/rqLsFgBBUc0pPCAcu69fluT8reEb21Hi4R+POKpF7uxrLaawzGnlTHAxCe TSHXvO9CdAHZEGXz69pL4Mer3UqPFgDi+BieA6CZePaR3OTL0vv4G936QudEWJ1FoNHH FETQljC/D7AA8+ZKK2ynOAcbXY1LZdal6Nor4E+SEx9tmASHrmqMTgCDmb28QAf3wGuC ZSgNpJEOgHdQXpCeLJVrixzwOd1pLNHdNgW1P2Fco/31ZcJVL1RFOH6Xt5aTahRYL+IH /Oow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/D6aLozHwnS1sPI8iNsL3pMxewPkp4IUhb3tHD+DOe4=; b=tauFOc4VjM6o/U74eXOvgxWcLvEuPNi5WHiqo2oig2CoDh0NtlfFw5LTGP0bBLoVst DUz3lPbhllmo4XHYUhczBLYIlfFiMw5RYo1m0HlDBJ77En6jOLtUBzM84mkTmOida2kA tHwvnCer9f6AO6PLLJ8gXK6efJnMNtGEOWtBGI+YkStf5n5OB1cV5L7dCFuFMaVM2q0Y egXbvZA0PJVLUlNP+vvixITSxr1MbWUOMKBdnZTG8MfOULGaMAuXrhX5U5WuJzT5J0QW XafNA5AfXq4WwALLGldzGNoFVPTsbaM+BYivnvVonmLw8Gl89qy20PpEFBp+23/Ng8+w OFIw== X-Gm-Message-State: APjAAAUGVmXytf8sAS4xrMOU0DS0xgkNXRs3nVpfwCS66YUBYXwBmRhR 7fSH377kXJm2msJwDSI2ltT5TR2Lslo= X-Received: by 2002:a25:77c8:: with SMTP id s191mr20720580ybc.152.1558564116955; Wed, 22 May 2019 15:28:36 -0700 (PDT) Received: from localhost.localdomain ([71.46.56.17]) by smtp.gmail.com with ESMTPSA id q11sm2276453ywg.7.2019.05.22.15.28.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 22 May 2019 15:28:36 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 22 May 2019 18:28:17 -0400 Message-Id: <20190522222821.23850-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190522222821.23850-1-richard.henderson@linaro.org> References: <20190522222821.23850-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::b42 Subject: [Qemu-devel] [PULL 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: , Cc: peter.maydell@linaro.org 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 {