diff options
-rw-r--r-- | gas/config/tc-aarch64.c | 19 | ||||
-rw-r--r-- | 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 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; } |