diff --git a/SOURCES/binutils-aarch64-support-armv9.2-a-dsb-fix.patch b/SOURCES/binutils-aarch64-support-armv9.2-a-dsb-fix.patch new file mode 100644 index 0000000000000000000000000000000000000000..883a9da6e5dc9dad59131f28ffe921a71154d5c5 --- /dev/null +++ b/SOURCES/binutils-aarch64-support-armv9.2-a-dsb-fix.patch @@ -0,0 +1,15203 @@ +diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c +index 0ac618d8a..927b2420e 100644 +--- a/gas/config/tc-aarch64.c ++++ b/gas/config/tc-aarch64.c +@@ -22,7 +22,8 @@ + #include "as.h" + #include + #include +-#include "bfd_stdint.h" ++#include ++#include + #define NO_RELOC 0 + #include "safe-ctype.h" + #include "subsegs.h" +@@ -146,8 +147,8 @@ typedef struct aarch64_instruction aarch64_instruction; + + static aarch64_instruction inst; + +-static bfd_boolean parse_operands (char *, const aarch64_opcode *); +-static bfd_boolean programmer_friendly_fixup (aarch64_instruction *); ++static bool parse_operands (char *, const aarch64_opcode *); ++static bool programmer_friendly_fixup (aarch64_instruction *); + + /* Diagnostics inline function utilities. + +@@ -173,7 +174,7 @@ clear_error (void) + inst.parsing_error.error = NULL; + } + +-static inline bfd_boolean ++static inline bool + error_p (void) + { + return inst.parsing_error.kind != AARCH64_OPDE_NIL; +@@ -243,12 +244,6 @@ set_fatal_syntax_error (const char *error) + present. */ + #define COND_ALWAYS 0x10 + +-typedef struct +-{ +- const char *template; +- unsigned long value; +-} asm_barrier_opt; +- + typedef struct + { + const char *template; +@@ -534,85 +529,99 @@ const char FLT_CHARS[] = "rRsSfFdDxXeEpPhH"; + + #define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0) + +-static inline bfd_boolean ++static inline bool + skip_past_char (char **str, char c) + { + if (**str == c) + { + (*str)++; +- return TRUE; ++ return true; + } + else +- return FALSE; ++ return false; + } + + #define skip_past_comma(str) skip_past_char (str, ',') + + /* Arithmetic expressions (possibly involving symbols). */ + +-static bfd_boolean in_my_get_expression_p = FALSE; ++static bool in_aarch64_get_expression = false; + +-/* Third argument to my_get_expression. */ +-#define GE_NO_PREFIX 0 +-#define GE_OPT_PREFIX 1 ++/* Third argument to aarch64_get_expression. */ ++#define GE_NO_PREFIX false ++#define GE_OPT_PREFIX true + +-/* Return TRUE if the string pointed by *STR is successfully parsed ++/* Fourth argument to aarch64_get_expression. */ ++#define ALLOW_ABSENT false ++#define REJECT_ABSENT true ++ ++/* Fifth argument to aarch64_get_expression. */ ++#define NORMAL_RESOLUTION false ++ ++/* Return true if the string pointed by *STR is successfully parsed + as an valid expression; *EP will be filled with the information of +- such an expression. Otherwise return FALSE. */ ++ such an expression. Otherwise return false. ++ ++ If ALLOW_IMMEDIATE_PREFIX is true then skip a '#' at the start. ++ If REJECT_ABSENT is true then trat missing expressions as an error. ++ If DEFER_RESOLUTION is true, then do not resolve expressions against ++ constant symbols. Necessary if the expression is part of a fixup ++ that uses a reloc that must be emitted. */ + +-static bfd_boolean +-my_get_expression (expressionS * ep, char **str, int prefix_mode, +- int reject_absent) ++static bool ++aarch64_get_expression (expressionS * ep, ++ char ** str, ++ bool allow_immediate_prefix, ++ bool reject_absent, ++ bool defer_resolution) + { + char *save_in; + segT seg; +- int prefix_present_p = 0; ++ bool prefix_present = false; + +- switch (prefix_mode) ++ if (allow_immediate_prefix) + { +- case GE_NO_PREFIX: +- break; +- case GE_OPT_PREFIX: + if (is_immediate_prefix (**str)) + { + (*str)++; +- prefix_present_p = 1; ++ prefix_present = true; + } +- break; +- default: +- abort (); + } + + memset (ep, 0, sizeof (expressionS)); + + save_in = input_line_pointer; + input_line_pointer = *str; +- in_my_get_expression_p = TRUE; +- seg = expression (ep); +- in_my_get_expression_p = FALSE; ++ in_aarch64_get_expression = true; ++ if (defer_resolution) ++ seg = deferred_expression (ep); ++ else ++ seg = expression (ep); ++ in_aarch64_get_expression = false; + + if (ep->X_op == O_illegal || (reject_absent && ep->X_op == O_absent)) + { + /* We found a bad expression in md_operand(). */ + *str = input_line_pointer; + input_line_pointer = save_in; +- if (prefix_present_p && ! error_p ()) ++ if (prefix_present && ! error_p ()) + set_fatal_syntax_error (_("bad expression")); + else + set_first_syntax_error (_("bad expression")); +- return FALSE; ++ return false; + } + + #ifdef OBJ_AOUT + if (seg != absolute_section + && seg != text_section + && seg != data_section +- && seg != bss_section && seg != undefined_section) ++ && seg != bss_section ++ && seg != undefined_section) + { + set_syntax_error (_("bad segment")); + *str = input_line_pointer; + input_line_pointer = save_in; +- return FALSE; ++ return false; + } + #else + (void) seg; +@@ -620,7 +629,7 @@ my_get_expression (expressionS * ep, char **str, int prefix_mode, + + *str = input_line_pointer; + input_line_pointer = save_in; +- return TRUE; ++ return true; + } + + /* Turn a string in input_line_pointer into a floating point constant +@@ -687,7 +696,7 @@ md_atof (int type, char *litP, int *sizeP) + void + md_operand (expressionS * exp) + { +- if (in_my_get_expression_p) ++ if (in_aarch64_get_expression) + exp->X_op = O_illegal; + } + +@@ -769,9 +778,9 @@ parse_reg (char **ccp) + return reg; + } + +-/* Return TRUE if REG->TYPE is a valid type of TYPE; otherwise +- return FALSE. */ +-static bfd_boolean ++/* Return true if REG->TYPE is a valid type of TYPE; otherwise ++ return false. */ ++static bool + aarch64_check_reg_type (const reg_entry *reg, aarch64_reg_type type) + { + return (reg_type_masks[type] & (1 << reg->type)) != 0; +@@ -848,13 +857,13 @@ aarch64_reg_parse_32_64 (char **ccp, aarch64_opnd_qualifier_t *qualifier) + } + + /* Parse the qualifier of a vector register or vector element of type +- REG_TYPE. Fill in *PARSED_TYPE and return TRUE if the parsing +- succeeds; otherwise return FALSE. ++ REG_TYPE. Fill in *PARSED_TYPE and return true if the parsing ++ succeeds; otherwise return false. + + Accept only one occurrence of: + 4b 8b 16b 2h 4h 8h 2s 4s 1d 2d + b h s d q */ +-static bfd_boolean ++static bool + parse_vector_type_for_operand (aarch64_reg_type reg_type, + struct vector_type_el *parsed_type, char **str) + { +@@ -876,7 +885,7 @@ parse_vector_type_for_operand (aarch64_reg_type reg_type, + if (width != 1 && width != 2 && width != 4 && width != 8 && width != 16) + { + first_error_fmt (_("bad size %d in vector width specifier"), width); +- return FALSE; ++ return false; + } + + elt_size: +@@ -911,7 +920,7 @@ elt_size: + first_error_fmt (_("unexpected character `%c' in element size"), *ptr); + else + first_error (_("missing element size")); +- return FALSE; ++ return false; + } + if (width != 0 && width * element_size != 64 + && width * element_size != 128 +@@ -921,7 +930,7 @@ elt_size: + first_error_fmt (_ + ("invalid element size %d and vector size combination %c"), + width, *ptr); +- return FALSE; ++ return false; + } + ptr++; + +@@ -930,13 +939,13 @@ elt_size: + + *str = ptr; + +- return TRUE; ++ return true; + } + + /* *STR contains an SVE zero/merge predication suffix. Parse it into + *PARSED_TYPE and point *STR at the end of the suffix. */ + +-static bfd_boolean ++static bool + parse_predication_for_operand (struct vector_type_el *parsed_type, char **str) + { + char *ptr = *str; +@@ -958,11 +967,11 @@ parse_predication_for_operand (struct vector_type_el *parsed_type, char **str) + *ptr); + else + first_error (_("missing predication type")); +- return FALSE; ++ return false; + } + parsed_type->width = 0; + *str = ptr + 1; +- return TRUE; ++ return true; + } + + /* Parse a register of the type TYPE. +@@ -974,18 +983,18 @@ parse_predication_for_operand (struct vector_type_el *parsed_type, char **str) + type of the register in *RTYPE when multiple alternatives were given, and + return the register shape and element index information in *TYPEINFO. + +- IN_REG_LIST should be set with TRUE if the caller is parsing a register ++ IN_REG_LIST should be set with true if the caller is parsing a register + list. */ + + static int + parse_typed_reg (char **ccp, aarch64_reg_type type, aarch64_reg_type *rtype, +- struct vector_type_el *typeinfo, bfd_boolean in_reg_list) ++ struct vector_type_el *typeinfo, bool in_reg_list) + { + char *str = *ccp; + const reg_entry *reg = parse_reg (&str); + struct vector_type_el atype; + struct vector_type_el parsetype; +- bfd_boolean is_typed_vecreg = FALSE; ++ bool is_typed_vecreg = false; + + atype.defined = 0; + atype.type = NT_invtype; +@@ -1023,7 +1032,7 @@ parse_typed_reg (char **ccp, aarch64_reg_type type, aarch64_reg_type *rtype, + } + + /* Register if of the form Vn.[bhsdq]. */ +- is_typed_vecreg = TRUE; ++ is_typed_vecreg = true; + + if (type == REG_TYPE_ZN || type == REG_TYPE_PN) + { +@@ -1064,7 +1073,8 @@ parse_typed_reg (char **ccp, aarch64_reg_type type, aarch64_reg_type *rtype, + + atype.defined |= NTA_HASINDEX; + +- my_get_expression (&exp, &str, GE_NO_PREFIX, 1); ++ aarch64_get_expression (&exp, &str, GE_NO_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION); + + if (exp.X_op != O_constant) + { +@@ -1120,7 +1130,7 @@ aarch64_reg_parse (char **ccp, aarch64_reg_type type, + struct vector_type_el atype; + char *str = *ccp; + int reg = parse_typed_reg (&str, type, rtype, &atype, +- /*in_reg_list= */ FALSE); ++ /*in_reg_list= */ false); + + if (reg == PARSE_FAIL) + return PARSE_FAIL; +@@ -1133,7 +1143,7 @@ aarch64_reg_parse (char **ccp, aarch64_reg_type type, + return reg; + } + +-static inline bfd_boolean ++static inline bool + eq_vector_type_el (struct vector_type_el e1, struct vector_type_el e2) + { + return +@@ -1174,8 +1184,8 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type, + int in_range; + int ret_val; + int i; +- bfd_boolean error = FALSE; +- bfd_boolean expect_index = FALSE; ++ bool error = false; ++ bool expect_index = false; + + if (*str != '{') + { +@@ -1201,23 +1211,23 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type, + val_range = val; + } + val = parse_typed_reg (&str, type, NULL, &typeinfo, +- /*in_reg_list= */ TRUE); ++ /*in_reg_list= */ true); + if (val == PARSE_FAIL) + { + set_first_syntax_error (_("invalid vector register in list")); +- error = TRUE; ++ error = true; + continue; + } + /* reject [bhsd]n */ + if (type == REG_TYPE_VN && typeinfo.defined == 0) + { + set_first_syntax_error (_("invalid scalar register in list")); +- error = TRUE; ++ error = true; + continue; + } + + if (typeinfo.defined & NTA_HASINDEX) +- expect_index = TRUE; ++ expect_index = true; + + if (in_range) + { +@@ -1225,7 +1235,7 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type, + { + set_first_syntax_error + (_("invalid range in vector register list")); +- error = TRUE; ++ error = true; + } + val_range++; + } +@@ -1238,7 +1248,7 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type, + { + set_first_syntax_error + (_("type mismatch in vector register list")); +- error = TRUE; ++ error = true; + } + } + if (! error) +@@ -1255,7 +1265,7 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type, + if (*str != '}') + { + set_first_syntax_error (_("end of vector register list not found")); +- error = TRUE; ++ error = true; + } + str++; + +@@ -1267,33 +1277,34 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type, + { + expressionS exp; + +- my_get_expression (&exp, &str, GE_NO_PREFIX, 1); ++ aarch64_get_expression (&exp, &str, GE_NO_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION); + if (exp.X_op != O_constant) + { + set_first_syntax_error (_("constant expression required.")); +- error = TRUE; ++ error = true; + } + if (! skip_past_char (&str, ']')) +- error = TRUE; ++ error = true; + else + typeinfo_first.index = exp.X_add_number; + } + else + { + set_first_syntax_error (_("expected index")); +- error = TRUE; ++ error = true; + } + } + + if (nb_regs > 4) + { + set_first_syntax_error (_("too many registers in vector register list")); +- error = TRUE; ++ error = true; + } + else if (nb_regs == 0) + { + set_first_syntax_error (_("empty vector register list")); +- error = TRUE; ++ error = true; + } + + *ccp = str; +@@ -1331,7 +1342,7 @@ insert_reg_alias (char *str, int number, aarch64_reg_type type) + new->name = name; + new->number = number; + new->type = type; +- new->builtin = FALSE; ++ new->builtin = false; + + if (hash_insert (aarch64_reg_hsh, name, (void *) new)) + abort (); +@@ -1344,9 +1355,9 @@ insert_reg_alias (char *str, int number, aarch64_reg_type type) + new_register_name .req existing_register_name + + If we find one, or if it looks sufficiently like one that we want to +- handle any error here, return TRUE. Otherwise return FALSE. */ ++ handle any error here, return true. Otherwise return false. */ + +-static bfd_boolean ++static bool + create_register_alias (char *newname, char *p) + { + const reg_entry *old; +@@ -1357,17 +1368,17 @@ create_register_alias (char *newname, char *p) + collapsed to single spaces. */ + oldname = p; + if (strncmp (oldname, " .req ", 6) != 0) +- return FALSE; ++ return false; + + oldname += 6; + if (*oldname == '\0') +- return FALSE; ++ return false; + + old = hash_find (aarch64_reg_hsh, oldname); + if (!old) + { + as_warn (_("unknown register '%s' -- .req ignored"), oldname); +- return TRUE; ++ return true; + } + + /* If TC_CASE_SENSITIVE is defined, then newname already points to +@@ -1404,7 +1415,7 @@ create_register_alias (char *newname, char *p) + if (insert_reg_alias (nbuf, old->number, old->type) == NULL) + { + free (nbuf); +- return TRUE; ++ return true; + } + } + +@@ -1416,7 +1427,7 @@ create_register_alias (char *newname, char *p) + } + + free (nbuf); +- return TRUE; ++ return true; + } + + /* Should never be called, as .req goes between the alias and the +@@ -1464,7 +1475,7 @@ s_unreq (int a ATTRIBUTE_UNUSED) + char *p; + char *nbuf; + +- hash_delete (aarch64_reg_hsh, name, FALSE); ++ hash_delete (aarch64_reg_hsh, name, false); + free ((char *) reg->name); + free (reg); + +@@ -1478,7 +1489,7 @@ s_unreq (int a ATTRIBUTE_UNUSED) + reg = hash_find (aarch64_reg_hsh, nbuf); + if (reg) + { +- hash_delete (aarch64_reg_hsh, nbuf, FALSE); ++ hash_delete (aarch64_reg_hsh, nbuf, false); + free ((char *) reg->name); + free (reg); + } +@@ -1488,7 +1499,7 @@ s_unreq (int a ATTRIBUTE_UNUSED) + reg = hash_find (aarch64_reg_hsh, nbuf); + if (reg) + { +- hash_delete (aarch64_reg_hsh, nbuf, FALSE); ++ hash_delete (aarch64_reg_hsh, nbuf, false); + free ((char *) reg->name); + free (reg); + } +@@ -1748,8 +1759,8 @@ find_or_make_literal_pool (int size) + } + + /* Add the literal of size SIZE in *EXP to the relevant literal pool. +- Return TRUE on success, otherwise return FALSE. */ +-static bfd_boolean ++ Return true on success, otherwise return false. */ ++static bool + add_to_lit_pool (expressionS *exp, int size) + { + literal_pool *pool; +@@ -1782,7 +1793,7 @@ add_to_lit_pool (expressionS *exp, int size) + if (entry >= MAX_LITERAL_POOL_SIZE) + { + set_syntax_error (_("literal pool overflow")); +- return FALSE; ++ return false; + } + + pool->literals[entry].exp = *exp; +@@ -1804,7 +1815,7 @@ add_to_lit_pool (expressionS *exp, int size) + exp->X_add_number = ((int) entry) * size; + exp->X_add_symbol = pool->symbol; + +- return TRUE; ++ return true; + } + + /* Can't use symbol_new here, so have to create a symbol and then at +@@ -2149,24 +2160,24 @@ const pseudo_typeS md_pseudo_table[] = { + + /* Check whether STR points to a register name followed by a comma or the + end of line; REG_TYPE indicates which register types are checked +- against. Return TRUE if STR is such a register name; otherwise return +- FALSE. The function does not intend to produce any diagnostics, but since ++ against. Return true if STR is such a register name; otherwise return ++ false. The function does not intend to produce any diagnostics, but since + the register parser aarch64_reg_parse, which is called by this function, + does produce diagnostics, we call clear_error to clear any diagnostics + that may be generated by aarch64_reg_parse. +- Also, the function returns FALSE directly if there is any user error ++ Also, the function returns false directly if there is any user error + present at the function entry. This prevents the existing diagnostics + state from being spoiled. + The function currently serves parse_constant_immediate and + parse_big_immediate only. */ +-static bfd_boolean ++static bool + reg_name_p (char *str, aarch64_reg_type reg_type) + { + int reg; + + /* Prevent the diagnostics state from being spoiled. */ + if (error_p ()) +- return FALSE; ++ return false; + + reg = aarch64_reg_parse (&str, reg_type, NULL, NULL); + +@@ -2174,13 +2185,13 @@ reg_name_p (char *str, aarch64_reg_type reg_type) + clear_error (); + + if (reg == PARSE_FAIL) +- return FALSE; ++ return false; + + skip_whitespace (str); +- if (*str == ',' || is_end_of_line[(unsigned int) *str]) +- return TRUE; ++ if (*str == ',' || is_end_of_line[(unsigned char) *str]) ++ return true; + +- return FALSE; ++ return false; + } + + /* Parser functions used exclusively in instruction operands. */ +@@ -2190,27 +2201,28 @@ reg_name_p (char *str, aarch64_reg_type reg_type) + 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 register of type REG_TYPE followed +- by a comma or the end of line. Return FALSE if STR is such a string. */ ++ by a comma or the end of line. Return false if STR is such a string. */ + +-static bfd_boolean ++static bool + parse_immediate_expression (char **str, expressionS *exp, + aarch64_reg_type reg_type) + { + if (reg_name_p (*str, reg_type)) + { + set_recoverable_error (_("immediate operand required")); +- return FALSE; ++ return false; + } + +- my_get_expression (exp, str, GE_OPT_PREFIX, 1); ++ aarch64_get_expression (exp, str, GE_OPT_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION); + + if (exp->X_op == O_absent) + { + set_fatal_syntax_error (_("missing immediate expression")); +- return FALSE; ++ return false; + } + +- return TRUE; ++ return true; + } + + /* Constant immediate-value read function for use in insn parsing. +@@ -2218,24 +2230,24 @@ parse_immediate_expression (char **str, expressionS *exp, + 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. */ ++ Return true on success; otherwise return false. */ + +-static bfd_boolean ++static bool + parse_constant_immediate (char **str, int64_t *val, aarch64_reg_type reg_type) + { + expressionS exp; + + if (! parse_immediate_expression (str, &exp, reg_type)) +- return FALSE; ++ return false; + + if (exp.X_op != O_constant) + { + set_syntax_error (_("constant expression required")); +- return FALSE; ++ return false; + } + + *val = exp.X_add_number; +- return TRUE; ++ return true; + } + + static uint32_t +@@ -2245,14 +2257,14 @@ encode_imm_float_bits (uint32_t imm) + | ((imm >> (31 - 7)) & 0x80); /* b[31] -> b[7] */ + } + +-/* Return TRUE if the single-precision floating-point value encoded in IMM ++/* Return true if the single-precision floating-point value encoded in IMM + can be expressed in the AArch64 8-bit signed floating-point format with + 3-bit exponent and normalized 4 bits of precision; in other words, the + floating-point value must be expressable as + (+/-) n / 16 * power (2, r) + where n and r are integers such that 16 <= n <=31 and -3 <= r <= 4. */ + +-static bfd_boolean ++static bool + aarch64_imm_float_p (uint32_t imm) + { + /* If a single-precision floating-point value has the following bit +@@ -2278,11 +2290,11 @@ aarch64_imm_float_p (uint32_t imm) + && ((imm & 0x7e000000) == pattern); /* bits 25 - 29 == ~ bit 30. */ + } + +-/* Return TRUE if the IEEE double value encoded in IMM can be expressed ++/* Return true if the IEEE double value encoded in IMM can be expressed + as an IEEE float without any loss of precision. Store the value in + *FPWORD if so. */ + +-static bfd_boolean ++static bool + can_convert_double_to_float (uint64_t imm, uint32_t *fpword) + { + /* If a double-precision floating-point value has the following bit +@@ -2304,7 +2316,7 @@ can_convert_double_to_float (uint64_t imm, uint32_t *fpword) + + /* Lower 29 bits need to be 0s. */ + if ((imm & 0x1fffffff) != 0) +- return FALSE; ++ return false; + + /* Prepare the pattern for 'Eeeeeeeee'. */ + if (((high32 >> 30) & 0x1) == 0) +@@ -2314,21 +2326,21 @@ can_convert_double_to_float (uint64_t imm, uint32_t *fpword) + + /* Check E~~~. */ + if ((high32 & 0x78000000) != pattern) +- return FALSE; ++ return false; + + /* Check Eeee_eeee != 1111_1111. */ + if ((high32 & 0x7ff00000) == 0x47f00000) +- return FALSE; ++ return false; + + *fpword = ((high32 & 0xc0000000) /* 1 n bit and 1 E bit. */ + | ((high32 << 3) & 0x3ffffff8) /* 7 e and 20 s bits. */ + | (low32 >> 29)); /* 3 S bits. */ +- return TRUE; ++ return true; + } + + /* Return true if we should treat OPERAND as a double-precision + floating-point operand rather than a single-precision one. */ +-static bfd_boolean ++static bool + double_precision_operand_p (const aarch64_opnd_info *operand) + { + /* Check for unsuffixed SVE registers, which are allowed +@@ -2340,9 +2352,9 @@ double_precision_operand_p (const aarch64_opnd_info *operand) + || aarch64_get_qualifier_esize (operand->qualifier) == 8); + } + +-/* Parse a floating-point immediate. Return TRUE on success and return the ++/* Parse a floating-point immediate. Return true on success and return the + 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 ++ *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). REG_TYPE says which register + names should be treated as registers rather than as symbolic immediates. +@@ -2350,8 +2362,8 @@ double_precision_operand_p (const aarch64_opnd_info *operand) + This routine accepts any IEEE float; it is up to the callers to reject + invalid ones. */ + +-static bfd_boolean +-parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p, ++static bool ++parse_aarch64_imm_float (char **ccp, int *immed, bool dp_p, + aarch64_reg_type reg_type) + { + char *str = *ccp; +@@ -2360,7 +2372,7 @@ parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p, + int found_fpchar = 0; + int64_t val = 0; + unsigned fpword = 0; +- bfd_boolean hex_p = FALSE; ++ bool hex_p = false; + + skip_past_char (&str, '#'); + +@@ -2370,7 +2382,7 @@ parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p, + if (strncmp (fpnum, "0x", 2) == 0) + { + /* Support the hexadecimal representation of the IEEE754 encoding. +- Double-precision is expected when DP_P is TRUE, otherwise the ++ Double-precision is expected when DP_P is true, otherwise the + representation should be in single-precision. */ + if (! parse_constant_immediate (&str, &val, reg_type)) + goto invalid_fp; +@@ -2385,14 +2397,14 @@ parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p, + else + fpword = val; + +- hex_p = TRUE; ++ hex_p = true; + } + else + { + if (reg_name_p (str, reg_type)) + { + set_recoverable_error (_("immediate operand required")); +- return FALSE; ++ return false; + } + + /* We must not accidentally parse an integer as a floating-point number. +@@ -2406,7 +2418,7 @@ parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p, + } + + if (!found_fpchar) +- return FALSE; ++ return false; + } + + if (! hex_p) +@@ -2426,11 +2438,11 @@ parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p, + + *immed = fpword; + *ccp = str; +- return TRUE; ++ return true; + + invalid_fp: + set_fatal_syntax_error (_("invalid floating-point constant")); +- return FALSE; ++ return false; + } + + /* Less-generic immediate-value read function with the possibility of loading +@@ -2440,9 +2452,9 @@ invalid_fp: + 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 register of type REG_TYPE followed by a comma or +- the end of line. Return FALSE if STR is such a register. */ ++ the end of line. Return false if STR is such a register. */ + +-static bfd_boolean ++static bool + parse_big_immediate (char **str, int64_t *imm, aarch64_reg_type reg_type) + { + char *ptr = *str; +@@ -2450,17 +2462,18 @@ parse_big_immediate (char **str, int64_t *imm, aarch64_reg_type reg_type) + if (reg_name_p (ptr, reg_type)) + { + set_syntax_error (_("immediate operand required")); +- return FALSE; ++ return false; + } + +- my_get_expression (&inst.reloc.exp, &ptr, GE_OPT_PREFIX, 1); ++ aarch64_get_expression (&inst.reloc.exp, &ptr, GE_OPT_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION); + + if (inst.reloc.exp.X_op == O_constant) + *imm = inst.reloc.exp.X_add_number; + + *str = ptr; + +- return TRUE; ++ return true; + } + + /* Set operand IDX of the *INSTR that needs a GAS internal fixup. +@@ -2478,10 +2491,10 @@ aarch64_set_gas_internal_fixup (struct reloc *reloc, + reloc->need_libopcodes_p = 1; + }; + +-/* Return TRUE if the instruction needs to be fixed up later internally by +- the GAS; otherwise return FALSE. */ ++/* Return true if the instruction needs to be fixed up later internally by ++ the GAS; otherwise return false. */ + +-static inline bfd_boolean ++static inline bool + aarch64_gas_internal_fixup_p (void) + { + return inst.reloc.type == BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP; +@@ -2537,7 +2550,8 @@ struct reloc_table_entry + bfd_reloc_code_real_type ld_literal_type; + }; + +-static struct reloc_table_entry reloc_table[] = { ++static struct reloc_table_entry reloc_table[] = ++{ + /* Low 12 bits of absolute address: ADD/i and LDR/STR */ + {"lo12", 0, + 0, /* adr_type */ +@@ -3027,6 +3041,109 @@ find_reloc_table_entry (char **str) + return NULL; + } + ++/* Returns 0 if the relocation should never be forced, ++ 1 if the relocation must be forced, and -1 if either ++ result is OK. */ ++ ++static signed int ++aarch64_force_reloc (unsigned int type) ++{ ++ switch (type) ++ { ++ case BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP: ++ /* Perform these "immediate" internal relocations ++ even if the symbol is extern or weak. */ ++ return 0; ++ ++ case BFD_RELOC_AARCH64_LD_GOT_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC: ++ /* Pseudo relocs that need to be fixed up according to ++ ilp32_p. */ ++ return 0; ++ ++ case BFD_RELOC_AARCH64_ADD_LO12: ++ case BFD_RELOC_AARCH64_ADR_GOT_PAGE: ++ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: ++ case BFD_RELOC_AARCH64_ADR_HI21_PCREL: ++ case BFD_RELOC_AARCH64_GOT_LD_PREL19: ++ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: ++ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: ++ case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: ++ case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: ++ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: ++ case BFD_RELOC_AARCH64_LDST128_LO12: ++ case BFD_RELOC_AARCH64_LDST16_LO12: ++ case BFD_RELOC_AARCH64_LDST32_LO12: ++ case BFD_RELOC_AARCH64_LDST64_LO12: ++ case BFD_RELOC_AARCH64_LDST8_LO12: ++ case BFD_RELOC_AARCH64_LDST_LO12: ++ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: ++ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: ++ case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: ++ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: ++ case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: ++ case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: ++ case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: ++ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: ++ case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21: ++ case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: ++ case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: ++ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: ++ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: ++ case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: ++ case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: ++ case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: ++ case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: ++ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: ++ case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: ++ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: ++ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: ++ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: ++ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: ++ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: ++ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: ++ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: ++ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: ++ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: ++ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: ++ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: ++ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: ++ /* Always leave these relocations for the linker. */ ++ return 1; ++ ++ default: ++ return -1; ++ } ++} ++ ++int ++aarch64_force_relocation (struct fix *fixp) ++{ ++ int res = aarch64_force_reloc (fixp->fx_r_type); ++ ++ if (res == -1) ++ return generic_force_reloc (fixp); ++ return res; ++} ++ + /* Mode argument to parse_shift and parser_shifter_operand. */ + enum parse_shift_mode + { +@@ -3043,8 +3160,8 @@ enum parse_shift_mode + }; + + /* Parse a operator on an AArch64 data processing instruction. +- Return TRUE on success; otherwise return FALSE. */ +-static bfd_boolean ++ Return true on success; otherwise return false. */ ++static bool + parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + { + const struct aarch64_name_value_pair *shift_op; +@@ -3060,7 +3177,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (p == *str) + { + set_syntax_error (_("shift expression expected")); +- return FALSE; ++ return false; + } + + shift_op = hash_find_n (aarch64_shift_hsh, *str, p - *str); +@@ -3068,7 +3185,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (shift_op == NULL) + { + set_syntax_error (_("shift operator expected")); +- return FALSE; ++ return false; + } + + kind = aarch64_get_operand_modifier (shift_op); +@@ -3076,7 +3193,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (kind == AARCH64_MOD_MSL && mode != SHIFTED_LSL_MSL) + { + set_syntax_error (_("invalid use of 'MSL'")); +- return FALSE; ++ return false; + } + + if (kind == AARCH64_MOD_MUL +@@ -3084,7 +3201,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + && mode != SHIFTED_MUL_VL) + { + set_syntax_error (_("invalid use of 'MUL'")); +- return FALSE; ++ return false; + } + + switch (mode) +@@ -3093,7 +3210,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (aarch64_extend_operator_p (kind)) + { + set_syntax_error (_("extending shift is not permitted")); +- return FALSE; ++ return false; + } + break; + +@@ -3101,7 +3218,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (kind == AARCH64_MOD_ROR) + { + set_syntax_error (_("'ROR' shift is not permitted")); +- return FALSE; ++ return false; + } + break; + +@@ -3109,7 +3226,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (kind != AARCH64_MOD_LSL) + { + set_syntax_error (_("only 'LSL' shift is permitted")); +- return FALSE; ++ return false; + } + break; + +@@ -3117,7 +3234,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (kind != AARCH64_MOD_MUL) + { + set_syntax_error (_("only 'MUL' is permitted")); +- return FALSE; ++ return false; + } + break; + +@@ -3135,7 +3252,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + } + } + set_syntax_error (_("only 'MUL VL' is permitted")); +- return FALSE; ++ return false; + + case SHIFTED_REG_OFFSET: + if (kind != AARCH64_MOD_UXTW && kind != AARCH64_MOD_LSL +@@ -3143,7 +3260,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + { + set_fatal_syntax_error + (_("invalid shift for the register offset addressing mode")); +- return FALSE; ++ return false; + } + break; + +@@ -3151,7 +3268,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (kind != AARCH64_MOD_LSL && kind != AARCH64_MOD_MSL) + { + set_syntax_error (_("invalid shift operator")); +- return FALSE; ++ return false; + } + break; + +@@ -3173,7 +3290,8 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + p++; + exp_has_prefix = 1; + } +- my_get_expression (&exp, &p, GE_NO_PREFIX, 0); ++ (void) aarch64_get_expression (&exp, &p, GE_NO_PREFIX, ALLOW_ABSENT, ++ NORMAL_RESOLUTION); + } + if (kind == AARCH64_MOD_MUL_VL) + /* For consistency, give MUL VL the same shift amount as an implicit +@@ -3184,14 +3302,14 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + if (!aarch64_extend_operator_p (kind) || exp_has_prefix) + { + set_syntax_error (_("missing shift amount")); +- return FALSE; ++ return false; + } + operand->shifter.amount = 0; + } + else if (exp.X_op != O_constant) + { + set_syntax_error (_("constant shift amount required")); +- return FALSE; ++ return false; + } + /* For parsing purposes, MUL #n has no inherent range. The range + depends on the operand and will be checked by operand-specific +@@ -3200,7 +3318,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + && (exp.X_add_number < 0 || exp.X_add_number > 63)) + { + set_fatal_syntax_error (_("shift amount out of range 0 to 63")); +- return FALSE; ++ return false; + } + else + { +@@ -3212,7 +3330,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + operand->shifter.kind = kind; + + *str = p; +- return TRUE; ++ return true; + } + + /* Parse a for a data processing instruction: +@@ -3222,38 +3340,39 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) + + Validation of immediate operands is deferred to md_apply_fix. + +- Return TRUE on success; otherwise return FALSE. */ ++ Return true on success; otherwise return false. */ + +-static bfd_boolean ++static bool + parse_shifter_operand_imm (char **str, aarch64_opnd_info *operand, + enum parse_shift_mode mode) + { + char *p; + + if (mode != SHIFTED_ARITH_IMM && mode != SHIFTED_LOGIC_IMM) +- return FALSE; ++ return false; + + p = *str; + + /* Accept an immediate expression. */ +- if (! my_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX, 1)) +- return FALSE; ++ if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX, ++ REJECT_ABSENT, NORMAL_RESOLUTION)) ++ return false; + + /* Accept optional LSL for arithmetic immediate values. */ + if (mode == SHIFTED_ARITH_IMM && skip_past_comma (&p)) + if (! parse_shift (&p, operand, SHIFTED_LSL)) +- return FALSE; ++ return false; + + /* Not accept any shifter for logical immediate values. */ + if (mode == SHIFTED_LOGIC_IMM && skip_past_comma (&p) + && parse_shift (&p, operand, mode)) + { + set_syntax_error (_("unexpected shift operator")); +- return FALSE; ++ return false; + } + + *str = p; +- return TRUE; ++ return true; + } + + /* Parse a for a data processing instruction: +@@ -3268,9 +3387,9 @@ parse_shifter_operand_imm (char **str, aarch64_opnd_info *operand, + + Validation of immediate operands is deferred to md_apply_fix. + +- Return TRUE on success; otherwise return FALSE. */ ++ Return true on success; otherwise return false. */ + +-static bfd_boolean ++static bool + parse_shifter_operand (char **str, aarch64_opnd_info *operand, + enum parse_shift_mode mode) + { +@@ -3285,13 +3404,13 @@ parse_shifter_operand (char **str, aarch64_opnd_info *operand, + if (opd_class == AARCH64_OPND_CLASS_IMMEDIATE) + { + set_syntax_error (_("unexpected register in the immediate operand")); +- return FALSE; ++ return false; + } + + if (!aarch64_check_reg_type (reg, REG_TYPE_R_Z)) + { + set_syntax_error (_(get_reg_expected_msg (REG_TYPE_R_Z))); +- return FALSE; ++ return false; + } + + operand->reg.regno = reg->number; +@@ -3299,28 +3418,28 @@ parse_shifter_operand (char **str, aarch64_opnd_info *operand, + + /* Accept optional shift operation on register. */ + if (! skip_past_comma (str)) +- return TRUE; ++ return true; + + if (! parse_shift (str, operand, mode)) +- return FALSE; ++ return false; + +- return TRUE; ++ return true; + } + else if (opd_class == AARCH64_OPND_CLASS_MODIFIED_REG) + { + set_syntax_error + (_("integer register expected in the extended/shifted operand " + "register")); +- return FALSE; ++ return false; + } + + /* We have a shifted immediate variable. */ + return parse_shifter_operand_imm (str, operand, mode); + } + +-/* Return TRUE on success; return FALSE otherwise. */ ++/* Return true on success; return false otherwise. */ + +-static bfd_boolean ++static bool + parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand, + enum parse_shift_mode mode) + { +@@ -3345,22 +3464,24 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand, + if (!(entry = find_reloc_table_entry (str))) + { + set_syntax_error (_("unknown relocation modifier")); +- return FALSE; ++ return false; + } + + if (entry->add_type == 0) + { + set_syntax_error + (_("this relocation modifier is not allowed on this instruction")); +- return FALSE; ++ return false; + } + + /* Save str before we decompose it. */ + p = *str; + + /* Next, we parse the expression. */ +- if (! my_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX, 1)) +- return FALSE; ++ if (! aarch64_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX, ++ REJECT_ABSENT, ++ aarch64_force_reloc (entry->add_type) == 1)) ++ return false; + + /* Record the relocation type (use the ADD variant here). */ + inst.reloc.type = entry->add_type; +@@ -3368,7 +3489,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand, + + /* If str is empty, we've reached the end, stop here. */ + if (**str == '\0') +- return TRUE; ++ return true; + + /* Otherwise, we have a shifted reloc modifier, so rewind to + recover the variable name and continue parsing for the shifter. */ +@@ -3448,7 +3569,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand, + for addressing modes not supported by the instruction, and to set + inst.reloc.type. */ + +-static bfd_boolean ++static bool + parse_address_main (char **str, aarch64_opnd_info *operand, + aarch64_opnd_qualifier_t *base_qualifier, + aarch64_opnd_qualifier_t *offset_qualifier, +@@ -3480,7 +3601,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (! entry) + { + set_syntax_error (_("unknown relocation modifier")); +- return FALSE; ++ return false; + } + + switch (operand->type) +@@ -3500,14 +3621,15 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + set_syntax_error + (_("this relocation modifier is not allowed on this " + "instruction")); +- return FALSE; ++ return false; + } + + /* #:: */ +- if (! my_get_expression (exp, &p, GE_NO_PREFIX, 1)) ++ if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT, ++ aarch64_force_reloc (ty) == 1)) + { + set_syntax_error (_("invalid relocation expression")); +- return FALSE; ++ return false; + } + + /* #:: */ +@@ -3517,20 +3639,20 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + } + else + { +- + if (skip_past_char (&p, '=')) + /* =immediate; need to generate the literal in the literal pool. */ + inst.gen_lit_pool = 1; + +- if (!my_get_expression (exp, &p, GE_NO_PREFIX, 1)) ++ if (!aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION)) + { + set_syntax_error (_("invalid address")); +- return FALSE; ++ return false; + } + } + + *str = p; +- return TRUE; ++ return true; + } + + /* [ */ +@@ -3539,7 +3661,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (!reg || !aarch64_check_reg_type (reg, base_type)) + { + set_syntax_error (_(get_reg_expected_msg (base_type))); +- return FALSE; ++ return false; + } + operand->addr.base_regno = reg->number; + +@@ -3555,7 +3677,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (!aarch64_check_reg_type (reg, offset_type)) + { + set_syntax_error (_(get_reg_expected_msg (offset_type))); +- return FALSE; ++ return false; + } + + /* [Xn,Rm */ +@@ -3568,7 +3690,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (! parse_shift (&p, operand, SHIFTED_REG_OFFSET)) + /* Use the diagnostics set in parse_shift, so not set new + error message here. */ +- return FALSE; ++ return false; + } + /* We only accept: + [base,Xm] # For vector plus scalar SVE2 indexing. +@@ -3582,7 +3704,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (*offset_qualifier == AARCH64_OPND_QLF_W) + { + set_syntax_error (_("invalid use of 32-bit register offset")); +- return FALSE; ++ return false; + } + if (aarch64_get_qualifier_esize (*base_qualifier) + != aarch64_get_qualifier_esize (*offset_qualifier) +@@ -3591,13 +3713,13 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + || *offset_qualifier != AARCH64_OPND_QLF_X)) + { + set_syntax_error (_("offset has different size from base")); +- return FALSE; ++ return false; + } + } + else if (*offset_qualifier == AARCH64_OPND_QLF_X) + { + set_syntax_error (_("invalid use of 64-bit register offset")); +- return FALSE; ++ return false; + } + } + else +@@ -3613,7 +3735,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (!(entry = find_reloc_table_entry (&p))) + { + set_syntax_error (_("unknown relocation modifier")); +- return FALSE; ++ return false; + } + + if (entry->ldst_type == 0) +@@ -3621,17 +3743,18 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + set_syntax_error + (_("this relocation modifier is not allowed on this " + "instruction")); +- return FALSE; ++ return false; + } + + /* [Xn,#:: */ + /* We now have the group relocation table entry corresponding to + the name in the assembler source. Next, we parse the + expression. */ +- if (! my_get_expression (exp, &p, GE_NO_PREFIX, 1)) ++ if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT, ++ aarch64_force_reloc (entry->ldst_type) == 1)) + { + set_syntax_error (_("invalid relocation expression")); +- return FALSE; ++ return false; + } + + /* [Xn,#:: */ +@@ -3641,16 +3764,17 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + } + else + { +- if (! my_get_expression (exp, &p, GE_OPT_PREFIX, 1)) ++ if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION)) + { + set_syntax_error (_("invalid expression in the address")); +- return FALSE; ++ return false; + } + /* [Xn, */ + if (imm_shift_mode != SHIFTED_NONE && skip_past_comma (&p)) + /* [Xn,, */ + if (! parse_shift (&p, operand, imm_shift_mode)) +- return FALSE; ++ return false; + } + } + } +@@ -3658,7 +3782,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (! skip_past_char (&p, ']')) + { + set_syntax_error (_("']' expected")); +- return FALSE; ++ return false; + } + + if (skip_past_char (&p, '!')) +@@ -3667,7 +3791,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + { + set_syntax_error (_("register offset not allowed in pre-indexed " + "addressing mode")); +- return FALSE; ++ return false; + } + /* [Xn]! */ + operand->addr.writeback = 1; +@@ -3681,7 +3805,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (operand->addr.preind) + { + set_syntax_error (_("cannot combine pre- and post-indexing")); +- return FALSE; ++ return false; + } + + reg = aarch64_reg_parse_32_64 (&p, offset_qualifier); +@@ -3691,17 +3815,18 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + if (!aarch64_check_reg_type (reg, REG_TYPE_R_64)) + { + set_syntax_error (_(get_reg_expected_msg (REG_TYPE_R_64))); +- return FALSE; ++ return false; + } + + operand->addr.offset.regno = reg->number; + operand->addr.offset.is_reg = 1; + } +- else if (! my_get_expression (exp, &p, GE_OPT_PREFIX, 1)) ++ else if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT, ++ NORMAL_RESOLUTION)) + { + /* [Xn],#expr */ + set_syntax_error (_("invalid expression in the address")); +- return FALSE; ++ return false; + } + } + +@@ -3715,7 +3840,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + { + /* Reject [Rn]! */ + set_syntax_error (_("missing offset in the pre-indexed address")); +- return FALSE; ++ return false; + } + + operand->addr.preind = 1; +@@ -3733,12 +3858,12 @@ parse_address_main (char **str, aarch64_opnd_info *operand, + } + + *str = p; +- return TRUE; ++ return true; + } + +-/* Parse a base AArch64 address (as opposed to an SVE one). Return TRUE ++/* Parse a base AArch64 address (as opposed to an SVE one). Return true + on success. */ +-static bfd_boolean ++static bool + parse_address (char **str, aarch64_opnd_info *operand) + { + aarch64_opnd_qualifier_t base_qualifier, offset_qualifier; +@@ -3748,8 +3873,8 @@ parse_address (char **str, aarch64_opnd_info *operand) + + /* Parse an address in which SVE vector registers and MUL VL are allowed. + The arguments have the same meaning as for parse_address_main. +- Return TRUE on success. */ +-static bfd_boolean ++ Return true on success. */ ++static bool + parse_sve_address (char **str, aarch64_opnd_info *operand, + aarch64_opnd_qualifier_t *base_qualifier, + aarch64_opnd_qualifier_t *offset_qualifier) +@@ -3761,23 +3886,23 @@ parse_sve_address (char **str, aarch64_opnd_info *operand, + + /* Parse a register X0-X30. The register must be 64-bit and register 31 + is unallocated. */ +-static bfd_boolean ++static bool + parse_x0_to_x30 (char **str, aarch64_opnd_info *operand) + { + const reg_entry *reg = parse_reg (str); + if (!reg || !aarch64_check_reg_type (reg, REG_TYPE_R_64)) + { + set_syntax_error (_(get_reg_expected_msg (REG_TYPE_R_64))); +- return FALSE; ++ return false; + } + operand->reg.regno = reg->number; + operand->qualifier = AARCH64_OPND_QLF_X; +- return TRUE; ++ return true; + } + + /* Parse an operand for a MOVZ, MOVN or MOVK instruction. +- Return TRUE on success; otherwise return FALSE. */ +-static bfd_boolean ++ Return true on success; otherwise return false. */ ++static bool + parse_half (char **str, int *internal_fixup_p) + { + char *p = *str; +@@ -3793,17 +3918,18 @@ parse_half (char **str, int *internal_fixup_p) + + /* Try to parse a relocation. Anything else is an error. */ + ++p; ++ + if (!(entry = find_reloc_table_entry (&p))) + { + set_syntax_error (_("unknown relocation modifier")); +- return FALSE; ++ return false; + } + + if (entry->movw_type == 0) + { + set_syntax_error + (_("this relocation modifier is not allowed on this instruction")); +- return FALSE; ++ return false; + } + + inst.reloc.type = entry->movw_type; +@@ -3811,18 +3937,19 @@ parse_half (char **str, int *internal_fixup_p) + else + *internal_fixup_p = 1; + +- if (! my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, 1)) +- return FALSE; ++ if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT, ++ aarch64_force_reloc (inst.reloc.type) == 1)) ++ return false; + + *str = p; +- return TRUE; ++ return true; + } + + /* Parse an operand for an ADRP instruction: + ADRP ,