From c01860a95bd1fa84b55c2e17f51b772dcb18b8c3 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 17 2021 08:10:41 +0000 Subject: import binutils-2.30-101.el8 --- diff --git a/SOURCES/binutils-CVE-2021-3487.patch b/SOURCES/binutils-CVE-2021-3487.patch new file mode 100644 index 0000000..f6eb1e5 --- /dev/null +++ b/SOURCES/binutils-CVE-2021-3487.patch @@ -0,0 +1,38 @@ +--- binutils.orig/bfd/dwarf2.c 2021-04-14 14:24:18.945917267 +0100 ++++ binutils-2.30/bfd/dwarf2.c 2021-04-14 14:25:51.908614106 +0100 +@@ -532,6 +532,10 @@ read_section (bfd * abfd, + /* The section may have already been read. */ + if (contents == NULL) + { ++ bfd_size_type amt; ++ asection *msec; ++ ufile_ptr filesize; ++ + msec = bfd_get_section_by_name (abfd, section_name); + if (! msec) + { +@@ -547,10 +551,22 @@ read_section (bfd * abfd, + return FALSE; + } + +- *section_size = msec->rawsize ? msec->rawsize : msec->size; ++ amt = bfd_get_section_limit_octets (abfd, msec); ++ filesize = bfd_get_file_size (abfd); ++ if (amt >= filesize) ++ { ++ /* PR 26946 */ ++ _bfd_error_handler (_("DWARF error: section %s is larger than its filesize! (0x%lx vs 0x%lx)"), ++ section_name, (long) amt, (long) filesize); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ *section_size = amt; ++ + /* Paranoia - alloc one extra so that we can make sure a string + section is NUL terminated. */ +- amt = *section_size + 1; ++ amt += 1; ++ + if (amt == 0) + { + bfd_set_error (bfd_error_no_memory); diff --git a/SOURCES/binutils-aarch64-armv8.6-support.patch b/SOURCES/binutils-aarch64-armv8.6-support.patch deleted file mode 100644 index fd070a7..0000000 --- a/SOURCES/binutils-aarch64-armv8.6-support.patch +++ /dev/null @@ -1,146139 +0,0 @@ -diff -rup binutils-2.30/bfd/archures.c binutils-2.30.new/bfd/archures.c ---- binutils-2.30/bfd/archures.c 2021-03-23 16:21:44.001022834 +0000 -+++ binutils-2.30.new/bfd/archures.c 2021-03-23 16:20:02.829710624 +0000 -@@ -526,6 +526,7 @@ DESCRIPTION - .#define bfd_mach_tilegx32 2 - . bfd_arch_aarch64, {* AArch64. *} - .#define bfd_mach_aarch64 0 -+.#define bfd_mach_aarch64_8R 1 - .#define bfd_mach_aarch64_ilp32 32 - . bfd_arch_nios2, {* Nios II. *} - .#define bfd_mach_nios2 0 -diff -rup binutils-2.30/bfd/bfd-in2.h binutils-2.30.new/bfd/bfd-in2.h ---- binutils-2.30/bfd/bfd-in2.h 2021-03-23 16:21:44.002022828 +0000 -+++ binutils-2.30.new/bfd/bfd-in2.h 2021-03-23 16:20:02.815710719 +0000 -@@ -985,12 +985,6 @@ extern void bfd_elf64_aarch64_init_maps - extern void bfd_elf32_aarch64_init_maps - (bfd *); - --extern void bfd_elf64_aarch64_set_options -- (bfd *, struct bfd_link_info *, int, int, int, int, int, int); -- --extern void bfd_elf32_aarch64_set_options -- (bfd *, struct bfd_link_info *, int, int, int, int, int, int); -- - /* ELF AArch64 mapping symbol support. */ - #define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP (1 << 0) - #define BFD_AARCH64_SPECIAL_SYM_TYPE_TAG (1 << 1) -@@ -2388,6 +2382,7 @@ enum bfd_architecture - #define bfd_mach_tilegx32 2 - bfd_arch_aarch64, /* AArch64. */ - #define bfd_mach_aarch64 0 -+#define bfd_mach_aarch64_8R 1 - #define bfd_mach_aarch64_ilp32 32 - bfd_arch_nios2, /* Nios II. */ - #define bfd_mach_nios2 0 -@@ -5961,6 +5956,36 @@ of a signed value. Changes instruction - value's sign. */ - BFD_RELOC_AARCH64_MOVW_G2_S, - -+/* AArch64 MOV[NZ] instruction with most significant bits 0 to 15 -+of a signed value. Changes instruction to MOVZ or MOVN depending on the -+value's sign. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G0, -+ -+/* AArch64 MOV[NZ] instruction with most significant bits 0 to 15 -+of a signed value. Changes instruction to MOVZ or MOVN depending on the -+value's sign. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G0_NC, -+ -+/* AArch64 MOVK instruction with most significant bits 16 to 31 -+of a signed value. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G1, -+ -+/* AArch64 MOVK instruction with most significant bits 16 to 31 -+of a signed value. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G1_NC, -+ -+/* AArch64 MOVK instruction with most significant bits 32 to 47 -+of a signed value. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G2, -+ -+/* AArch64 MOVK instruction with most significant bits 32 to 47 -+of a signed value. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G2_NC, -+ -+/* AArch64 MOVK instruction with most significant bits 47 to 63 -+of a signed value. */ -+ BFD_RELOC_AARCH64_MOVW_PREL_G3, -+ - /* AArch64 Load Literal instruction, holding a 19 bit pc-relative word - offset. The lowest two bits must be zero and are not stored in the - instruction, giving a 21 bit signed byte offset. */ -@@ -6188,6 +6213,34 @@ instructions. */ - /* AArch64 TLS LOCAL EXEC relocation. */ - BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC, - -+/* bit[11:1] of byte offset to module TLS base address, encoded in ldst -+instructions. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, -+ -+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, -+ -+/* bit[11:2] of byte offset to module TLS base address, encoded in ldst -+instructions. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, -+ -+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, -+ -+/* bit[11:3] of byte offset to module TLS base address, encoded in ldst -+instructions. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, -+ -+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, -+ -+/* bit[11:0] of byte offset to module TLS base address, encoded in ldst -+instructions. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, -+ -+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, -+ - /* AArch64 TLS DESC relocation. */ - BFD_RELOC_AARCH64_TLSDESC_LD_PREL19, - -@@ -6271,6 +6324,14 @@ any object files. */ - /* Similar as BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12, but no overflow check. */ - BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC, - -+/* AArch64 pseudo relocation code for TLS local exec mode. It's to be -+used internally by the AArch64 assembler and not (currently) written to -+any object files. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12, -+ -+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12, but no overflow check. */ -+ BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC, -+ - /* AArch64 pseudo relocation code to be used internally by the AArch64 - assembler and not (currently) written to any object files. */ - BFD_RELOC_AARCH64_LD_GOT_LO12_NC, -diff -rup binutils-2.30/bfd/cpu-aarch64.c binutils-2.30.new/bfd/cpu-aarch64.c ---- binutils-2.30/bfd/cpu-aarch64.c 2018-01-13 13:31:15.000000000 +0000 -+++ binutils-2.30.new/bfd/cpu-aarch64.c 2021-03-23 16:20:02.830710617 +0000 -@@ -1,5 +1,5 @@ - /* BFD support for AArch64. -- Copyright (C) 2009-2018 Free Software Foundation, Inc. -+ Copyright (C) 2009-2021 Free Software Foundation, Inc. - Contributed by ARM Ltd. - - This file is part of BFD, the Binary File Descriptor library. -@@ -22,6 +22,7 @@ - #include "bfd.h" - #include "libbfd.h" - #include "libiberty.h" -+#include "cpu-aarch64.h" - - /* This routine is provided two arch_infos and works out which Aarch64 - machine which would be compatible with both and returns a pointer -@@ -68,10 +69,11 @@ static struct - } - processors[] = - { -- /* These two are example CPUs supported in GCC, once we have real -- CPUs they will be removed. */ -- { bfd_mach_aarch64, "example-1" }, -- { bfd_mach_aarch64, "example-2" } -+ { bfd_mach_aarch64, "cortex-a34" }, -+ { bfd_mach_aarch64, "cortex-a65" }, -+ { bfd_mach_aarch64, "cortex-a65ae" }, -+ { bfd_mach_aarch64, "cortex-a76ae" }, -+ { bfd_mach_aarch64, "cortex-a77" } - }; - - static bfd_boolean -@@ -103,10 +105,14 @@ scan (const struct bfd_arch_info *info, - #define N(NUMBER, PRINT, WORDSIZE, DEFAULT, NEXT) \ - { WORDSIZE, WORDSIZE, 8, bfd_arch_aarch64, NUMBER, \ - "aarch64", PRINT, 4, DEFAULT, compatible, scan, \ -- bfd_arch_default_fill, NEXT } -+ bfd_arch_default_fill, NEXT, 0 } -+ -+static const bfd_arch_info_type bfd_aarch64_arch_v8_r = -+ N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, FALSE, NULL); - - static const bfd_arch_info_type bfd_aarch64_arch_ilp32 = -- N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, FALSE, NULL); -+ N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, FALSE, -+ &bfd_aarch64_arch_v8_r); - - const bfd_arch_info_type bfd_aarch64_arch = - N (0, "aarch64", 64, TRUE, &bfd_aarch64_arch_ilp32); -diff -rup binutils-2.30/bfd/reloc.c binutils-2.30.new/bfd/reloc.c ---- binutils-2.30/bfd/reloc.c 2018-01-13 13:31:15.000000000 +0000 -+++ binutils-2.30.new/bfd/reloc.c 2021-03-23 16:20:02.829710624 +0000 -@@ -7071,6 +7071,43 @@ ENUMDOC - of a signed value. Changes instruction to MOVZ or MOVN depending on the - value's sign. - ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G0 -+ENUMDOC -+ AArch64 MOV[NZ] instruction with most significant bits 0 to 15 -+ of a signed value. Changes instruction to MOVZ or MOVN depending on the -+ value's sign. -+ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G0_NC -+ENUMDOC -+ AArch64 MOV[NZ] instruction with most significant bits 0 to 15 -+ of a signed value. Changes instruction to MOVZ or MOVN depending on the -+ value's sign. -+ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G1 -+ENUMDOC -+ AArch64 MOVK instruction with most significant bits 16 to 31 -+ of a signed value. -+ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G1_NC -+ENUMDOC -+ AArch64 MOVK instruction with most significant bits 16 to 31 -+ of a signed value. -+ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G2 -+ENUMDOC -+ AArch64 MOVK instruction with most significant bits 32 to 47 -+ of a signed value. -+ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G2_NC -+ENUMDOC -+ AArch64 MOVK instruction with most significant bits 32 to 47 -+ of a signed value. -+ENUM -+ BFD_RELOC_AARCH64_MOVW_PREL_G3 -+ENUMDOC -+ AArch64 MOVK instruction with most significant bits 47 to 63 -+ of a signed value. -+ENUM - BFD_RELOC_AARCH64_LD_LO19_PCREL - ENUMDOC - AArch64 Load Literal instruction, holding a 19 bit pc-relative word -@@ -7359,6 +7396,42 @@ ENUM - ENUMDOC - AArch64 TLS LOCAL EXEC relocation. - ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12 -+ENUMDOC -+ bit[11:1] of byte offset to module TLS base address, encoded in ldst -+ instructions. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC -+ENUMDOC -+ Similar as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12 -+ENUMDOC -+ bit[11:2] of byte offset to module TLS base address, encoded in ldst -+ instructions. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC -+ENUMDOC -+ Similar as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12 -+ENUMDOC -+ bit[11:3] of byte offset to module TLS base address, encoded in ldst -+ instructions. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC -+ENUMDOC -+ Similar as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12 -+ENUMDOC -+ bit[11:0] of byte offset to module TLS base address, encoded in ldst -+ instructions. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC -+ENUMDOC -+ Similar as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check. -+ENUM - BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 - ENUMDOC - AArch64 TLS DESC relocation. -@@ -7467,6 +7540,16 @@ ENUM - ENUMDOC - Similar as BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12, but no overflow check. - ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12 -+ENUMDOC -+ AArch64 pseudo relocation code for TLS local exec mode. It's to be -+ used internally by the AArch64 assembler and not (currently) written to -+ any object files. -+ENUM -+ BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC -+ENUMDOC -+ Similar as BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12, but no overflow check. -+ENUM - BFD_RELOC_AARCH64_LD_GOT_LO12_NC - ENUMDOC - AArch64 pseudo relocation code to be used internally by the AArch64 -diff -rup binutils-2.30/gas/config/tc-aarch64.c binutils-2.30.new/gas/config/tc-aarch64.c ---- binutils-2.30/gas/config/tc-aarch64.c 2021-03-23 16:21:44.128021971 +0000 -+++ binutils-2.30.new/gas/config/tc-aarch64.c 2021-03-23 16:19:55.031763633 +0000 -@@ -1,6 +1,6 @@ - /* tc-aarch64.c -- Assemble for the AArch64 ISA - -- Copyright (C) 2009-2018 Free Software Foundation, Inc. -+ Copyright (C) 2009-2021 Free Software Foundation, Inc. - Contributed by ARM Ltd. - - This file is part of GAS. -@@ -35,6 +35,9 @@ - - #include "dwarf2dbg.h" - -+/* Number of littlenums required to hold an extended precision number. */ -+#define MAX_LITTLENUMS 6 -+ - /* Types of processor to assemble for. */ - #ifndef CPU_DEFAULT - #define CPU_DEFAULT AARCH64_ARCH_V8 -@@ -55,6 +58,9 @@ static const aarch64_feature_set *march_ - /* Constants for known architecture features. */ - static const aarch64_feature_set cpu_default = CPU_DEFAULT; - -+/* Currently active instruction sequence. */ -+static aarch64_instr_sequence *insn_sequence = NULL; -+ - #ifdef OBJ_ELF - /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */ - static symbolS *GOT_symbol; -@@ -146,6 +152,13 @@ static aarch64_instruction inst; - static bfd_boolean parse_operands (char *, const aarch64_opcode *); - static bfd_boolean programmer_friendly_fixup (aarch64_instruction *); - -+#ifdef OBJ_ELF -+# define now_instr_sequence seg_info \ -+ (now_seg)->tc_segment_info_data.insn_sequence -+#else -+static struct aarch64_instr_sequence now_instr_sequence; -+#endif -+ - /* Diagnostics inline function utilities. - - These are lightweight utilities which should only be called by parse_operands -@@ -228,9 +241,6 @@ set_fatal_syntax_error (const char *erro - set_error (AARCH64_OPDE_FATAL_SYNTAX_ERROR, error); - } - --/* Number of littlenums required to hold an extended precision number. */ --#define MAX_LITTLENUMS 6 -- - /* Return value for certain parsers when the parsing fails; those parsers - return the information of the parsed result, e.g. register number, on - success. */ -@@ -243,12 +253,6 @@ set_fatal_syntax_error (const char *erro - typedef struct - { - const char *template; -- unsigned long value; --} asm_barrier_opt; -- --typedef struct --{ -- const char *template; - uint32_t value; - } asm_nzcv; - -@@ -439,24 +443,28 @@ get_reg_expected_msg (aarch64_reg_type r - - /* Some well known registers that we refer to directly elsewhere. */ - #define REG_SP 31 -+#define REG_ZR 31 - - /* Instructions take 4 bytes in the object file. */ - #define INSN_SIZE 4 - --static struct hash_control *aarch64_ops_hsh; --static struct hash_control *aarch64_cond_hsh; --static struct hash_control *aarch64_shift_hsh; --static struct hash_control *aarch64_sys_regs_hsh; --static struct hash_control *aarch64_pstatefield_hsh; --static struct hash_control *aarch64_sys_regs_ic_hsh; --static struct hash_control *aarch64_sys_regs_dc_hsh; --static struct hash_control *aarch64_sys_regs_at_hsh; --static struct hash_control *aarch64_sys_regs_tlbi_hsh; --static struct hash_control *aarch64_reg_hsh; --static struct hash_control *aarch64_barrier_opt_hsh; --static struct hash_control *aarch64_nzcv_hsh; --static struct hash_control *aarch64_pldop_hsh; --static struct hash_control *aarch64_hint_opt_hsh; -+#define htab_t struct hash_control * -+ -+static htab_t aarch64_ops_hsh; -+static htab_t aarch64_cond_hsh; -+static htab_t aarch64_shift_hsh; -+static htab_t aarch64_sys_regs_hsh; -+static htab_t aarch64_pstatefield_hsh; -+static htab_t aarch64_sys_regs_ic_hsh; -+static htab_t aarch64_sys_regs_dc_hsh; -+static htab_t aarch64_sys_regs_at_hsh; -+static htab_t aarch64_sys_regs_tlbi_hsh; -+static htab_t aarch64_sys_regs_sr_hsh; -+static htab_t aarch64_reg_hsh; -+static htab_t aarch64_barrier_opt_hsh; -+static htab_t aarch64_nzcv_hsh; -+static htab_t aarch64_pldop_hsh; -+static htab_t aarch64_hint_opt_hsh; - - /* Stuff needed to resolve the label ambiguity - As: -@@ -520,7 +528,7 @@ const char EXP_CHARS[] = "eE"; - /* As in 0f12.456 */ - /* or 0d1.2345e12 */ - --const char FLT_CHARS[] = "rRsSfFdDxXeEpP"; -+const char FLT_CHARS[] = "rRsSfFdDxXeEpPhH"; - - /* Prefix character that indicates the start of an immediate value. */ - #define is_immediate_prefix(C) ((C) == '#') -@@ -618,6 +626,96 @@ my_get_expression (expressionS * ep, cha - return TRUE; - } - -+#define MAX_PRECISION 5 -+#define H_PRECISION 1 -+#define F_PRECISION 2 -+#define D_PRECISION 4 -+#define X_PRECISION 5 -+#define P_PRECISION 5 -+/* Length in LittleNums of guard bits. */ -+#define GUARD 2 -+ -+static void -+make_invalid_floating_point_number (LITTLENUM_TYPE *words) -+{ -+ as_bad (_("cannot create floating-point number")); -+ /* Zero the leftmost bit. */ -+ words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; -+ words[1] = (LITTLENUM_TYPE) -1; -+ words[2] = (LITTLENUM_TYPE) -1; -+ words[3] = (LITTLENUM_TYPE) -1; -+ words[4] = (LITTLENUM_TYPE) -1; -+ words[5] = (LITTLENUM_TYPE) -1; -+} -+ -+char * atof_ieee_detail (char *, int, int, LITTLENUM_TYPE *, FLONUM_TYPE *); -+ -+/* Build a floating point constant at str into a IEEE floating -+ point number. This function does the same thing as atof_ieee -+ however it allows more control over the exact format, i.e. -+ explicitly specifying the precision and number of exponent bits -+ instead of relying on this infomation being deduced from a given type. -+ -+ If generic_float_info is not NULL then it will be set to contain generic -+ infomation about the parsed floating point number. -+ -+ Returns pointer past text consumed. */ -+char * -+atof_ieee_detail (char * str, -+ int precision, -+ int exponent_bits, -+ LITTLENUM_TYPE * words, -+ FLONUM_TYPE * generic_float_info) -+{ -+ /* Extra bits for zeroed low-order bits. -+ The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ -+ static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; -+ char *return_value; -+ -+ /* Number of 16-bit words in the format. */ -+ FLONUM_TYPE save_gen_flonum; -+ -+ /* We have to save the generic_floating_point_number because it -+ contains storage allocation about the array of LITTLENUMs where -+ the value is actually stored. We will allocate our own array of -+ littlenums below, but have to restore the global one on exit. */ -+ save_gen_flonum = generic_floating_point_number; -+ -+ return_value = str; -+ generic_floating_point_number.low = bits + MAX_PRECISION; -+ generic_floating_point_number.high = NULL; -+ generic_floating_point_number.leader = NULL; -+ generic_floating_point_number.exponent = 0; -+ generic_floating_point_number.sign = '\0'; -+ -+ /* Use more LittleNums than seems necessary: the highest flonum may -+ have 15 leading 0 bits, so could be useless. */ -+ -+ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); -+ -+ generic_floating_point_number.high -+ = generic_floating_point_number.low + precision - 1 + GUARD; -+ -+ if (atof_generic (&return_value, ".", EXP_CHARS, -+ &generic_floating_point_number)) -+ { -+ make_invalid_floating_point_number (words); -+ return NULL; -+ } -+ -+ if (generic_float_info) -+ *generic_float_info = generic_floating_point_number; -+ -+ gen_to_words (words, precision, exponent_bits); -+ -+ /* Restore the generic_floating_point_number's storage alloc (and -+ everything else). */ -+ generic_floating_point_number = save_gen_flonum; -+ -+ return return_value; -+} -+ -+ - /* Turn a string in input_line_pointer into a floating point constant - of type TYPE, and store the appropriate bytes in *LITP. The number - of LITTLENUMS emitted is stored in *SIZEP. An error message is -@@ -626,6 +724,54 @@ my_get_expression (expressionS * ep, cha - const char * - md_atof (int type, char *litP, int *sizeP) - { -+ /* If this is a bfloat16 type, then parse it slightly differently - -+ as it does not follow the IEEE standard exactly. */ -+ if (type == 'b') -+ { -+ char * t; -+ LITTLENUM_TYPE words[MAX_LITTLENUMS]; -+ FLONUM_TYPE generic_float; -+ -+ t = atof_ieee_detail (input_line_pointer, 1, 8, words, &generic_float); -+ -+ if (t) -+ input_line_pointer = t; -+ else -+ return _("invalid floating point number"); -+ -+ switch (generic_float.sign) -+ { -+ /* Is +Inf. */ -+ case 'P': -+ words[0] = 0x7f80; -+ break; -+ -+ /* Is -Inf. */ -+ case 'N': -+ words[0] = 0xff80; -+ break; -+ -+ /* Is NaN. */ -+ /* bfloat16 has two types of NaN - quiet and signalling. -+ Quiet NaN has bit[6] == 1 && faction != 0, whereas -+ signalling Nan's have bit[0] == 0 && fraction != 0. -+ Chose this specific encoding as it is the same form -+ as used by other IEEE 754 encodings in GAS. */ -+ case 0: -+ words[0] = 0x7fff; -+ break; -+ -+ default: -+ break; -+ } -+ -+ *sizeP = 2; -+ -+ md_number_to_chars (litP, (valueT) words[0], sizeof (LITTLENUM_TYPE)); -+ -+ return NULL; -+ } -+ - return ieee_md_atof (type, litP, sizeP, target_big_endian); - } - -@@ -826,7 +972,7 @@ parse_vector_type_for_operand (aarch64_r - return FALSE; - } - --elt_size: -+ elt_size: - switch (TOLOWER (*ptr)) - { - case 'b': -@@ -1945,7 +2091,7 @@ s_variant_pcs (int ignored ATTRIBUTE_UNU - restore_line_pointer (c); - demand_empty_rest_of_line (); - bfdsym = symbol_get_bfdsym (sym); -- elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym); -+ elfsym = elf_symbol_from (NULL, bfdsym); - gas_assert (elfsym); - elfsym->internal_elf_sym.st_other |= STO_AARCH64_VARIANT_PCS; - } -@@ -2088,6 +2234,8 @@ const pseudo_typeS md_pseudo_table[] = { - {"dword", s_aarch64_elf_cons, 8}, - {"variant_pcs", s_variant_pcs, 0}, - #endif -+ {"float16", float_cons, 'h'}, -+ {"bfloat16", float_cons, 'b'}, - {0, 0, 0} - }; - -@@ -2122,7 +2270,7 @@ reg_name_p (char *str, aarch64_reg_type - return FALSE; - - skip_whitespace (str); -- if (*str == ',' || is_end_of_line[(unsigned int) *str]) -+ if (*str == ',' || is_end_of_line[(unsigned char) *str]) - return TRUE; - - return FALSE; -@@ -2302,7 +2450,6 @@ parse_aarch64_imm_float (char **ccp, int - char *str = *ccp; - char *fpnum; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; -- int found_fpchar = 0; - int64_t val = 0; - unsigned fpword = 0; - bfd_boolean hex_p = FALSE; -@@ -2332,26 +2479,10 @@ parse_aarch64_imm_float (char **ccp, int - - hex_p = TRUE; - } -- else -- { -- if (reg_name_p (str, reg_type)) -- { -- set_recoverable_error (_("immediate operand required")); -- return FALSE; -- } -- -- /* We must not accidentally parse an integer as a floating-point number. -- Make sure that the value we parse is not an integer by checking for -- special characters '.' or 'e'. */ -- for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++) -- if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E') -- { -- found_fpchar = 1; -- break; -- } -- -- if (!found_fpchar) -- return FALSE; -+ else if (reg_name_p (str, reg_type)) -+ { -+ set_recoverable_error (_("immediate operand required")); -+ return FALSE; - } - - if (! hex_p) -@@ -2373,7 +2504,7 @@ parse_aarch64_imm_float (char **ccp, int - *ccp = str; - return TRUE; - --invalid_fp: -+ invalid_fp: - set_fatal_syntax_error (_("invalid floating-point constant")); - return FALSE; - } -@@ -2600,6 +2731,69 @@ static struct reloc_table_entry reloc_ta - 0, - 0}, - -+ /* Most significant bits 0-15 of signed/unsigned address/value: MOVZ */ -+ {"prel_g0", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G0, -+ 0, -+ 0, -+ 0}, -+ -+ /* Most significant bits 0-15 of signed/unsigned address/value: MOVK */ -+ {"prel_g0_nc", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G0_NC, -+ 0, -+ 0, -+ 0}, -+ -+ /* Most significant bits 16-31 of signed/unsigned address/value: MOVZ */ -+ {"prel_g1", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G1, -+ 0, -+ 0, -+ 0}, -+ -+ /* Most significant bits 16-31 of signed/unsigned address/value: MOVK */ -+ {"prel_g1_nc", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G1_NC, -+ 0, -+ 0, -+ 0}, -+ -+ /* Most significant bits 32-47 of signed/unsigned address/value: MOVZ */ -+ {"prel_g2", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G2, -+ 0, -+ 0, -+ 0}, -+ -+ /* Most significant bits 32-47 of signed/unsigned address/value: MOVK */ -+ {"prel_g2_nc", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G2_NC, -+ 0, -+ 0, -+ 0}, -+ -+ /* Most significant bits 48-63 of signed/unsigned address/value: MOVZ */ -+ {"prel_g3", 1, -+ 0, /* adr_type */ -+ 0, -+ BFD_RELOC_AARCH64_MOVW_PREL_G3, -+ 0, -+ 0, -+ 0}, -+ - /* Get to the page containing GOT entry for a symbol. */ - {"got", 1, - 0, /* adr_type */ -@@ -2862,7 +3056,7 @@ static struct reloc_table_entry reloc_ta - 0, - 0, - BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12, -- 0, -+ BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12, - 0}, - - /* Get tp offset for a symbol. */ -@@ -2880,7 +3074,7 @@ static struct reloc_table_entry reloc_ta - 0, - 0, - BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC, -- 0, -+ BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC, - 0}, - - /* Most significant bits 32-47 of address/value: MOVZ. */ -@@ -3337,6 +3531,7 @@ parse_shifter_operand_reloc (char **str, - [base,Xm,SXTX {#imm}] - [base,Wm,(S|U)XTW {#imm}] - Pre-indexed -+ [base]! // in ldraa/ldrab exclusive - [base,#imm]! - Post-indexed - [base],#imm -@@ -3350,6 +3545,7 @@ parse_shifter_operand_reloc (char **str, - [base,Zm.D,(S|U)XTW {#imm}] // ignores top 32 bits of Zm.D elements - [Zn.S,#imm] - [Zn.D,#imm] -+ [Zn.S{, Xm}] - [Zn.S,Zm.S{,LSL #imm}] // in ADR - [Zn.D,Zm.D{,LSL #imm}] // in ADR - [Zn.D,Zm.D,(S|U)XTW {#imm}] // in ADR -@@ -3515,6 +3711,7 @@ parse_address_main (char **str, aarch64_ - return FALSE; - } - /* We only accept: -+ [base,Xm] # For vector plus scalar SVE2 indexing. - [base,Xm{,LSL #imm}] - [base,Xm,SXTX {#imm}] - [base,Wm,(S|U)XTW {#imm}] */ -@@ -3528,7 +3725,10 @@ parse_address_main (char **str, aarch64_ - return FALSE; - } - if (aarch64_get_qualifier_esize (*base_qualifier) -- != aarch64_get_qualifier_esize (*offset_qualifier)) -+ != aarch64_get_qualifier_esize (*offset_qualifier) -+ && (operand->type != AARCH64_OPND_SVE_ADDR_ZX -+ || *base_qualifier != AARCH64_OPND_QLF_S_S -+ || *offset_qualifier != AARCH64_OPND_QLF_X)) - { - set_syntax_error (_("offset has different size from base")); - return FALSE; -@@ -3646,18 +3846,43 @@ parse_address_main (char **str, aarch64_ - } - - /* If at this point neither .preind nor .postind is set, we have a -- bare [Rn]{!}; reject [Rn]! but accept [Rn] as a shorthand for [Rn,#0]. */ -+ bare [Rn]{!}; only accept [Rn]! as a shorthand for [Rn,#0]! for ldraa and -+ ldrab, accept [Rn] as a shorthand for [Rn,#0]. -+ For SVE2 vector plus scalar offsets, allow [Zn.] as shorthand for -+ [Zn., xzr]. */ - if (operand->addr.preind == 0 && operand->addr.postind == 0) - { - if (operand->addr.writeback) - { -- /* Reject [Rn]! */ -- set_syntax_error (_("missing offset in the pre-indexed address")); -- return FALSE; -+ if (operand->type == AARCH64_OPND_ADDR_SIMM10) -+ { -+ /* Accept [Rn]! as a shorthand for [Rn,#0]! */ -+ operand->addr.offset.is_reg = 0; -+ operand->addr.offset.imm = 0; -+ operand->addr.preind = 1; -+ } -+ else -+ { -+ /* Reject [Rn]! */ -+ set_syntax_error (_("missing offset in the pre-indexed address")); -+ return FALSE; -+ } -+ } -+ else -+ { -+ operand->addr.preind = 1; -+ if (operand->type == AARCH64_OPND_SVE_ADDR_ZX) -+ { -+ operand->addr.offset.is_reg = 1; -+ operand->addr.offset.regno = REG_ZR; -+ *offset_qualifier = AARCH64_OPND_QLF_X; -+ } -+ else -+ { -+ inst.reloc.exp.X_op = O_constant; -+ inst.reloc.exp.X_add_number = 0; -+ } - } -- operand->addr.preind = 1; -- inst.reloc.exp.X_op = O_constant; -- inst.reloc.exp.X_add_number = 0; - } - - *str = p; -@@ -3849,7 +4074,7 @@ static int - parse_barrier (char **str) - { - char *p, *q; -- const asm_barrier_opt *o; -+ const struct aarch64_name_value_pair *o; - - p = q = *str; - while (ISALPHA (*q)) -@@ -3881,7 +4106,7 @@ parse_barrier_psb (char **str, - if (!o) - { - set_fatal_syntax_error -- ( _("unknown or missing option to PSB")); -+ ( _("unknown or missing option to PSB/TSB")); - return PARSE_FAIL; - } - -@@ -3889,7 +4114,48 @@ parse_barrier_psb (char **str, - { - /* PSB only accepts option name 'CSYNC'. */ - set_syntax_error -- (_("the specified option is not accepted for PSB")); -+ (_("the specified option is not accepted for PSB/TSB")); -+ return PARSE_FAIL; -+ } -+ -+ *str = q; -+ *hint_opt = o; -+ return 0; -+} -+ -+/* Parse an operand for BTI. Set *HINT_OPT to the hint-option record -+ return 0 if successful. Otherwise return PARSE_FAIL. */ -+ -+static int -+parse_bti_operand (char **str, -+ const struct aarch64_name_value_pair ** hint_opt) -+{ -+ char *p, *q; -+ const struct aarch64_name_value_pair *o; -+ -+ p = q = *str; -+ while (ISALPHA (*q)) -+ q++; -+ -+ o = hash_find_n (aarch64_hint_opt_hsh, p, q - p); -+ if (!o) -+ { -+ set_fatal_syntax_error -+ ( _("unknown option to BTI")); -+ return PARSE_FAIL; -+ } -+ -+ switch (o->value) -+ { -+ /* Valid BTI operands. */ -+ case HINT_OPD_C: -+ case HINT_OPD_J: -+ case HINT_OPD_JC: -+ break; -+ -+ default: -+ set_syntax_error -+ (_("unknown option to BTI")); - return PARSE_FAIL; - } - -@@ -3909,21 +4175,26 @@ parse_barrier_psb (char **str, - */ - - static int --parse_sys_reg (char **str, struct hash_control *sys_regs, -- int imple_defined_p, int pstatefield_p) -+parse_sys_reg (char **str, htab_t sys_regs, -+ int imple_defined_p, int pstatefield_p, -+ uint32_t* flags) - { - char *p, *q; -- char buf[32]; -+ char buf[AARCH64_MAX_SYSREG_NAME_LEN]; - const aarch64_sys_reg *o; - int value; - - p = buf; - for (q = *str; ISALNUM (*q) || *q == '_'; q++) -- if (p < buf + 31) -+ if (p < buf + (sizeof (buf) - 1)) - *p++ = TOLOWER (*q); - *p = '\0'; -- /* Assert that BUF be large enough. */ -- gas_assert (p - buf == q - *str); -+ -+ /* If the name is longer than AARCH64_MAX_SYSREG_NAME_LEN then it cannot be a -+ valid system register. This is enforced by construction of the hash -+ table. */ -+ if (p - buf != q - *str) -+ return PARSE_FAIL; - - o = hash_find (sys_regs, buf); - if (!o) -@@ -3941,6 +4212,8 @@ parse_sys_reg (char **str, struct hash_c - if (op0 > 3 || op1 > 7 || cn > 15 || cm > 15 || op2 > 7) - return PARSE_FAIL; - value = (op0 << 14) | (op1 << 11) | (cn << 7) | (cm << 3) | op2; -+ if (flags) -+ *flags = 0; - } - } - else -@@ -3948,13 +4221,17 @@ parse_sys_reg (char **str, struct hash_c - if (pstatefield_p && !aarch64_pstatefield_supported_p (cpu_variant, o)) - as_bad (_("selected processor does not support PSTATE field " - "name '%s'"), buf); -- if (!pstatefield_p && !aarch64_sys_reg_supported_p (cpu_variant, o)) -+ if (!pstatefield_p -+ && !aarch64_sys_ins_reg_supported_p (cpu_variant, o->name, -+ o->value, o->flags, o->features)) - as_bad (_("selected processor does not support system register " - "name '%s'"), buf); -- if (aarch64_sys_reg_deprecated_p (o)) -+ if (aarch64_sys_reg_deprecated_p (o->flags)) - as_warn (_("system register name '%s' is deprecated and may be " - "removed in a future release"), buf); - value = o->value; -+ if (flags) -+ *flags = o->flags; - } - - *str = q; -@@ -3965,25 +4242,35 @@ parse_sys_reg (char **str, struct hash_c - for the option, or NULL. */ - - static const aarch64_sys_ins_reg * --parse_sys_ins_reg (char **str, struct hash_control *sys_ins_regs) -+parse_sys_ins_reg (char **str, htab_t sys_ins_regs) - { - char *p, *q; -- char buf[32]; -+ char buf[AARCH64_MAX_SYSREG_NAME_LEN]; - const aarch64_sys_ins_reg *o; - - p = buf; - for (q = *str; ISALNUM (*q) || *q == '_'; q++) -- if (p < buf + 31) -+ if (p < buf + (sizeof (buf) - 1)) - *p++ = TOLOWER (*q); - *p = '\0'; - -+ /* If the name is longer than AARCH64_MAX_SYSREG_NAME_LEN then it cannot be a -+ valid system register. This is enforced by construction of the hash -+ table. */ -+ if (p - buf != q - *str) -+ return NULL; -+ - o = hash_find (sys_ins_regs, buf); - if (!o) - return NULL; - -- if (!aarch64_sys_ins_reg_supported_p (cpu_variant, o)) -+ if (!aarch64_sys_ins_reg_supported_p (cpu_variant, -+ o->name, o->value, o->flags, 0)) - as_bad (_("selected processor does not support system register " - "name '%s'"), buf); -+ if (aarch64_sys_reg_deprecated_p (o->flags)) -+ as_warn (_("system register name '%s' is deprecated and may be " -+ "removed in a future release"), buf); - - *str = q; - return o; -@@ -4137,7 +4424,10 @@ reencode_movzn_to_movn (uint32_t opcode) - static fixS * - fix_new_aarch64 (fragS * frag, - int where, -- short int size, expressionS * exp, int pc_rel, int reloc) -+ short int size, -+ expressionS * exp, -+ int pc_rel, -+ int reloc) - { - fixS *new_fix; - -@@ -4371,6 +4661,7 @@ record_operand_error (const aarch64_opco - info.index = idx; - info.kind = kind; - info.error = error; -+ info.non_fatal = FALSE; - record_operand_error_info (opcode, &info); - } - -@@ -4386,6 +4677,7 @@ record_operand_error_with_data (const aa - info.data[0] = extra_data[0]; - info.data[1] = extra_data[1]; - info.data[2] = extra_data[2]; -+ info.non_fatal = FALSE; - record_operand_error_info (opcode, &info); - } - -@@ -4504,7 +4796,8 @@ print_operands (char *buf, const aarch64 - break; - - /* Generate the operand string in STR. */ -- aarch64_print_operand (str, sizeof (str), 0, opcode, opnds, i, NULL, NULL); -+ aarch64_print_operand (str, sizeof (str), 0, opcode, opnds, i, NULL, NULL, -+ NULL, cpu_variant); - - /* Delimiter. */ - if (str[0] != '\0') -@@ -4550,12 +4843,14 @@ output_operand_error_record (const opera - enum aarch64_opnd opd_code = (idx >= 0 ? opcode->operands[idx] - : AARCH64_OPND_NIL); - -+ typedef void (*handler_t)(const char *format, ...); -+ handler_t handler = detail->non_fatal ? as_warn : as_bad; -+ - switch (detail->kind) - { - case AARCH64_OPDE_NIL: - gas_assert (0); - break; -- - case AARCH64_OPDE_SYNTAX_ERROR: - case AARCH64_OPDE_RECOVERABLE: - case AARCH64_OPDE_FATAL_SYNTAX_ERROR: -@@ -4565,21 +4860,21 @@ output_operand_error_record (const opera - if (detail->error != NULL) - { - if (idx < 0) -- as_bad (_("%s -- `%s'"), detail->error, str); -+ handler (_("%s -- `%s'"), detail->error, str); - else -- as_bad (_("%s at operand %d -- `%s'"), -- detail->error, idx + 1, str); -+ handler (_("%s at operand %d -- `%s'"), -+ detail->error, idx + 1, str); - } - else - { - gas_assert (idx >= 0); -- as_bad (_("operand %d must be %s -- `%s'"), idx + 1, -- aarch64_get_operand_desc (opd_code), str); -+ handler (_("operand %d must be %s -- `%s'"), idx + 1, -+ aarch64_get_operand_desc (opd_code), str); - } - break; - - case AARCH64_OPDE_INVALID_VARIANT: -- as_bad (_("operand mismatch -- `%s'"), str); -+ handler (_("operand mismatch -- `%s'"), str); - if (verbose_error_p) - { - /* We will try to correct the erroneous instruction and also provide -@@ -4627,7 +4922,7 @@ output_operand_error_record (const opera - && programmer_friendly_fixup (&inst); - gas_assert (result); - result = aarch64_opcode_encode (opcode, inst_base, &inst_base->value, -- NULL, NULL); -+ NULL, NULL, insn_sequence); - gas_assert (!result); - - /* Find the most matched qualifier sequence. */ -@@ -4676,36 +4971,36 @@ output_operand_error_record (const opera - break; - - case AARCH64_OPDE_UNTIED_OPERAND: -- as_bad (_("operand %d must be the same register as operand 1 -- `%s'"), -- detail->index + 1, str); -+ handler (_("operand %d must be the same register as operand 1 -- `%s'"), -+ detail->index + 1, str); - break; - - case AARCH64_OPDE_OUT_OF_RANGE: - if (detail->data[0] != detail->data[1]) -- as_bad (_("%s out of range %d to %d at operand %d -- `%s'"), -- detail->error ? detail->error : _("immediate value"), -- detail->data[0], detail->data[1], idx + 1, str); -+ handler (_("%s out of range %d to %d at operand %d -- `%s'"), -+ detail->error ? detail->error : _("immediate value"), -+ detail->data[0], detail->data[1], idx + 1, str); - else -- as_bad (_("%s must be %d at operand %d -- `%s'"), -- detail->error ? detail->error : _("immediate value"), -- detail->data[0], idx + 1, str); -+ handler (_("%s must be %d at operand %d -- `%s'"), -+ detail->error ? detail->error : _("immediate value"), -+ detail->data[0], idx + 1, str); - break; - - case AARCH64_OPDE_REG_LIST: - if (detail->data[0] == 1) -- as_bad (_("invalid number of registers in the list; " -- "only 1 register is expected at operand %d -- `%s'"), -- idx + 1, str); -+ handler (_("invalid number of registers in the list; " -+ "only 1 register is expected at operand %d -- `%s'"), -+ idx + 1, str); - else -- as_bad (_("invalid number of registers in the list; " -- "%d registers are expected at operand %d -- `%s'"), -- detail->data[0], idx + 1, str); -+ handler (_("invalid number of registers in the list; " -+ "%d registers are expected at operand %d -- `%s'"), -+ detail->data[0], idx + 1, str); - break; - - case AARCH64_OPDE_UNALIGNED: -- as_bad (_("immediate value must be a multiple of " -- "%d at operand %d -- `%s'"), -- detail->data[0], idx + 1, str); -+ handler (_("immediate value must be a multiple of " -+ "%d at operand %d -- `%s'"), -+ detail->data[0], idx + 1, str); - break; - - default: -@@ -4719,10 +5014,15 @@ output_operand_error_record (const opera - When this function is called, the operand error information had - been collected for an assembly line and there will be multiple - errors in the case of multiple instruction templates; output the -- error message that most closely describes the problem. */ -+ error message that most closely describes the problem. -+ -+ The errors to be printed can be filtered on printing all errors -+ or only non-fatal errors. This distinction has to be made because -+ the error buffer may already be filled with fatal errors we don't want to -+ print due to the different instruction templates. */ - - static void --output_operand_error_report (char *str) -+output_operand_error_report (char *str, bfd_boolean non_fatal_only) - { - int largest_error_pos; - const char *msg = NULL; -@@ -4740,9 +5040,14 @@ output_operand_error_report (char *str) - /* Only one error. */ - if (head == operand_error_report.tail) - { -- DEBUG_TRACE ("single opcode entry with error kind: %s", -- operand_mismatch_kind_names[head->detail.kind]); -- output_operand_error_record (head, str); -+ /* If the only error is a non-fatal one and we don't want to print it, -+ just exit. */ -+ if (!non_fatal_only || head->detail.non_fatal) -+ { -+ DEBUG_TRACE ("single opcode entry with error kind: %s", -+ operand_mismatch_kind_names[head->detail.kind]); -+ output_operand_error_record (head, str); -+ } - return; - } - -@@ -4753,16 +5058,21 @@ output_operand_error_report (char *str) - { - gas_assert (curr->detail.kind != AARCH64_OPDE_NIL); - DEBUG_TRACE ("\t%s", operand_mismatch_kind_names[curr->detail.kind]); -- if (operand_error_higher_severity_p (curr->detail.kind, kind)) -+ if (operand_error_higher_severity_p (curr->detail.kind, kind) -+ && (!non_fatal_only || (non_fatal_only && curr->detail.non_fatal))) - kind = curr->detail.kind; - } -- gas_assert (kind != AARCH64_OPDE_NIL); -+ -+ gas_assert (kind != AARCH64_OPDE_NIL || non_fatal_only); - - /* Pick up one of errors of KIND to report. */ - largest_error_pos = -2; /* Index can be -1 which means unknown index. */ - for (curr = head; curr != NULL; curr = curr->next) - { -- if (curr->detail.kind != kind) -+ /* If we don't want to print non-fatal errors then don't consider them -+ at all. */ -+ if (curr->detail.kind != kind -+ || (non_fatal_only && !curr->detail.non_fatal)) - continue; - /* If there are multiple errors, pick up the one with the highest - mismatching operand index. In the case of multiple errors with -@@ -4778,6 +5088,17 @@ output_operand_error_report (char *str) - } - } - -+ /* The way errors are collected in the back-end is a bit non-intuitive. But -+ essentially, because each operand template is tried recursively you may -+ always have errors collected from the previous tried OPND. These are -+ usually skipped if there is one successful match. However now with the -+ non-fatal errors we have to ignore those previously collected hard errors -+ when we're only interested in printing the non-fatal ones. This condition -+ prevents us from printing errors that are not appropriate, since we did -+ match a condition, but it also has warnings that it wants to print. */ -+ if (non_fatal_only && !record) -+ return; -+ - gas_assert (largest_error_pos != -2 && record != NULL); - DEBUG_TRACE ("Pick up error kind %s to report", - operand_mismatch_kind_names[record->detail.kind]); -@@ -4802,7 +5123,8 @@ get_aarch64_insn (char *buf) - { - unsigned char *where = (unsigned char *) buf; - uint32_t result; -- result = (where[0] | (where[1] << 8) | (where[2] << 16) | (where[3] << 24)); -+ result = ((where[0] | (where[1] << 8) | (where[2] << 16) -+ | ((uint32_t) where[3] << 24))); - return result; - } - -@@ -4957,6 +5279,10 @@ vectype_to_qualifier (const struct vecto - if (vectype->type == NT_b && vectype->width == 4) - return AARCH64_OPND_QLF_S_4B; - -+ /* Special case S_2H. */ -+ if (vectype->type == NT_h && vectype->width == 2) -+ return AARCH64_OPND_QLF_S_2H; -+ - /* Vector element register. */ - return AARCH64_OPND_QLF_S_B + vectype->type; - } -@@ -4989,7 +5315,7 @@ vectype_to_qualifier (const struct vecto - return offset; - } - --vectype_conversion_fail: -+ vectype_conversion_fail: - first_error (_("bad vector arrangement type")); - return AARCH64_OPND_QLF_NIL; - } -@@ -5014,6 +5340,8 @@ process_omitted_operand (enum aarch64_op - case AARCH64_OPND_Rm: - case AARCH64_OPND_Rt: - case AARCH64_OPND_Rt2: -+ case AARCH64_OPND_Rt_LS64: -+ case AARCH64_OPND_Rt_SP: - case AARCH64_OPND_Rs: - case AARCH64_OPND_Ra: - case AARCH64_OPND_Rt_SYS: -@@ -5041,6 +5369,7 @@ process_omitted_operand (enum aarch64_op - case AARCH64_OPND_Ed: - case AARCH64_OPND_En: - case AARCH64_OPND_Em: -+ case AARCH64_OPND_Em16: - case AARCH64_OPND_SM3_IMM2: - operand->reglane.regno = default_value; - break; -@@ -5079,6 +5408,11 @@ process_omitted_operand (enum aarch64_op - - case AARCH64_OPND_BARRIER_ISB: - operand->barrier = aarch64_barrier_options + default_value; -+ break; -+ -+ case AARCH64_OPND_BTI_TARGET: -+ operand->hint_option = aarch64_hint_options + default_value; -+ break; - - default: - break; -@@ -5102,6 +5436,10 @@ process_movw_reloc_info (void) - case BFD_RELOC_AARCH64_MOVW_G0_S: - case BFD_RELOC_AARCH64_MOVW_G1_S: - case BFD_RELOC_AARCH64_MOVW_G2_S: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G0: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G1: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G2: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G3: - case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: - case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: - case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: -@@ -5119,6 +5457,8 @@ process_movw_reloc_info (void) - case BFD_RELOC_AARCH64_MOVW_G0_NC: - case BFD_RELOC_AARCH64_MOVW_G0_S: - case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G0: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC: - case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: - case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: - case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: -@@ -5132,6 +5472,8 @@ process_movw_reloc_info (void) - case BFD_RELOC_AARCH64_MOVW_G1_NC: - case BFD_RELOC_AARCH64_MOVW_G1_S: - case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G1: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC: - case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: - case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: - case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: -@@ -5144,6 +5486,8 @@ process_movw_reloc_info (void) - case BFD_RELOC_AARCH64_MOVW_G2: - case BFD_RELOC_AARCH64_MOVW_G2_NC: - case BFD_RELOC_AARCH64_MOVW_G2_S: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G2: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC: - case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: - case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: - if (is32) -@@ -5156,6 +5500,7 @@ process_movw_reloc_info (void) - shift = 32; - break; - case BFD_RELOC_AARCH64_MOVW_G3: -+ case BFD_RELOC_AARCH64_MOVW_PREL_G3: - if (is32) - { - set_fatal_syntax_error -@@ -5202,7 +5547,7 @@ ldst_lo12_determine_real_reloc_type (voi - enum aarch64_opnd_qualifier opd0_qlf = inst.base.operands[0].qualifier; - enum aarch64_opnd_qualifier opd1_qlf = inst.base.operands[1].qualifier; - -- const bfd_reloc_code_real_type reloc_ldst_lo12[3][5] = { -+ const bfd_reloc_code_real_type reloc_ldst_lo12[5][5] = { - { - BFD_RELOC_AARCH64_LDST8_LO12, - BFD_RELOC_AARCH64_LDST16_LO12, -@@ -5223,13 +5568,31 @@ ldst_lo12_determine_real_reloc_type (voi - BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, - BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, - BFD_RELOC_AARCH64_NONE -+ }, -+ { -+ BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, -+ BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, -+ BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, -+ BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, -+ BFD_RELOC_AARCH64_NONE -+ }, -+ { -+ BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, -+ BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, -+ BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, -+ BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, -+ BFD_RELOC_AARCH64_NONE - } - }; - - gas_assert (inst.reloc.type == BFD_RELOC_AARCH64_LDST_LO12 - || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12 - || (inst.reloc.type -- == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)); -+ == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC) -+ || (inst.reloc.type -+ == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12) -+ || (inst.reloc.type -+ == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC)); - gas_assert (inst.base.opcode->operands[1] == AARCH64_OPND_ADDR_UIMM12); - - if (opd1_qlf == AARCH64_OPND_QLF_NIL) -@@ -5240,7 +5603,9 @@ ldst_lo12_determine_real_reloc_type (voi - - logsz = get_logsz (aarch64_get_qualifier_esize (opd1_qlf)); - if (inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12 -- || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC) -+ || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC -+ || inst.reloc.type == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12 -+ || inst.reloc.type == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC) - gas_assert (logsz <= 3); - else - gas_assert (logsz <= 4); -@@ -5345,14 +5710,31 @@ parse_operands (char *str, const aarch64 - case AARCH64_OPND_Rt2: - case AARCH64_OPND_Rs: - case AARCH64_OPND_Ra: -+ case AARCH64_OPND_Rt_LS64: - case AARCH64_OPND_Rt_SYS: - case AARCH64_OPND_PAIRREG: - case AARCH64_OPND_SVE_Rm: - po_int_reg_or_fail (REG_TYPE_R_Z); -+ -+ /* In LS64 load/store instructions Rt register number must be even -+ and <=22. */ -+ if (operands[i] == AARCH64_OPND_Rt_LS64) -+ { -+ /* We've already checked if this is valid register. -+ This will check if register number (Rt) is not undefined for LS64 -+ instructions: -+ if Rt<4:3> == '11' || Rt<0> == '1' then UNDEFINED. */ -+ if ((info->reg.regno & 0x18) == 0x18 || (info->reg.regno & 0x01) == 0x01) -+ { -+ set_syntax_error (_("invalid Rt register number in 64-byte load/store")); -+ goto failure; -+ } -+ } - break; - - case AARCH64_OPND_Rd_SP: - case AARCH64_OPND_Rn_SP: -+ case AARCH64_OPND_Rt_SP: - case AARCH64_OPND_SVE_Rn_SP: - case AARCH64_OPND_Rm_SP: - po_int_reg_or_fail (REG_TYPE_R_SP); -@@ -5477,6 +5859,8 @@ parse_operands (char *str, const aarch64 - - case AARCH64_OPND_SVE_Zm3_INDEX: - case AARCH64_OPND_SVE_Zm3_22_INDEX: -+ case AARCH64_OPND_SVE_Zm3_11_INDEX: -+ case AARCH64_OPND_SVE_Zm4_11_INDEX: - case AARCH64_OPND_SVE_Zm4_INDEX: - case AARCH64_OPND_SVE_Zn_INDEX: - reg_type = REG_TYPE_ZN; -@@ -5485,6 +5869,7 @@ parse_operands (char *str, const aarch64 - case AARCH64_OPND_Ed: - case AARCH64_OPND_En: - case AARCH64_OPND_Em: -+ case AARCH64_OPND_Em16: - case AARCH64_OPND_SM3_IMM2: - reg_type = REG_TYPE_VN; - vector_reg_index: -@@ -5533,11 +5918,20 @@ parse_operands (char *str, const aarch64 - val = parse_vector_reg_list (&str, reg_type, &vectype); - if (val == PARSE_FAIL) - goto failure; -+ - if (! reg_list_valid_p (val, /* accept_alternate */ 0)) - { - set_fatal_syntax_error (_("invalid register list")); - goto failure; - } -+ -+ if (vectype.width != 0 && *str != ',') -+ { -+ set_fatal_syntax_error -+ (_("expected element type rather than vector type")); -+ goto failure; -+ } -+ - info->reglist.first_regno = (val >> 2) & 0x1f; - info->reglist.num_regs = (val & 0x3) + 1; - } -@@ -5591,7 +5985,10 @@ parse_operands (char *str, const aarch64 - case AARCH64_OPND_CCMP_IMM: - case AARCH64_OPND_SIMM5: - case AARCH64_OPND_FBITS: -+ case AARCH64_OPND_TME_UIMM16: - case AARCH64_OPND_UIMM4: -+ case AARCH64_OPND_UIMM4_ADDG: -+ case AARCH64_OPND_UIMM10: - case AARCH64_OPND_UIMM3_OP1: - case AARCH64_OPND_UIMM3_OP2: - case AARCH64_OPND_IMM_VLSL: -@@ -5603,8 +6000,10 @@ parse_operands (char *str, const aarch64 - case AARCH64_OPND_SVE_LIMM_MOV: - case AARCH64_OPND_SVE_SHLIMM_PRED: - case AARCH64_OPND_SVE_SHLIMM_UNPRED: -+ case AARCH64_OPND_SVE_SHLIMM_UNPRED_22: - case AARCH64_OPND_SVE_SHRIMM_PRED: - case AARCH64_OPND_SVE_SHRIMM_UNPRED: -+ case AARCH64_OPND_SVE_SHRIMM_UNPRED_22: - case AARCH64_OPND_SVE_SIMM5: - case AARCH64_OPND_SVE_SIMM5B: - case AARCH64_OPND_SVE_SIMM6: -@@ -5618,6 +6017,7 @@ parse_operands (char *str, const aarch64 - case AARCH64_OPND_IMM_ROT3: - case AARCH64_OPND_SVE_IMM_ROT1: - case AARCH64_OPND_SVE_IMM_ROT2: -+ case AARCH64_OPND_SVE_IMM_ROT3: - po_imm_nc_or_fail (); - info->imm.value = val; - break; -@@ -5865,6 +6265,7 @@ parse_operands (char *str, const aarch64 - break; - - case AARCH64_OPND_EXCEPTION: -+ case AARCH64_OPND_UNDEFINED: - po_misc_or_fail (parse_immediate_expression (&str, &inst.reloc.exp, - imm_reg_type)); - assign_imm_if_const_or_fixup_later (&inst.reloc, info, -@@ -6062,6 +6463,8 @@ parse_operands (char *str, const aarch64 - - case AARCH64_OPND_ADDR_SIMM9: - case AARCH64_OPND_ADDR_SIMM9_2: -+ case AARCH64_OPND_ADDR_SIMM11: -+ case AARCH64_OPND_ADDR_SIMM13: - po_misc_or_fail (parse_address (&str, info)); - if (info->addr.pcrel || info->addr.offset.is_reg - || (!info->addr.preind && !info->addr.postind) -@@ -6116,7 +6519,11 @@ parse_operands (char *str, const aarch64 - || (inst.reloc.type - == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12) - || (inst.reloc.type -- == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)) -+ == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC) -+ || (inst.reloc.type -+ == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12) -+ || (inst.reloc.type -+ == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC)) - inst.reloc.type = ldst_lo12_determine_real_reloc_type (); - /* Leave qualifier to be determined by libopcodes. */ - break; -@@ -6144,6 +6551,7 @@ parse_operands (char *str, const aarch64 - break; - - case AARCH64_OPND_SVE_ADDR_RI_S4x16: -+ case AARCH64_OPND_SVE_ADDR_RI_S4x32: - case AARCH64_OPND_SVE_ADDR_RI_S4xVL: - case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL: - case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL: -@@ -6182,6 +6590,25 @@ parse_operands (char *str, const aarch64 - info->addr.offset.imm = inst.reloc.exp.X_add_number; - break; - -+ case AARCH64_OPND_SVE_ADDR_R: -+ /* [{, }] -+ but recognizing SVE registers. */ -+ po_misc_or_fail (parse_sve_address (&str, info, &base_qualifier, -+ &offset_qualifier)); -+ if (offset_qualifier == AARCH64_OPND_QLF_NIL) -+ { -+ offset_qualifier = AARCH64_OPND_QLF_X; -+ info->addr.offset.is_reg = 1; -+ info->addr.offset.regno = 31; -+ } -+ else if (base_qualifier != AARCH64_OPND_QLF_X -+ || offset_qualifier != AARCH64_OPND_QLF_X) -+ { -+ set_syntax_error (_("invalid addressing mode")); -+ goto failure; -+ } -+ goto regoff_addr; -+ - case AARCH64_OPND_SVE_ADDR_RR: - case AARCH64_OPND_SVE_ADDR_RR_LSL1: - case AARCH64_OPND_SVE_ADDR_RR_LSL2: -@@ -6228,6 +6655,33 @@ parse_operands (char *str, const aarch64 - info->qualifier = offset_qualifier; - goto regoff_addr; - -+ case AARCH64_OPND_SVE_ADDR_ZX: -+ /* [Zn.{, }]. */ -+ po_misc_or_fail (parse_sve_address (&str, info, &base_qualifier, -+ &offset_qualifier)); -+ /* Things to check: -+ base_qualifier either S_S or S_D -+ offset_qualifier must be X -+ */ -+ if ((base_qualifier != AARCH64_OPND_QLF_S_S -+ && base_qualifier != AARCH64_OPND_QLF_S_D) -+ || offset_qualifier != AARCH64_OPND_QLF_X) -+ { -+ set_syntax_error (_("invalid addressing mode")); -+ goto failure; -+ } -+ info->qualifier = base_qualifier; -+ if (!info->addr.offset.is_reg || info->addr.pcrel -+ || !info->addr.preind || info->addr.writeback -+ || info->shifter.operator_present != 0) -+ { -+ set_syntax_error (_("invalid addressing mode")); -+ goto failure; -+ } -+ info->shifter.kind = AARCH64_MOD_LSL; -+ break; -+ -+ - case AARCH64_OPND_SVE_ADDR_ZI_U5: - case AARCH64_OPND_SVE_ADDR_ZI_U5x2: - case AARCH64_OPND_SVE_ADDR_ZI_U5x4: -@@ -6269,17 +6723,21 @@ parse_operands (char *str, const aarch64 - goto regoff_addr; - - case AARCH64_OPND_SYSREG: -- if ((val = parse_sys_reg (&str, aarch64_sys_regs_hsh, 1, 0)) -- == PARSE_FAIL) -- { -- set_syntax_error (_("unknown or missing system register name")); -- goto failure; -- } -- inst.base.operands[i].sysreg = val; -- break; -+ { -+ uint32_t sysreg_flags; -+ if ((val = parse_sys_reg (&str, aarch64_sys_regs_hsh, 1, 0, -+ &sysreg_flags)) == PARSE_FAIL) -+ { -+ set_syntax_error (_("unknown or missing system register name")); -+ goto failure; -+ } -+ inst.base.operands[i].sysreg.value = val; -+ inst.base.operands[i].sysreg.flags = sysreg_flags; -+ break; -+ } - - case AARCH64_OPND_PSTATEFIELD: -- if ((val = parse_sys_reg (&str, aarch64_pstatefield_hsh, 0, 1)) -+ if ((val = parse_sys_reg (&str, aarch64_pstatefield_hsh, 0, 1, NULL)) - == PARSE_FAIL) - { - set_syntax_error (_("unknown or missing PSTATE field name")); -@@ -6292,18 +6750,26 @@ parse_operands (char *str, const aarch64 - inst.base.operands[i].sysins_op = - parse_sys_ins_reg (&str, aarch64_sys_regs_ic_hsh); - goto sys_reg_ins; -+ - case AARCH64_OPND_SYSREG_DC: - inst.base.operands[i].sysins_op = - parse_sys_ins_reg (&str, aarch64_sys_regs_dc_hsh); - goto sys_reg_ins; -+ - case AARCH64_OPND_SYSREG_AT: - inst.base.operands[i].sysins_op = - parse_sys_ins_reg (&str, aarch64_sys_regs_at_hsh); - goto sys_reg_ins; -+ -+ case AARCH64_OPND_SYSREG_SR: -+ inst.base.operands[i].sysins_op = -+ parse_sys_ins_reg (&str, aarch64_sys_regs_sr_hsh); -+ goto sys_reg_ins; -+ - case AARCH64_OPND_SYSREG_TLBI: - inst.base.operands[i].sysins_op = - parse_sys_ins_reg (&str, aarch64_sys_regs_tlbi_hsh); --sys_reg_ins: -+ sys_reg_ins: - if (inst.base.operands[i].sysins_op == NULL) - { - set_fatal_syntax_error ( _("unknown or missing operation name")); -@@ -6324,12 +6790,53 @@ sys_reg_ins: - backtrack_pos = 0; - goto failure; - } -+ if (val != PARSE_FAIL -+ && operands[i] == AARCH64_OPND_BARRIER) -+ { -+ /* Regular barriers accept options CRm (C0-C15). -+ DSB nXS barrier variant accepts values > 15. */ -+ if (val < 0 || val > 15) -+ { -+ set_syntax_error (_("the specified option is not accepted in DSB")); -+ goto failure; -+ } -+ } - /* This is an extension to accept a 0..15 immediate. */ - if (val == PARSE_FAIL) - po_imm_or_fail (0, 15); - info->barrier = aarch64_barrier_options + val; - break; - -+ case AARCH64_OPND_BARRIER_DSB_NXS: -+ val = parse_barrier (&str); -+ if (val != PARSE_FAIL) -+ { -+ /* DSB nXS barrier variant accept only