aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/config/tc-aarch64.c19
-rw-r--r--include/opcode/aarch64.h12
2 files changed, 28 insertions, 3 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 1468729..29535e7 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6168,6 +6168,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:
@@ -7864,6 +7875,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:
@@ -7885,8 +7902,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 187a428..854bb74 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;
}