public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Victor Do Nascimento <victor.donascimento@arm.com>
To: <binutils@sourceware.org>
Cc: <richard.earnshaw@arm.com>, <nickc@redhat.com>,
	Victor Do Nascimento <victor.donascimento@arm.com>
Subject: [PATCH 04/12] aarch64: Add support for optional operand pairs
Date: Wed, 3 Jan 2024 01:17:18 +0000	[thread overview]
Message-ID: <20240103011739.2444792-5-victor.donascimento@arm.com> (raw)
In-Reply-To: <20240103011739.2444792-1-victor.donascimento@arm.com>

Two of the instructions added by the `+d128' architectural extension
add the flexibility to have two optional operands.  Prior to the
addition of the `tlbip' and `sysp' instructions, no mnemonic allowed
more than one such optional operand.

With `tlbip' as an example, some TLBIP instruction names do not allow
for any optional operands, while others allow for both to be optional.
In the latter case, it is possible that either the second operand
alone is omitted or both operands are omitted.
Therefore, a considerable degree of flexibility needed to be added to
the way operands were parsed.  It was, however, possible to achieve
this with relatively few changes to existing code.

it is noteworthy that opcode flags specifying the optional operand
number are non-orthogonal. For example, we have:

       #define F_OPD1_OPT (2 << 12) : 0b10 << 12
       #define F_OPD2_OPT (3 << 12) : 0b11 << 12

such that by virtue of the observation that

       (F_OPD1_OPT | F_OPD2_OPT) == F_OPD2_OPT

it is impossible to mark both operands 1 and 2 as optional for an
instruction and it is assumed that a maximum of 1 operand can ever be
optional.  This is not overly-problematic given that, for optional
pairs, the second optional operand is always found immediately after
the first.  Thus, it suffices for us to flag that there is a second
optional operand.  With this fact, we can infer its position in the
mnemonic from the position of the first (e.g. if the second operand in
the mnemonic is optional, we know the third is too).  We therefore
define the `F_OPD_PAIR_OPT' flag and calculate its position in the
mnemonic from the value encoded by the `F_OPD<n>_OPT' flag.

Another observation is that there is a tight coupling between default
values assigned to the two registers when one (or both) are omitted
from the mnemonic.  Namely, if Xt1 has a value of 0x1f (the zero
register is specified), Xt2 defaults to the same value, otherwise Xt2
will be assigned Xt + 1.  This meant that where you have default value
validation, in checking the second optional operand's value, it is
also necessary to look at the value assigned to the
previously-processed operand value before deciding its validity. Thus
`process_omitted_operand' needs not only access to its `operand'
argument, but also to the global `inst' struct.
---
 gas/config/tc-aarch64.c  | 19 +++++++++++++++++--
 include/opcode/aarch64.h | 12 +++++++++++-
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 796a6da267b..12fb1740635 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6179,6 +6179,17 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
     case AARCH64_OPND_VnD1:
       operand->reg.regno = default_value;
       break;
+    case AARCH64_OPND_PAIRREG_OR_XZR:
+      if (inst.base.operands[idx - 1].reg.regno == 0x1f)
+	{
+	  operand->reg.regno = 0x1f;
+	  break;
+	}
+      operand->reg.regno = inst.base.operands[idx - 1].reg.regno + 1;
+      break;
+    case AARCH64_OPND_PAIRREG:
+      operand->reg.regno = inst.base.operands[idx - 1].reg.regno + 1;
+      break;
 
     case AARCH64_OPND_Ed:
     case AARCH64_OPND_En:
@@ -7875,6 +7886,12 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 
       /* If we get here, this operand was successfully parsed.  */
       inst.base.operands[i].present = 1;
+
+      /* As instructions can have multiple optional operands, it is imporant to
+	 reset the backtrack_pos variable once we finish processing an operand
+	 successfully.  */
+      backtrack_pos = 0;
+
       continue;
 
     failure:
@@ -7896,8 +7913,6 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 	char *tmp = backtrack_pos;
 	char endchar = END_OF_INSN;
 
-	if (i != (aarch64_num_of_operands (opcode) - 1))
-	  endchar = ',';
 	skip_past_char (&tmp, ',');
 
 	if (*tmp != endchar)
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index d3db252e5c2..c69f85557d0 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -1220,7 +1220,11 @@ extern const aarch64_opcode aarch64_opcode_table[];
 /* This instruction has an extra constraint on it that imposes a requirement on
    subsequent instructions.  */
 #define F_SCAN (1ULL << 31)
-/* Next bit is 32.  */
+/* Instruction takes a pair of optional operands.  If we specify the Nth operand
+   to be optional, then we also implicitly specify (N+1)th operand to also be
+   optional.  */
+#define F_OPD_PAIR_OPT (1ULL << 32)
+/* Next bit is 33.  */
 
 /* Instruction constraints.  */
 /* This instruction has a predication constraint on the instruction at PC+4.  */
@@ -1259,9 +1263,15 @@ pseudo_opcode_p (const aarch64_opcode *opcode)
   return (opcode->flags & F_PSEUDO) != 0lu;
 }
 
+/* Deal with two possible scenarios: If F_OP_PAIR_OPT not set, as is the case
+   by default, F_OPDn_OPT must equal IDX + 1, else F_OPDn_OPT must be in range
+   [IDX, IDX + 1].  */
 static inline bool
 optional_operand_p (const aarch64_opcode *opcode, unsigned int idx)
 {
+  if (opcode->flags & F_OPD_PAIR_OPT)
+    return (((opcode->flags >> 12) & 0x7) == idx
+	    || ((opcode->flags >> 12) & 0x7) == idx + 1);
   return ((opcode->flags >> 12) & 0x7) == idx + 1;
 }
 
-- 
2.42.0


  parent reply	other threads:[~2024-01-03  1:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-03  1:17 [PATCH 00/12] aarch64: Add Armv9.4-A support for the d128 extension Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 01/12] aarch64: Add +d128 architectural feature support Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 02/12] aarch64: Expand maximum number of operands from 5 to 6 Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 03/12] aarch64: Add support for xzr register in register pair operands Victor Do Nascimento
2024-01-03  1:17 ` Victor Do Nascimento [this message]
2024-01-03  1:17 ` [PATCH 05/12] aarch64: Add support for the SYSP 128-bit system instruction Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 06/12] aarch64: Apply narrowing of allowed immediate values for SYSP Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 07/12] aarch64: Create QL_SRC_X2 and QL_DEST_X2 qualifier macros Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 08/12] aarch64: Implement TLBIP 128-bit instruction Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 09/12] aarch64: Add xs variants of tlbip operands Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 10/12] aarch64: Add TLBIP tests Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 11/12] aarch64: Add support for 128-bit system register mrrs and msrr insns Victor Do Nascimento
2024-01-03  1:17 ` [PATCH 12/12] arch64: Add optional operand register pair support tests Victor Do Nascimento
2024-01-05 16:10 ` [PATCH 00/12] aarch64: Add Armv9.4-A support for the d128 extension Nick Clifton
2024-01-05 16:53   ` Victor Do Nascimento
2024-01-08 10:04     ` Nick Clifton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240103011739.2444792-5-victor.donascimento@arm.com \
    --to=victor.donascimento@arm.com \
    --cc=binutils@sourceware.org \
    --cc=nickc@redhat.com \
    --cc=richard.earnshaw@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).