mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
aarch64: Add an error code for out-of-range registers
libopcodes currently reports out-of-range registers as a general AARCH64_OPDE_OTHER_ERROR. However, this means that each register range needs its own hard-coded string, which is a bit cumbersome if the range is determined programmatically. This patch therefore adds a dedicated error type for out-of-range errors.
This commit is contained in:
parent
36043bcff4
commit
859f51df4d
@ -5057,6 +5057,7 @@ const char* operand_mismatch_kind_names[] =
|
||||
"AARCH64_OPDE_OUT_OF_RANGE",
|
||||
"AARCH64_OPDE_UNALIGNED",
|
||||
"AARCH64_OPDE_OTHER_ERROR",
|
||||
"AARCH64_OPDE_INVALID_REGNO",
|
||||
};
|
||||
#endif /* DEBUG_AARCH64 */
|
||||
|
||||
@ -5081,6 +5082,7 @@ operand_error_higher_severity_p (enum aarch64_operand_error_kind lhs,
|
||||
gas_assert (AARCH64_OPDE_OUT_OF_RANGE > AARCH64_OPDE_REG_LIST);
|
||||
gas_assert (AARCH64_OPDE_UNALIGNED > AARCH64_OPDE_OUT_OF_RANGE);
|
||||
gas_assert (AARCH64_OPDE_OTHER_ERROR > AARCH64_OPDE_REG_LIST);
|
||||
gas_assert (AARCH64_OPDE_INVALID_REGNO > AARCH64_OPDE_OTHER_ERROR);
|
||||
return lhs > rhs;
|
||||
}
|
||||
|
||||
@ -5712,6 +5714,12 @@ output_operand_error_record (const operand_error_record *record, char *str)
|
||||
detail->index + 1, str);
|
||||
break;
|
||||
|
||||
case AARCH64_OPDE_INVALID_REGNO:
|
||||
handler (_("%s%d-%s%d expected at operand %d -- `%s'"),
|
||||
detail->data[0].s, detail->data[1].i,
|
||||
detail->data[0].s, detail->data[2].i, idx + 1, str);
|
||||
break;
|
||||
|
||||
case AARCH64_OPDE_OUT_OF_RANGE:
|
||||
if (detail->data[0].i != detail->data[1].i)
|
||||
handler (_("%s out of range %d to %d at operand %d -- `%s'"),
|
||||
|
@ -1311,6 +1311,13 @@ struct aarch64_inst
|
||||
Error of the highest severity and used for any severe issue that does not
|
||||
fall into any of the above categories.
|
||||
|
||||
AARCH64_OPDE_INVALID_REGNO
|
||||
A register was syntactically valid and had the right type, but it was
|
||||
outside the range supported by the associated operand field. This is
|
||||
a high severity error because there are currently no instructions that
|
||||
would accept the operands that precede the erroneous one (if any) and
|
||||
yet still accept a wider range of registers.
|
||||
|
||||
AARCH64_OPDE_RECOVERABLE, AARCH64_OPDE_SYNTAX_ERROR and
|
||||
AARCH64_OPDE_FATAL_SYNTAX_ERROR are only deteced by GAS while the
|
||||
AARCH64_OPDE_INVALID_VARIANT error can only be spotted by libopcodes as
|
||||
@ -1339,7 +1346,8 @@ enum aarch64_operand_error_kind
|
||||
AARCH64_OPDE_UNTIED_OPERAND,
|
||||
AARCH64_OPDE_OUT_OF_RANGE,
|
||||
AARCH64_OPDE_UNALIGNED,
|
||||
AARCH64_OPDE_OTHER_ERROR
|
||||
AARCH64_OPDE_OTHER_ERROR,
|
||||
AARCH64_OPDE_INVALID_REGNO
|
||||
};
|
||||
|
||||
/* N.B. GAS assumes that this structure work well with shallow copy. */
|
||||
|
@ -1335,6 +1335,18 @@ set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
|
||||
set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_invalid_regno_error (aarch64_operand_error *mismatch_detail, int idx,
|
||||
const char *prefix, int lower_bound, int upper_bound)
|
||||
{
|
||||
if (mismatch_detail == NULL)
|
||||
return;
|
||||
set_error (mismatch_detail, AARCH64_OPDE_INVALID_REGNO, idx, NULL);
|
||||
mismatch_detail->data[0].s = prefix;
|
||||
mismatch_detail->data[1].i = lower_bound;
|
||||
mismatch_detail->data[2].i = upper_bound;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_out_of_range_error (aarch64_operand_error *mismatch_detail,
|
||||
int idx, int lower_bound, int upper_bound,
|
||||
@ -1569,11 +1581,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
|
||||
mask = (1 << shift) - 1;
|
||||
if (opnd->reg.regno > mask)
|
||||
{
|
||||
assert (mask == 7 || mask == 15);
|
||||
set_other_error (mismatch_detail, idx,
|
||||
mask == 15
|
||||
? _("z0-z15 expected")
|
||||
: _("z0-z7 expected"));
|
||||
set_invalid_regno_error (mismatch_detail, idx, "z", 0, mask);
|
||||
return 0;
|
||||
}
|
||||
mask = (1u << (size - shift)) - 1;
|
||||
@ -1642,7 +1650,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
|
||||
if (opnd->reg.regno >= 8
|
||||
&& get_operand_fields_width (get_operand_from_code (type)) == 3)
|
||||
{
|
||||
set_other_error (mismatch_detail, idx, _("p0-p7 expected"));
|
||||
set_invalid_regno_error (mismatch_detail, idx, "p", 0, 7);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user