From patchwork Thu Mar 30 10:26:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 77083 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1036288vqo; Thu, 30 Mar 2023 03:59:06 -0700 (PDT) X-Google-Smtp-Source: AKy350YJkE0Z4JUQfSKL16oPy88lOA1r8/DSuBzfm6deQixZo2vK6jBCt52CPMYG7i2UFIXl6f5J X-Received: by 2002:a05:6402:716:b0:502:2494:b8fc with SMTP id w22-20020a056402071600b005022494b8fcmr21041122edx.7.1680173945854; Thu, 30 Mar 2023 03:59:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680173945; cv=none; d=google.com; s=arc-20160816; b=saXZTK2HkCbpT01uTDY2BC4mlpYp9CLIg3Jf7GFcUVQtTh/eZpd7Uy4Ojp77gbsdzV 3GXr14FCxx0EHCFYPqhd8XWGmt8HCH9die8l6iL9GwbpAGE12hsdYnXUATrS32wS0S2b FcWm9C7jrX5juyWKazcHogZifHd8chq4fOMTKpoQwnyaTjHmreUaj5s1XyXax+doOQKK 3PvPGR9f1f2Zk4bW0rKw10Qb3gX0WtxTemqUHL+GoThVoLu0tiStKZqHPN0cRf2Zw35v 5hK3PKY2N6uuUTBH1INTvw9l5VIwt20AYEd+AblgpZpjckGq168DM+/67TUJAH2eu7EL qIDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=aVFudG0EFqN+kN8znp6oNy8eYJl3OoZ3X1V9tK6F75k=; b=KXAE2CauRprGekoG0s+tFAV/ysXSSBpTvi2VmQ8IypLUga00nfwExAf5Vb59IJU3gJ ZX9eY12uZasci8YjQxPBWztKho1bL3DFrlO55wSyECj9Fb5YRkrr8eKuN9SjTS9MfH2k O+3HKei5IVhYGU1iS/zxJCNK7ZoV2VR8vOz1VE24od0Z7+rYIeabi82lP96v1n3Aff8E AnCQt3ksivnCt6145r7VozyVEbet5a3CpZCazS5V1Syg8SvcSK7lKdOaCZlUIFjJApwC pS3O67aODXMvvuU2ahWWoe8ZFJ6BVEKflccHqaB2ABbKQ/x+bIFxmRNmh+i9JL30otH6 It4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Ut0FKpCu; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id n24-20020a05640206d800b004aaa505ac5fsi39330867edy.76.2023.03.30.03.59.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 03:59:05 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Ut0FKpCu; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B9C2C38A90B5 for ; Thu, 30 Mar 2023 10:40:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B9C2C38A90B5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680172850; bh=aVFudG0EFqN+kN8znp6oNy8eYJl3OoZ3X1V9tK6F75k=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Ut0FKpCuFHJBehLt+NOVLtIpxYQ1WuQIBWQYcXmeIOSJgkSIGKnvp/2pWaFc6oP46 mWt/beDFzO7qlunB4eSe+8y+xw+AT6gyThMfDWHFY+uykqyjtTzlLiEqoUZzUzc7ei exjgqxyxdsn84ayKzyZshj09aKbDuoVXY5bW48XY= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 7A9993895FDF for ; Thu, 30 Mar 2023 10:26:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7A9993895FDF Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 969FD12FC; Thu, 30 Mar 2023 03:27:40 -0700 (PDT) Received: from e121540-lin.manchester.arm.com (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A934A3F663; Thu, 30 Mar 2023 03:26:55 -0700 (PDT) To: binutils@sourceware.org Cc: Richard Sandiford Subject: [PATCH 04/31] aarch64: Add support for vgx2 and vgx4 Date: Thu, 30 Mar 2023 11:26:19 +0100 Message-Id: <20230330102646.3327818-5-richard.sandiford@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230330102646.3327818-1-richard.sandiford@arm.com> References: <20230330102646.3327818-1-richard.sandiford@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-32.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_NUMSUBJECT, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Sandiford via Binutils From: Richard Sandiford Reply-To: Richard Sandiford Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1761790075350703093?= X-GMAIL-MSGID: =?utf-8?q?1761790075350703093?= Many SME2 instructions operate on groups of 2 or 4 ZA vectors. This is indicated by adding a "vgx2" or "vgx4" group size to the ZA index. The group size is optional in assembly but preferred for disassembly. There is not a binary distinction between mnemonics that have group sizes and mnemonics that don't, nor between mnemonics that take vgx2 and mnemonics that take vgx4. We therefore get better error messages if we allow any ZA index to have a group size during parsing, and wait until constraint checking to reject invalid sizes. A quirk of the way errors are reported means that if an instruction is wrong both in its qualifiers and its use of a group size, we'll print suggested alternative instructions that also have an incorrect group size. But that's a general property that also applies to things like out-of-range immediates. It's also not obviously the wrong thing to do. We need to be relatively confident that we're looking at the right opcode before reporting detailed operand-specific errors, so doing qualifier checking first seems resonable. --- gas/config/tc-aarch64.c | 33 ++++++++++++++- gas/testsuite/gas/aarch64/sme-2-illegal.l | 3 ++ gas/testsuite/gas/aarch64/sme-2-illegal.s | 4 ++ gas/testsuite/gas/aarch64/sme-3-illegal.l | 11 +++++ gas/testsuite/gas/aarch64/sme-3-illegal.s | 6 +++ gas/testsuite/gas/aarch64/sme-5-illegal.l | 6 +++ gas/testsuite/gas/aarch64/sme-5-illegal.s | 6 +++ gas/testsuite/gas/aarch64/sme-6-illegal.l | 6 +++ gas/testsuite/gas/aarch64/sme-6-illegal.s | 6 +++ gas/testsuite/gas/aarch64/sme-7-illegal.l | 12 ++++++ gas/testsuite/gas/aarch64/sme-7-illegal.s | 11 +++++ gas/testsuite/gas/aarch64/sme-9-illegal.l | 10 +++++ gas/testsuite/gas/aarch64/sme-9-illegal.s | 6 +++ include/opcode/aarch64.h | 13 ++++++ opcodes/aarch64-opc.c | 49 +++++++++++++++++++---- 15 files changed, 173 insertions(+), 9 deletions(-) diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index b4e0b937605..2d732ea1780 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -4550,6 +4550,26 @@ parse_sme_za_index (char **str, struct aarch64_indexed_za *opnd) return false; } + opnd->group_size = 0; + if (skip_past_char (str, ',')) + { + if (strncasecmp (*str, "vgx2", 4) == 0 && !ISALPHA ((*str)[4])) + { + *str += 4; + opnd->group_size = 2; + } + else if (strncasecmp (*str, "vgx4", 4) == 0 && !ISALPHA ((*str)[4])) + { + *str += 4; + opnd->group_size = 4; + } + else + { + set_syntax_error (_("invalid vector group size")); + return false; + } + } + if (!skip_past_char (str, ']')) { set_syntax_error (_("expected ']'")); @@ -5067,6 +5087,7 @@ const char* operand_mismatch_kind_names[] = "AARCH64_OPDE_SYNTAX_ERROR", "AARCH64_OPDE_FATAL_SYNTAX_ERROR", "AARCH64_OPDE_INVALID_VARIANT", + "AARCH64_OPDE_INVALID_VG_SIZE", "AARCH64_OPDE_REG_LIST_LENGTH", "AARCH64_OPDE_REG_LIST_STRIDE", "AARCH64_OPDE_UNTIED_IMMS", @@ -5095,7 +5116,8 @@ operand_error_higher_severity_p (enum aarch64_operand_error_kind lhs, gas_assert (AARCH64_OPDE_SYNTAX_ERROR > AARCH64_OPDE_EXPECTED_A_AFTER_B); gas_assert (AARCH64_OPDE_FATAL_SYNTAX_ERROR > AARCH64_OPDE_SYNTAX_ERROR); gas_assert (AARCH64_OPDE_INVALID_VARIANT > AARCH64_OPDE_FATAL_SYNTAX_ERROR); - gas_assert (AARCH64_OPDE_REG_LIST_LENGTH > AARCH64_OPDE_INVALID_VARIANT); + gas_assert (AARCH64_OPDE_INVALID_VG_SIZE > AARCH64_OPDE_INVALID_VARIANT); + gas_assert (AARCH64_OPDE_REG_LIST_LENGTH > AARCH64_OPDE_INVALID_VG_SIZE); gas_assert (AARCH64_OPDE_REG_LIST_STRIDE > AARCH64_OPDE_REG_LIST_LENGTH); gas_assert (AARCH64_OPDE_OUT_OF_RANGE > AARCH64_OPDE_REG_LIST_STRIDE); gas_assert (AARCH64_OPDE_UNALIGNED > AARCH64_OPDE_OUT_OF_RANGE); @@ -5749,6 +5771,15 @@ output_operand_error_record (const operand_error_record *record, char *str) detail->data[0].i, idx + 1, str); break; + case AARCH64_OPDE_INVALID_VG_SIZE: + if (detail->data[0].i == 0) + handler (_("unexpected vector group size at operand %d -- `%s'"), + idx + 1, str); + else + handler (_("operand %d must have a vector group size of %d -- `%s'"), + idx + 1, detail->data[0].i, str); + break; + case AARCH64_OPDE_REG_LIST_LENGTH: if (detail->data[0].i == (1 << 1)) handler (_("expected a single-register list at operand %d -- `%s'"), diff --git a/gas/testsuite/gas/aarch64/sme-2-illegal.l b/gas/testsuite/gas/aarch64/sme-2-illegal.l index 1df18ef2002..fd36ed78381 100644 --- a/gas/testsuite/gas/aarch64/sme-2-illegal.l +++ b/gas/testsuite/gas/aarch64/sme-2-illegal.l @@ -25,3 +25,6 @@ [^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a\]' [^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,1a2\]' [^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a2\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `mova z0.b,p0/m,za0h.b\[w12,#0,vgx2\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `mova z0.b,p0/m,za0h.b\[w12,#0,vgx4\]' +[^:]*:[0-9]+: Error: invalid vector group size at operand 3 -- `mova z0.b,p0/m,za0h.b\[w12,#0,vgx8\]' diff --git a/gas/testsuite/gas/aarch64/sme-2-illegal.s b/gas/testsuite/gas/aarch64/sme-2-illegal.s index 28eb6719c91..8cc130ac9c0 100644 --- a/gas/testsuite/gas/aarch64/sme-2-illegal.s +++ b/gas/testsuite/gas/aarch64/sme-2-illegal.s @@ -30,3 +30,7 @@ mova z0.q, p0/m, za0v.q[w12, 1a] mova z0.q, p0/m, za0v.q[w12, #1a] mova z0.q, p0/m, za0v.q[w12, 1a2] mova z0.q, p0/m, za0v.q[w12, #1a2] + +mova z0.b, p0/m, za0h.b[w12, #0, vgx2] +mova z0.b, p0/m, za0h.b[w12, #0, vgx4] +mova z0.b, p0/m, za0h.b[w12, #0, vgx8] diff --git a/gas/testsuite/gas/aarch64/sme-3-illegal.l b/gas/testsuite/gas/aarch64/sme-3-illegal.l index 717af3b54be..f5fb169b78a 100644 --- a/gas/testsuite/gas/aarch64/sme-3-illegal.l +++ b/gas/testsuite/gas/aarch64/sme-3-illegal.l @@ -9,3 +9,14 @@ [^:]*:[0-9]+: Error: immediate offset out of range 0 to 3 at operand 1 -- `mova za3v\.s\[w15,#4\],p7/m,z31.s' [^:]*:[0-9]+: Error: immediate offset out of range 0 to 1 at operand 1 -- `mova za7v\.d\[w15,#2\],p7/m,z31.d' [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `mova za15v\.q\[w15,#1\],p7/m,z31.q' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `mova za0h\.b\[w12,#0,vgx2\],p0/m,z0\.b' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `mova za0h\.b\[w12,#0,vgx4\],p0/m,z0\.b' +[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `mova za0h\.b\[w12,#0,vgx8\],p0/m,z0\.b' +[^:]*:[0-9]+: Error: operand mismatch -- `mova za0h\.b\[w12,#0,vgx2\],p0/z,z0\.b' +[^:]*:[0-9]+: Info: did you mean this\? +[^:]*:[0-9]+: Info: mova za0h\.b\[w12, 0, vgx2\], p0/m, z0\.b +[^:]*:[0-9]+: Info: other valid variant\(s\): +[^:]*:[0-9]+: Info: mova za0h\.h\[w12, 0, vgx2\], p0/m, z0\.h +[^:]*:[0-9]+: Info: mova za0h\.s\[w12, 0, vgx2\], p0/m, z0\.s +[^:]*:[0-9]+: Info: mova za0h\.d\[w12, 0, vgx2\], p0/m, z0\.d +[^:]*:[0-9]+: Info: mova za0h\.q\[w12, 0, vgx2\], p0/m, z0\.q diff --git a/gas/testsuite/gas/aarch64/sme-3-illegal.s b/gas/testsuite/gas/aarch64/sme-3-illegal.s index 6ed58ec60a1..aeeaf549e8f 100644 --- a/gas/testsuite/gas/aarch64/sme-3-illegal.s +++ b/gas/testsuite/gas/aarch64/sme-3-illegal.s @@ -12,3 +12,9 @@ mova za1v.h[w15, #8], p7/m, z31.h mova za3v.s[w15, #4], p7/m, z31.s mova za7v.d[w15, #2], p7/m, z31.d mova za15v.q[w15, #1], p7/m, z31.q + +mova za0h.b[w12, #0, vgx2], p0/m, z0.b +mova za0h.b[w12, #0, vgx4], p0/m, z0.b +mova za0h.b[w12, #0, vgx8], p0/m, z0.b + +mova za0h.b[w12, #0, vgx2], p0/z, z0.b diff --git a/gas/testsuite/gas/aarch64/sme-5-illegal.l b/gas/testsuite/gas/aarch64/sme-5-illegal.l index f892dcd2090..f6eda9da5e2 100644 --- a/gas/testsuite/gas/aarch64/sme-5-illegal.l +++ b/gas/testsuite/gas/aarch64/sme-5-illegal.l @@ -56,3 +56,9 @@ [^:]*:[0-9]+: Error: missing braces at operand 1 -- `ld1w za0h.s\[w12,0\],p0/z,\[x0\]' [^:]*:[0-9]+: Error: missing braces at operand 1 -- `ld1d za0h.d\[w12,0\],p0/z,\[x0\]' [^:]*:[0-9]+: Error: missing braces at operand 1 -- `ld1q za0h.q\[w12,0\],p0/z,\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ld1b {za0h\.b\[w12,0,vgx2\]},p0/z,\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ld1b {za0h\.b\[w12,0,vgx4\]},p0/z,\[x0\]' +[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `ld1b {za0h\.b\[w12,0,vgx8\]},p0/z,\[x0\]' +[^:]*:[0-9]+: Error: operand mismatch -- `ld1b {za0h\.b\[w12,0,vgx4\]},p0/m,\[x0\]' +[^:]*:[0-9]+: Info: did you mean this\? +[^:]*:[0-9]+: Info: ld1b {za0h\.b\[w12, 0, vgx4\]}, p0/z, \[x0, xzr\] diff --git a/gas/testsuite/gas/aarch64/sme-5-illegal.s b/gas/testsuite/gas/aarch64/sme-5-illegal.s index 29f86669043..9dbce626a6e 100644 --- a/gas/testsuite/gas/aarch64/sme-5-illegal.s +++ b/gas/testsuite/gas/aarch64/sme-5-illegal.s @@ -57,3 +57,9 @@ ld1h za0h.h[w12, 0], p0/z, [x0] ld1w za0h.s[w12, 0], p0/z, [x0] ld1d za0h.d[w12, 0], p0/z, [x0] ld1q za0h.q[w12, 0], p0/z, [x0] + +ld1b {za0h.b[w12, 0, vgx2]}, p0/z, [x0] +ld1b {za0h.b[w12, 0, vgx4]}, p0/z, [x0] +ld1b {za0h.b[w12, 0, vgx8]}, p0/z, [x0] + +ld1b {za0h.b[w12, 0, vgx4]}, p0/m, [x0] diff --git a/gas/testsuite/gas/aarch64/sme-6-illegal.l b/gas/testsuite/gas/aarch64/sme-6-illegal.l index c8141e086ab..bc0d19417fc 100644 --- a/gas/testsuite/gas/aarch64/sme-6-illegal.l +++ b/gas/testsuite/gas/aarch64/sme-6-illegal.l @@ -43,3 +43,9 @@ [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `st1q {za15h.q\[w15,1\]},p7,\[sp\]' [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `st1q {za15v.q\[w15,1\]},p7,\[x0,x17,lsl#4\]' [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `st1q {za15h.q\[w15,1\]},p7,\[sp,x17,lsl#4\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `st1b {za0h.b\[w12,0,vgx2\]},p0,\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `st1b {za0h\.b\[w12,0,vgx4\]},p0,\[x0\]' +[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `st1b {za0h\.b\[w12,0,vgx8\]},p0,\[x0\]' +[^:]*:[0-9]+: Error: operand mismatch -- `st1b {za0h\.b\[w12,0,vgx2\]},p0/z,\[x0\]' +[^:]*:[0-9]+: Info: did you mean this\? +[^:]*:[0-9]+: Info: st1b {za0h\.b\[w12, 0, vgx2\]}, p0, \[x0, xzr\] diff --git a/gas/testsuite/gas/aarch64/sme-6-illegal.s b/gas/testsuite/gas/aarch64/sme-6-illegal.s index d0de01d5a6c..04a508821bc 100644 --- a/gas/testsuite/gas/aarch64/sme-6-illegal.s +++ b/gas/testsuite/gas/aarch64/sme-6-illegal.s @@ -44,3 +44,9 @@ st1q {za15v.q[w15, 1]}, p7, [x17] st1q {za15h.q[w15, 1]}, p7, [sp] st1q {za15v.q[w15, 1]}, p7, [x0, x17, lsl #4] st1q {za15h.q[w15, 1]}, p7, [sp, x17, lsl #4] + +st1b {za0h.b[w12, 0, vgx2]}, p0, [x0] +st1b {za0h.b[w12, 0, vgx4]}, p0, [x0] +st1b {za0h.b[w12, 0, vgx8]}, p0, [x0] + +st1b {za0h.b[w12, 0, vgx2]}, p0/z, [x0] diff --git a/gas/testsuite/gas/aarch64/sme-7-illegal.l b/gas/testsuite/gas/aarch64/sme-7-illegal.l index 0023a84da71..eb0c5e6f51a 100644 --- a/gas/testsuite/gas/aarch64/sme-7-illegal.l +++ b/gas/testsuite/gas/aarch64/sme-7-illegal.l @@ -54,3 +54,15 @@ [^:]*:[0-9]+: Error: expected 'za' rather than a ZA tile at operand 1 -- `ldr za0h.h\[w12,0\],\[x0\]' [^:]*:[0-9]+: Error: expected 'za' rather than a ZA tile at operand 1 -- `ldr za0v\[w12,0\],\[x0\]' [^:]*:[0-9]+: Error: expected 'za' rather than a ZA tile at operand 1 -- `ldr za0v.s\[w12,0\],\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ldr za\[w12,0,vgx2\],\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ldr za\[w12,0,vgx4\],\[x0\]' +[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `ldr za\[w12,0,vgx8\],\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `str za\[w12,0,vgx2\],\[x0\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `str za\[w12,0,vgx4\],\[x0\]' +[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `str za\[w12,0,vgx8\],\[x0\]' +[^:]*:[0-9]+: Error: operand mismatch -- `ldr za\.b\[w12,0,vgx2\],\[x0\]' +[^:]*:[0-9]+: Info: did you mean this\? +[^:]*:[0-9]+: Info: ldr za\[w12, 0, vgx2\], \[x0\] +[^:]*:[0-9]+: Error: operand mismatch -- `str za\.b\[w12,0,vgx4\],\[x0\]' +[^:]*:[0-9]+: Info: did you mean this\? +[^:]*:[0-9]+: Info: str za\[w12, 0, vgx4\], \[x0\] diff --git a/gas/testsuite/gas/aarch64/sme-7-illegal.s b/gas/testsuite/gas/aarch64/sme-7-illegal.s index 75e2810e647..05d7d23fe29 100644 --- a/gas/testsuite/gas/aarch64/sme-7-illegal.s +++ b/gas/testsuite/gas/aarch64/sme-7-illegal.s @@ -52,3 +52,14 @@ ldr za0h[w12, 0], [x0] ldr za0h.h[w12, 0], [x0] ldr za0v[w12, 0], [x0] ldr za0v.s[w12, 0], [x0] + +ldr za[w12, 0, vgx2], [x0] +ldr za[w12, 0, vgx4], [x0] +ldr za[w12, 0, vgx8], [x0] + +str za[w12, 0, vgx2], [x0] +str za[w12, 0, vgx4], [x0] +str za[w12, 0, vgx8], [x0] + +ldr za.b[w12, 0, vgx2], [x0] +str za.b[w12, 0, vgx4], [x0] diff --git a/gas/testsuite/gas/aarch64/sme-9-illegal.l b/gas/testsuite/gas/aarch64/sme-9-illegal.l index 0243c9efcdf..d7aff825288 100644 --- a/gas/testsuite/gas/aarch64/sme-9-illegal.l +++ b/gas/testsuite/gas/aarch64/sme-9-illegal.l @@ -27,6 +27,16 @@ [^:]*:[0-9]+: Error: immediate offset out of range 0 to 7 at operand 3 -- `psel p1,p8,p6.h\[w14,#8\]' [^:]*:[0-9]+: Error: immediate offset out of range 0 to 3 at operand 3 -- `psel p8,p4,p15.s\[w13,#4\]' [^:]*:[0-9]+: Error: immediate offset out of range 0 to 1 at operand 3 -- `psel p1,p1,p1.d\[w12,#2\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `psel p0,p0,p0\.b\[w12,#0,vgx2\]' +[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `psel p0,p0,p0\.b\[w12,#0,vgx4\]' +[^:]*:[0-9]+: Error: invalid vector group size at operand 3 -- `psel p0,p0,p0\.b\[w12,#0,vgx8\]' +[^:]*:[0-9]+: Error: operand mismatch -- `psel p0\.b,p0\.b,p0\.b\[w12,#0,vgx2\]' +[^:]*:[0-9]+: Info: did you mean this\? +[^:]*:[0-9]+: Info: psel p0, p0, p0\.b\[w12, 0\] +[^:]*:[0-9]+: Info: other valid variant\(s\): +[^:]*:[0-9]+: Info: psel p0, p0, p0\.h\[w12, 0\] +[^:]*:[0-9]+: Info: psel p0, p0, p0\.s\[w12, 0\] +[^:]*:[0-9]+: Info: psel p0, p0, p0\.d\[w12, 0\] [^:]*:[0-9]+: Error: operand mismatch -- `revd z0.q,p0/m,z0.b' [^:]*:[0-9]+: Info: did you mean this\? [^:]*:[0-9]+: Info: revd z0.q, p0/m, z0.q diff --git a/gas/testsuite/gas/aarch64/sme-9-illegal.s b/gas/testsuite/gas/aarch64/sme-9-illegal.s index f59582eeb8b..8f41298cd3c 100644 --- a/gas/testsuite/gas/aarch64/sme-9-illegal.s +++ b/gas/testsuite/gas/aarch64/sme-9-illegal.s @@ -17,6 +17,12 @@ psel p1, p8, p6.h[w14, #8] psel p8, p4, p15.s[w13, #4] psel p1, p1, p1.d[w12, #2] +psel p0, p0, p0.b[w12, #0, vgx2] +psel p0, p0, p0.b[w12, #0, vgx4] +psel p0, p0, p0.b[w12, #0, vgx8] + +psel p0.b, p0.b, p0.b[w12, #0, vgx2] + revd z0.q, p0/m, z0.b sclamp z8.b, z1.b, z31.q diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 94584668517..534bdaa869f 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -1120,6 +1120,7 @@ struct aarch64_indexed_za int regno; /* */ int64_t imm; /* */ } index; + unsigned group_size : 8; unsigned v : 1; /* horizontal or vertical vector indicator. */ }; @@ -1294,6 +1295,17 @@ struct aarch64_inst The following errors are only reported against an asm string that is syntactically valid and that has valid operand qualifiers. + AARCH64_OPDE_INVALID_VG_SIZE + Error about a "VGx" modifier in a ZA index not having the + correct . This error effectively forms a pair with + AARCH64_OPDE_REG_LIST_LENGTH, since both errors relate to the number + of vectors that an instruction operates on. However, the "VGx" + modifier is optional, whereas a register list always has a known + and explicit length. It therefore seems better to place more + importance on the register list length when selecting an opcode table + entry. This in turn means that having an incorrect register length + should be more severe than having an incorrect "VGx". + AARCH64_OPDE_REG_LIST_LENGTH Error about a register list operand having an unexpected number of registers. This error is low severity because there might be another @@ -1356,6 +1368,7 @@ enum aarch64_operand_error_kind AARCH64_OPDE_SYNTAX_ERROR, AARCH64_OPDE_FATAL_SYNTAX_ERROR, AARCH64_OPDE_INVALID_VARIANT, + AARCH64_OPDE_INVALID_VG_SIZE, AARCH64_OPDE_REG_LIST_LENGTH, AARCH64_OPDE_REG_LIST_STRIDE, AARCH64_OPDE_UNTIED_IMMS, diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index e97201bb03a..0d38ff250c4 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -1458,6 +1458,16 @@ set_reg_list_stride_error (aarch64_operand_error *mismatch_detail, int idx, mismatch_detail->data[0].i = 1 << expected_num; } +static inline void +set_invalid_vg_size (aarch64_operand_error *mismatch_detail, + int idx, int expected) +{ + if (mismatch_detail == NULL) + return; + set_error (mismatch_detail, AARCH64_OPDE_INVALID_VG_SIZE, idx, NULL); + mismatch_detail->data[0].i = expected; +} + static inline void set_other_error (aarch64_operand_error *mismatch_detail, int idx, const char* error) @@ -1517,12 +1527,14 @@ check_reglist (const aarch64_opnd_info *opnd, - a selection register in the range [MIN_WREG, MIN_WREG + 3] - - an immediate offset in the range [0, MAX_VALUE]. */ + - an immediate offset in the range [0, MAX_VALUE]. + + - a vector group size of GROUP_SIZE. */ static bool check_za_access (const aarch64_opnd_info *opnd, aarch64_operand_error *mismatch_detail, int idx, - int min_wreg, int max_value) + int min_wreg, int max_value, int group_size) { if (!value_in_range_p (opnd->indexed_za.index.regno, min_wreg, min_wreg + 3)) { @@ -1540,6 +1552,15 @@ check_za_access (const aarch64_opnd_info *opnd, set_offset_out_of_range_error (mismatch_detail, idx, 0, max_value); return false; } + + /* The vector group specifier is optional in assembly code. */ + if (opnd->indexed_za.group_size != 0 + && opnd->indexed_za.group_size != group_size) + { + set_invalid_vg_size (mismatch_detail, idx, group_size); + return false; + } + return true; } @@ -1657,7 +1678,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, case AARCH64_OPND_SME_PnT_Wm_imm: size = aarch64_get_qualifier_esize (opnd->qualifier); max_value = 16 / size - 1; - if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value)) + if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 0)) return 0; break; @@ -1680,12 +1701,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, case AARCH64_OPND_SME_ZA_HV_idx_ldstr: size = aarch64_get_qualifier_esize (opnd->qualifier); max_value = 16 / size - 1; - if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value)) + if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, + get_opcode_dependent_value (opcode))) return 0; break; case AARCH64_OPND_SME_ZA_array_off4: - if (!check_za_access (opnd, mismatch_detail, idx, 12, 15)) + if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, + get_opcode_dependent_value (opcode))) return 0; break; @@ -3671,7 +3694,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_SME_ZA_HV_idx_src: case AARCH64_OPND_SME_ZA_HV_idx_dest: case AARCH64_OPND_SME_ZA_HV_idx_ldstr: - snprintf (buf, size, "%s%s[%s, %s]%s", + snprintf (buf, size, "%s%s[%s, %s%s%s]%s", opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "", style_reg (styler, "za%d%c.%s", opnd->indexed_za.regno, @@ -3679,6 +3702,11 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, aarch64_get_qualifier_name (opnd->qualifier)), style_reg (styler, "w%d", opnd->indexed_za.index.regno), style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm), + opnd->indexed_za.group_size ? ", " : "", + opnd->indexed_za.group_size == 2 + ? style_sub_mnem (styler, "vgx2") + : opnd->indexed_za.group_size == 4 + ? style_sub_mnem (styler, "vgx4") : "", opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : ""); break; @@ -3687,10 +3715,15 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, break; case AARCH64_OPND_SME_ZA_array_off4: - snprintf (buf, size, "%s[%s, %s]", + snprintf (buf, size, "%s[%s, %s%s%s]", style_reg (styler, "za"), style_reg (styler, "w%d", opnd->indexed_za.index.regno), - style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm)); + style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm), + opnd->indexed_za.group_size ? ", " : "", + opnd->indexed_za.group_size == 2 + ? style_sub_mnem (styler, "vgx2") + : opnd->indexed_za.group_size == 4 + ? style_sub_mnem (styler, "vgx4") : ""); break; case AARCH64_OPND_SME_SM_ZA: