To prevent the expression parser from pushing a register name
into the symbol table as an undefined symbol, firstly a check is
- done to find out whether STR is a valid register name followed
- by a comma or the end of line. Return FALSE if STR is such a
- string. */
+ done to find out whether STR is a register of type REG_TYPE followed
+ by a comma or the end of line. Return FALSE if STR is such a string. */
static bfd_boolean
-parse_immediate_expression (char **str, expressionS *exp)
+parse_immediate_expression (char **str, expressionS *exp,
+ aarch64_reg_type reg_type)
{
- if (reg_name_p (*str, REG_TYPE_R_Z_BHSDQ_V))
+ if (reg_name_p (*str, reg_type))
{
set_recoverable_error (_("immediate operand required"));
return FALSE;
/* Constant immediate-value read function for use in insn parsing.
STR points to the beginning of the immediate (with the optional
- leading #); *VAL receives the value.
+ leading #); *VAL receives the value. REG_TYPE says which register
+ names should be treated as registers rather than as symbolic immediates.
Return TRUE on success; otherwise return FALSE. */
static bfd_boolean
-parse_constant_immediate (char **str, int64_t * val)
+parse_constant_immediate (char **str, int64_t *val, aarch64_reg_type reg_type)
{
expressionS exp;
- if (! parse_immediate_expression (str, &exp))
+ if (! parse_immediate_expression (str, &exp, reg_type))
return FALSE;
if (exp.X_op != O_constant)
value in *IMMED in the format of IEEE754 single-precision encoding.
*CCP points to the start of the string; DP_P is TRUE when the immediate
is expected to be in double-precision (N.B. this only matters when
- hexadecimal representation is involved).
+ hexadecimal representation is involved). REG_TYPE says which register
+ names should be treated as registers rather than as symbolic immediates.
N.B. 0.0 is accepted by this function. */
static bfd_boolean
-parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p)
+parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p,
+ aarch64_reg_type reg_type)
{
char *str = *ccp;
char *fpnum;
/* Support the hexadecimal representation of the IEEE754 encoding.
Double-precision is expected when DP_P is TRUE, otherwise the
representation should be in single-precision. */
- if (! parse_constant_immediate (&str, &val))
+ if (! parse_constant_immediate (&str, &val, reg_type))
goto invalid_fp;
if (dp_p)
To prevent the expression parser from pushing a register name into the
symbol table as an undefined symbol, a check is firstly done to find
- out whether STR is a valid register name followed by a comma or the end
- of line. Return FALSE if STR is such a register. */
+ out whether STR is a register of type REG_TYPE followed by a comma or
+ the end of line. Return FALSE if STR is such a register. */
static bfd_boolean
-parse_big_immediate (char **str, int64_t *imm)
+parse_big_immediate (char **str, int64_t *imm, aarch64_reg_type reg_type)
{
char *ptr = *str;
- if (reg_name_p (ptr, REG_TYPE_R_Z_BHSDQ_V))
+ if (reg_name_p (ptr, reg_type))
{
set_syntax_error (_("immediate operand required"));
return FALSE;
} while (0)
#define po_imm_nc_or_fail() do { \
- if (! parse_constant_immediate (&str, &val)) \
+ if (! parse_constant_immediate (&str, &val, imm_reg_type)) \
goto failure; \
} while (0)
#define po_imm_or_fail(min, max) do { \
- if (! parse_constant_immediate (&str, &val)) \
+ if (! parse_constant_immediate (&str, &val, imm_reg_type)) \
goto failure; \
if (val < min || val > max) \
{ \
int i;
char *backtrack_pos = 0;
const enum aarch64_opnd *operands = opcode->operands;
+ aarch64_reg_type imm_reg_type;
clear_error ();
skip_whitespace (str);
+ imm_reg_type = REG_TYPE_R_Z_BHSDQ_V;
+
for (i = 0; operands[i] != AARCH64_OPND_NIL; i++)
{
int64_t val;
bfd_boolean res1 = FALSE, res2 = FALSE;
/* N.B. -0.0 will be rejected; although -0.0 shouldn't be rejected,
it is probably not worth the effort to support it. */
- if (!(res1 = parse_aarch64_imm_float (&str, &qfloat, FALSE))
- && !(res2 = parse_constant_immediate (&str, &val)))
+ if (!(res1 = parse_aarch64_imm_float (&str, &qfloat, FALSE,
+ imm_reg_type))
+ && !(res2 = parse_constant_immediate (&str, &val,
+ imm_reg_type)))
goto failure;
if ((res1 && qfloat == 0) || (res2 && val == 0))
{
case AARCH64_OPND_SIMD_IMM:
case AARCH64_OPND_SIMD_IMM_SFT:
- if (! parse_big_immediate (&str, &val))
+ if (! parse_big_immediate (&str, &val, imm_reg_type))
goto failure;
assign_imm_if_const_or_fixup_later (&inst.reloc, info,
/* addr_off_p */ 0,
bfd_boolean dp_p
= (aarch64_get_qualifier_esize (inst.base.operands[0].qualifier)
== 8);
- if (! parse_aarch64_imm_float (&str, &qfloat, dp_p))
+ if (! parse_aarch64_imm_float (&str, &qfloat, dp_p, imm_reg_type))
goto failure;
if (qfloat == 0)
{
break;
case AARCH64_OPND_EXCEPTION:
- po_misc_or_fail (parse_immediate_expression (&str, &inst.reloc.exp));
+ po_misc_or_fail (parse_immediate_expression (&str, &inst.reloc.exp,
+ imm_reg_type));
assign_imm_if_const_or_fixup_later (&inst.reloc, info,
/* addr_off_p */ 0,
/* need_libopcodes_p */ 0,