[ARM,1/16] Add support for Armv8.1-M Mainline CLI

Message ID 44b39e73-3859-bb49-3902-5a9225b58154@arm.com
State New
Headers show
Series
  • Add support for Armv8.1-M Mainline
Related show

Commit Message

Andre Vieira (lists) April 4, 2019, 1:28 p.m.
Hi,

=== Context ===

This patch is part of a patch series to add support for Armv8.1-M
Mainline architecture. Its purpose is to add the command-line support to
assemble and link targeting Armv8.1-M Mainline architecture.

=== Patch description ===

The patch is straightforward, it does the following:

- support the new Tag_CPU_arch build attribute value, ie.:
   + declare the new value
   + update all the asserts forcing logic to be reviewed for new
     architectures
   + create a corresponding bfd_mach_arm_8_1M_MAIN enumerator in bfd and
     add mapping from Tag_CPU_arch to it
   + teach readelf about new Tag_CPU_arch value
- declare armv8.1-m.main as a supported architecture value
- define Armv8.1-M Mainline in terms of feature bits available
- tell objdump mapping from bfd_mach_arm_8_1M_MAIN enumerator to feature
   bits available
- update architecture-specific logic in gas and bfd guarded by the
   asserts mentioned above.
- tests for all the above

ChangeLog entries are as follows:

*** bfd/ChangeLog ***

2019-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* archures.c (bfd_mach_arm_8_1M_MAIN): Define.
	* bfd-in2.h: Regenerate.
	* cpu-arm.c (arch_info_struct): Add entry for Armv8.1-M Mainline.
	* elf32-arm.c (using_thumb_only): Return true for Armv8.1-M Mainline
	and update assert.
	(using_thumb2): Likewise.
	(using_thumb2_bl): Update assert.
	(arch_has_arm_nop): Likewise.
	(bfd_arm_get_mach_from_attributes): Add case for Armv8.1-M Mainline.
	(tag_cpu_arch_combine): Add logic for Armv8.1-M Mainline merging.

*** binutils/ChangeLog ***

2019-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* readelf.c (arm_attr_tag_CPU_arch): Add entry for Armv8.1-M Mainline.

*** gas/ChangeLog ***

2019-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* config/tc-arm.c (cpu_arch_ver): Add entry for Armv8.1-M Mainline
	Tag_CPU_arch build attribute value.  Reindent.
	(get_aeabi_cpu_arch_from_fset): Update assert.
	(aeabi_set_public_attributes): Update assert for Tag_DIV_use logic.
	* testsuite/gas/arm/attr-march-armv8_1-m.main.d: New test.

*** include/ChangeLog ***

2019-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* elf/arm.h (TAG_CPU_ARCH_V8_1M_MAIN): new macro.
	(MAX_TAG_CPU_ARCH): Set value to above macro.
	* opcode/arm.h (ARM_EXT2_V8_1M_MAIN): New macro.
	(ARM_AEXT_V8_1M_MAIN): Likewise.
	(ARM_AEXT2_V8_1M_MAIN): Likewise.
	(ARM_ARCH_V8_1M_MAIN): Likewise.

*** ld/ChangeLog ***

2019-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* testsuite/ld-arm/attr-merge-13.attr: New test.
	* testsuite/ld-arm/attr-merge-13a.s: New test.
	* testsuite/ld-arm/attr-merge-13b.s: New test.

*** opcodes/ChangeLog ***

2019-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* arm-dis.c (select_arm_features): Add logic for Armv8.1-M Mainline.

Patch

diff --git a/bfd/archures.c b/bfd/archures.c
index 647cf0d8d4273651c211cb867bb7f1690e5c4937..aaf2e112cf9413aebd16484b0ab9fda87ea438c2 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -341,6 +341,7 @@  DESCRIPTION
 .#define bfd_mach_arm_8R        24
 .#define bfd_mach_arm_8M_BASE   25
 .#define bfd_mach_arm_8M_MAIN   26
+.#define bfd_mach_arm_8_1M_MAIN 27
 .  bfd_arch_nds32,     {* Andes NDS32.  *}
 .#define bfd_mach_n1		1
 .#define bfd_mach_n1h		2
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 33a29406ae3f4786e1ccb727e29736c2179f122c..4f63fe50e6bf8003fb25beec9e64927a672e444b 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2274,6 +2274,7 @@  enum bfd_architecture
 #define bfd_mach_arm_8R        24
 #define bfd_mach_arm_8M_BASE   25
 #define bfd_mach_arm_8M_MAIN   26
+#define bfd_mach_arm_8_1M_MAIN 27
   bfd_arch_nds32,     /* Andes NDS32.  */
 #define bfd_mach_n1            1
 #define bfd_mach_n1h           2
diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c
index 568fdbfaeec4622e202f7451721bf851bbda640b..5a5da93cb4df61cc9bced426bb58622b5ef627c6 100644
--- a/bfd/cpu-arm.c
+++ b/bfd/cpu-arm.c
@@ -248,6 +248,7 @@  static const bfd_arch_info_type arch_info_struct[] =
   N (bfd_mach_arm_8R,        "armv8-r",        FALSE, & arch_info_struct[24]),
   N (bfd_mach_arm_8M_BASE,   "armv8-m.base",   FALSE, & arch_info_struct[25]),
   N (bfd_mach_arm_8M_MAIN,   "armv8-m.main",   FALSE, & arch_info_struct[26]),
+  N (bfd_mach_arm_8_1M_MAIN, "armv8.1-m.main", FALSE, & arch_info_struct[27]),
   N (bfd_mach_arm_unknown,   "arm_any",        FALSE, NULL)
 };
 
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 28ee9d55a85cf8f998f1720d0f7d00304bae940b..735fe122880c59633b0083b78b9b1e686cfd91c5 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3835,13 +3835,14 @@  using_thumb_only (struct elf32_arm_link_hash_table *globals)
   arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   if (arch == TAG_CPU_ARCH_V6_M
       || arch == TAG_CPU_ARCH_V6S_M
       || arch == TAG_CPU_ARCH_V7E_M
       || arch == TAG_CPU_ARCH_V8M_BASE
-      || arch == TAG_CPU_ARCH_V8M_MAIN)
+      || arch == TAG_CPU_ARCH_V8M_MAIN
+      || arch == TAG_CPU_ARCH_V8_1M_MAIN)
     return TRUE;
 
   return FALSE;
@@ -3862,14 +3863,15 @@  using_thumb2 (struct elf32_arm_link_hash_table *globals)
   arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   return (arch == TAG_CPU_ARCH_V6T2
 	  || arch == TAG_CPU_ARCH_V7
 	  || arch == TAG_CPU_ARCH_V7E_M
 	  || arch == TAG_CPU_ARCH_V8
 	  || arch == TAG_CPU_ARCH_V8R
-	  || arch == TAG_CPU_ARCH_V8M_MAIN);
+	  || arch == TAG_CPU_ARCH_V8M_MAIN
+	  || arch == TAG_CPU_ARCH_V8_1M_MAIN);
 }
 
 /* Determine whether Thumb-2 BL instruction is available.  */
@@ -3881,7 +3883,7 @@  using_thumb2_bl (struct elf32_arm_link_hash_table *globals)
     bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   /* Architecture was introduced after ARMv6T2 (eg. ARMv6-M).  */
   return (arch == TAG_CPU_ARCH_V6T2
@@ -4101,7 +4103,7 @@  arch_has_arm_nop (struct elf32_arm_link_hash_table *globals)
 					     Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   return (arch == TAG_CPU_ARCH_V6T2
 	  || arch == TAG_CPU_ARCH_V6K
@@ -13718,6 +13720,8 @@  bfd_arm_get_mach_from_attributes (bfd * abfd)
 	return bfd_mach_arm_8M_BASE;
     case TAG_CPU_ARCH_V8M_MAIN:
 	return bfd_mach_arm_8M_MAIN;
+    case TAG_CPU_ARCH_V8_1M_MAIN:
+	return bfd_mach_arm_8_1M_MAIN;
 
     default:
       /* Force entry to be added for any new known Tag_CPU_arch value.  */
@@ -14130,6 +14134,31 @@  tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       T(V8M_MAIN),	/* V8-M BASELINE.  */
       T(V8M_MAIN)	/* V8-M MAINLINE.  */
     };
+  const int v8_1m_mainline[] =
+    {
+      -1,		/* PRE_V4.  */
+      -1,		/* V4.  */
+      -1,		/* V4T.  */
+      -1,		/* V5T.  */
+      -1,		/* V5TE.  */
+      -1,		/* V5TEJ.  */
+      -1,		/* V6.  */
+      -1,		/* V6KZ.  */
+      -1,		/* V6T2.  */
+      -1,		/* V6K.  */
+      T(V8_1M_MAIN),	/* V7.  */
+      T(V8_1M_MAIN),	/* V6_M.  */
+      T(V8_1M_MAIN),	/* V6S_M.  */
+      T(V8_1M_MAIN),	/* V7E_M.  */
+      -1,		/* V8.  */
+      -1,		/* V8R.  */
+      T(V8_1M_MAIN),	/* V8-M BASELINE.  */
+      T(V8_1M_MAIN),	/* V8-M MAINLINE.  */
+      -1,		/* Unused (18).  */
+      -1,		/* Unused (19).  */
+      -1,		/* Unused (20).  */
+      T(V8_1M_MAIN)	/* V8.1-M MAINLINE.  */
+    };
   const int v4t_plus_v6_m[] =
     {
       -1,		/* PRE_V4.  */
@@ -14150,6 +14179,10 @@  tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       -1,		/* V8R.  */
       T(V8M_BASE),	/* V8-M BASELINE.  */
       T(V8M_MAIN),	/* V8-M MAINLINE.  */
+      -1,		/* Unused (18).  */
+      -1,		/* Unused (19).  */
+      -1,		/* Unused (20).  */
+      T(V8_1M_MAIN),	/* V8.1-M MAINLINE.  */
       T(V4T_PLUS_V6_M)	/* V4T plus V6_M.  */
     };
   const int *comb[] =
@@ -14164,6 +14197,10 @@  tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       v8r,
       v8m_baseline,
       v8m_mainline,
+      NULL,
+      NULL,
+      NULL,
+      v8_1m_mainline,
       /* Pseudo-architecture.  */
       v4t_plus_v6_m
     };
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 5a9d9ff433d5438e073e871b9c92d307d9f279d3..1fe71824776d979365ae936c6e35af8558da2683 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14370,7 +14370,7 @@  typedef struct
 static const char * arm_attr_tag_CPU_arch[] =
   {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
    "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
-   "v8-M.mainline"};
+   "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
 static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
 static const char * arm_attr_tag_THUMB_ISA_use[] =
   {"No", "Thumb-1", "Thumb-2", "Yes"};
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 4218d059d6d4cbe922c4eb8215afaee5d39c18e3..4f96066cc5f32b9a07d2f8b6a146ea2788f61f07 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -26570,6 +26570,7 @@  static const struct arm_arch_option_table arm_archs[] =
   ARM_ARCH_OPT ("armv8-m.base",	  ARM_ARCH_V8M_BASE,	FPU_ARCH_VFP),
   ARM_ARCH_OPT2 ("armv8-m.main",  ARM_ARCH_V8M_MAIN,	FPU_ARCH_VFP,
 		 armv8m_main),
+  ARM_ARCH_OPT ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN,	FPU_ARCH_VFP),
   ARM_ARCH_OPT2 ("armv8-a",	  ARM_ARCH_V8A,		FPU_ARCH_VFP, armv8a),
   ARM_ARCH_OPT2 ("armv8.1-a",	  ARM_ARCH_V8_1A,	FPU_ARCH_VFP, armv81a),
   ARM_ARCH_OPT2 ("armv8.2-a",	  ARM_ARCH_V8_2A,	FPU_ARCH_VFP, armv82a),
@@ -27284,30 +27285,30 @@  typedef struct
    stable when new architectures are added.  */
 static const cpu_arch_ver_table cpu_arch_ver[] =
 {
-    {TAG_CPU_ARCH_PRE_V4,   ARM_ARCH_V1},
-    {TAG_CPU_ARCH_PRE_V4,   ARM_ARCH_V2},
-    {TAG_CPU_ARCH_PRE_V4,   ARM_ARCH_V2S},
-    {TAG_CPU_ARCH_PRE_V4,   ARM_ARCH_V3},
-    {TAG_CPU_ARCH_PRE_V4,   ARM_ARCH_V3M},
-    {TAG_CPU_ARCH_V4,	    ARM_ARCH_V4xM},
-    {TAG_CPU_ARCH_V4,	    ARM_ARCH_V4},
-    {TAG_CPU_ARCH_V4T,	    ARM_ARCH_V4TxM},
-    {TAG_CPU_ARCH_V4T,	    ARM_ARCH_V4T},
-    {TAG_CPU_ARCH_V5T,	    ARM_ARCH_V5xM},
-    {TAG_CPU_ARCH_V5T,	    ARM_ARCH_V5},
-    {TAG_CPU_ARCH_V5T,	    ARM_ARCH_V5TxM},
-    {TAG_CPU_ARCH_V5T,	    ARM_ARCH_V5T},
-    {TAG_CPU_ARCH_V5TE,	    ARM_ARCH_V5TExP},
-    {TAG_CPU_ARCH_V5TE,	    ARM_ARCH_V5TE},
-    {TAG_CPU_ARCH_V5TEJ,    ARM_ARCH_V5TEJ},
-    {TAG_CPU_ARCH_V6,	    ARM_ARCH_V6},
-    {TAG_CPU_ARCH_V6KZ,	    ARM_ARCH_V6Z},
-    {TAG_CPU_ARCH_V6KZ,	    ARM_ARCH_V6KZ},
-    {TAG_CPU_ARCH_V6K,	    ARM_ARCH_V6K},
-    {TAG_CPU_ARCH_V6T2,	    ARM_ARCH_V6T2},
-    {TAG_CPU_ARCH_V6T2,	    ARM_ARCH_V6KT2},
-    {TAG_CPU_ARCH_V6T2,	    ARM_ARCH_V6ZT2},
-    {TAG_CPU_ARCH_V6T2,	    ARM_ARCH_V6KZT2},
+    {TAG_CPU_ARCH_PRE_V4,     ARM_ARCH_V1},
+    {TAG_CPU_ARCH_PRE_V4,     ARM_ARCH_V2},
+    {TAG_CPU_ARCH_PRE_V4,     ARM_ARCH_V2S},
+    {TAG_CPU_ARCH_PRE_V4,     ARM_ARCH_V3},
+    {TAG_CPU_ARCH_PRE_V4,     ARM_ARCH_V3M},
+    {TAG_CPU_ARCH_V4,	      ARM_ARCH_V4xM},
+    {TAG_CPU_ARCH_V4,	      ARM_ARCH_V4},
+    {TAG_CPU_ARCH_V4T,	      ARM_ARCH_V4TxM},
+    {TAG_CPU_ARCH_V4T,	      ARM_ARCH_V4T},
+    {TAG_CPU_ARCH_V5T,	      ARM_ARCH_V5xM},
+    {TAG_CPU_ARCH_V5T,	      ARM_ARCH_V5},
+    {TAG_CPU_ARCH_V5T,	      ARM_ARCH_V5TxM},
+    {TAG_CPU_ARCH_V5T,	      ARM_ARCH_V5T},
+    {TAG_CPU_ARCH_V5TE,	      ARM_ARCH_V5TExP},
+    {TAG_CPU_ARCH_V5TE,	      ARM_ARCH_V5TE},
+    {TAG_CPU_ARCH_V5TEJ,      ARM_ARCH_V5TEJ},
+    {TAG_CPU_ARCH_V6,	      ARM_ARCH_V6},
+    {TAG_CPU_ARCH_V6KZ,	      ARM_ARCH_V6Z},
+    {TAG_CPU_ARCH_V6KZ,	      ARM_ARCH_V6KZ},
+    {TAG_CPU_ARCH_V6K,	      ARM_ARCH_V6K},
+    {TAG_CPU_ARCH_V6T2,	      ARM_ARCH_V6T2},
+    {TAG_CPU_ARCH_V6T2,	      ARM_ARCH_V6KT2},
+    {TAG_CPU_ARCH_V6T2,	      ARM_ARCH_V6ZT2},
+    {TAG_CPU_ARCH_V6T2,	      ARM_ARCH_V6KZT2},
 
     /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
        always selected build attributes to match those of ARMv6-M
@@ -27316,25 +27317,26 @@  static const cpu_arch_ver_table cpu_arch_ver[] =
        would be selected when fully respecting chronology of architectures.
        It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
        move them before ARMv7 architectures.  */
-    {TAG_CPU_ARCH_V6_M,	    ARM_ARCH_V6M},
-    {TAG_CPU_ARCH_V6S_M,    ARM_ARCH_V6SM},
-
-    {TAG_CPU_ARCH_V7,	    ARM_ARCH_V7},
-    {TAG_CPU_ARCH_V7,	    ARM_ARCH_V7A},
-    {TAG_CPU_ARCH_V7,	    ARM_ARCH_V7R},
-    {TAG_CPU_ARCH_V7,	    ARM_ARCH_V7M},
-    {TAG_CPU_ARCH_V7,	    ARM_ARCH_V7VE},
-    {TAG_CPU_ARCH_V7E_M,    ARM_ARCH_V7EM},
-    {TAG_CPU_ARCH_V8,	    ARM_ARCH_V8A},
-    {TAG_CPU_ARCH_V8,	    ARM_ARCH_V8_1A},
-    {TAG_CPU_ARCH_V8,	    ARM_ARCH_V8_2A},
-    {TAG_CPU_ARCH_V8,	    ARM_ARCH_V8_3A},
-    {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
-    {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
-    {TAG_CPU_ARCH_V8R,	    ARM_ARCH_V8R},
-    {TAG_CPU_ARCH_V8,	    ARM_ARCH_V8_4A},
-    {TAG_CPU_ARCH_V8,	    ARM_ARCH_V8_5A},
-    {-1,		    ARM_ARCH_NONE}
+    {TAG_CPU_ARCH_V6_M,	      ARM_ARCH_V6M},
+    {TAG_CPU_ARCH_V6S_M,      ARM_ARCH_V6SM},
+
+    {TAG_CPU_ARCH_V7,	      ARM_ARCH_V7},
+    {TAG_CPU_ARCH_V7,	      ARM_ARCH_V7A},
+    {TAG_CPU_ARCH_V7,	      ARM_ARCH_V7R},
+    {TAG_CPU_ARCH_V7,	      ARM_ARCH_V7M},
+    {TAG_CPU_ARCH_V7,	      ARM_ARCH_V7VE},
+    {TAG_CPU_ARCH_V7E_M,      ARM_ARCH_V7EM},
+    {TAG_CPU_ARCH_V8,	      ARM_ARCH_V8A},
+    {TAG_CPU_ARCH_V8,	      ARM_ARCH_V8_1A},
+    {TAG_CPU_ARCH_V8,	      ARM_ARCH_V8_2A},
+    {TAG_CPU_ARCH_V8,	      ARM_ARCH_V8_3A},
+    {TAG_CPU_ARCH_V8M_BASE,   ARM_ARCH_V8M_BASE},
+    {TAG_CPU_ARCH_V8M_MAIN,   ARM_ARCH_V8M_MAIN},
+    {TAG_CPU_ARCH_V8R,	      ARM_ARCH_V8R},
+    {TAG_CPU_ARCH_V8,	      ARM_ARCH_V8_4A},
+    {TAG_CPU_ARCH_V8,	      ARM_ARCH_V8_5A},
+    {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
+    {-1,		      ARM_ARCH_NONE}
 };
 
 /* Set an attribute if it has not already been set by the user.  */
@@ -27417,7 +27419,7 @@  get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
   if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
     {
       /* Force revisiting of decision for each new architecture.  */
-      gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8M_MAIN);
+      gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
       *profile = 'A';
       return TAG_CPU_ARCH_V8;
     }
@@ -27688,7 +27690,7 @@  aeabi_set_public_attributes (void)
      by the base architecture.
 
      For new architectures we will have to check these tests.  */
-  gas_assert (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
   if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
       || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
     aeabi_set_attribute_int (Tag_DIV_use, 0);
diff --git a/gas/testsuite/gas/arm/attr-march-armv8_1-m.main.d b/gas/testsuite/gas/arm/attr-march-armv8_1-m.main.d
new file mode 100644
index 0000000000000000000000000000000000000000..acae2e31fe1afed95ee6a9466fbec13f45d05740
--- /dev/null
+++ b/gas/testsuite/gas/arm/attr-march-armv8_1-m.main.d
@@ -0,0 +1,13 @@ 
+# name: attributes for -march=armv8.1-m.main
+# source: blank.s
+# as: -march=armv8.1-m.main
+# readelf: -A
+# This test is only valid on EABI based ports.
+# target: *-*-*eabi* *-*-nacl*
+
+Attribute Section: aeabi
+File Attributes
+  Tag_CPU_name: "8.1-M.MAIN"
+  Tag_CPU_arch: v8.1-M.mainline
+  Tag_CPU_arch_profile: Microcontroller
+  Tag_THUMB_ISA_use: Yes
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 13f20002c25e126ad266b166c6e21125c57a4aaf..daf1d94391ea23c49cb646af430d2db8ef46c51e 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -111,7 +111,8 @@ 
 #define TAG_CPU_ARCH_V8R	15
 #define TAG_CPU_ARCH_V8M_BASE	16
 #define TAG_CPU_ARCH_V8M_MAIN	17
-#define MAX_TAG_CPU_ARCH	TAG_CPU_ARCH_V8M_MAIN
+#define TAG_CPU_ARCH_V8_1M_MAIN 21
+#define MAX_TAG_CPU_ARCH	TAG_CPU_ARCH_V8_1M_MAIN
 /* Pseudo-architecture to allow objects to be compatible with the subset of
    armv4t and armv6-m.  This value should never be stored in object files.  */
 #define TAG_CPU_ARCH_V4T_PLUS_V6_M (MAX_TAG_CPU_ARCH + 1)
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 4f5c89f8383b419832fea1aca0335553cbe4221d..73fb2e3f43c5fd2d77dc796b7decb329c5a8a57f 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -72,6 +72,7 @@ 
 #define ARM_EXT2_V8_5A	     0x00001000	/* ARM V8.5A.			     */
 #define ARM_EXT2_SB	     0x00002000	/* Speculation Barrier instruction.  */
 #define ARM_EXT2_PREDRES     0x00004000	/* Prediction Restriction insns.     */
+#define ARM_EXT2_V8_1M_MAIN  0x00008000 /* ARMv8.1-M Mainline.		     */
 
 /* Co-processor space extensions.  */
 #define ARM_CEXT_XSCALE	     0x00000001	/* Allow MIA etc.	 	   */
@@ -175,6 +176,9 @@ 
 #define ARM_AEXT2_V8M_MAIN_DSP	 ARM_AEXT2_V8M_MAIN
 #define ARM_AEXT_V8R		 ARM_AEXT_V8A
 #define ARM_AEXT2_V8R		 ARM_AEXT2_V8AR
+#define ARM_AEXT_V8_1M_MAIN	 ARM_AEXT_V8M_MAIN
+#define ARM_AEXT2_V8_1M_MAIN	(ARM_AEXT2_V8M_MAIN | ARM_EXT2_V8_1M_MAIN     \
+						    | ARM_EXT2_FP16_INST)
 
 /* Processors with specific extensions in the co-processor space.  */
 #define ARM_ARCH_XSCALE	ARM_FEATURE_LOW (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
@@ -353,6 +357,8 @@ 
 #define ARM_ARCH_V8M_MAIN_DSP  ARM_FEATURE_CORE (ARM_AEXT_V8M_MAIN_DSP,	   \
 						 ARM_AEXT2_V8M_MAIN_DSP)
 #define ARM_ARCH_V8R	       ARM_FEATURE_CORE (ARM_AEXT_V8R, ARM_AEXT2_V8R)
+#define ARM_ARCH_V8_1M_MAIN    ARM_FEATURE_CORE (ARM_AEXT_V8_1M_MAIN,	   \
+						 ARM_AEXT2_V8_1M_MAIN)
 
 /* Some useful combinations:  */
 #define ARM_ARCH_NONE	ARM_FEATURE_LOW (0, 0)
diff --git a/ld/testsuite/ld-arm/attr-merge-13.attr b/ld/testsuite/ld-arm/attr-merge-13.attr
new file mode 100644
index 0000000000000000000000000000000000000000..9fabb5b88e5fbba01ce68d40597e69866e11d7f1
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-13.attr
@@ -0,0 +1,6 @@ 
+Attribute Section: aeabi
+File Attributes
+  Tag_CPU_name: "8.1-M.MAIN"
+  Tag_CPU_arch: v8.1-M.mainline
+  Tag_CPU_arch_profile: Microcontroller
+  Tag_THUMB_ISA_use: Yes
diff --git a/ld/testsuite/ld-arm/attr-merge-13a.s b/ld/testsuite/ld-arm/attr-merge-13a.s
new file mode 100644
index 0000000000000000000000000000000000000000..5349f7ff3b5ccb0bb5d226b8deed743335d93e44
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-13a.s
@@ -0,0 +1,5 @@ 
+	.arch armv8-m.main
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v8-M.mainline
+	.eabi_attribute Tag_CPU_arch, 17
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/ld/testsuite/ld-arm/attr-merge-13b.s b/ld/testsuite/ld-arm/attr-merge-13b.s
new file mode 100644
index 0000000000000000000000000000000000000000..20e075357a94edae8d649f034ab3e17efa3c06d2
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-13b.s
@@ -0,0 +1,5 @@ 
+	.arch armv8.1-m.main
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v8.1-M.mainline
+	.eabi_attribute Tag_CPU_arch, 18
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 71d7c524a22b0d93e5b0dd1573abbe158cd636e8..be9879da621c14e4dd8a816a371aaad6ccc4a696 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -6464,6 +6464,7 @@  select_arm_features (unsigned long mach,
     case bfd_mach_arm_8R:	 ARM_SET_FEATURES (ARM_ARCH_V8R); break;
     case bfd_mach_arm_8M_BASE:	 ARM_SET_FEATURES (ARM_ARCH_V8M_BASE); break;
     case bfd_mach_arm_8M_MAIN:	 ARM_SET_FEATURES (ARM_ARCH_V8M_MAIN); break;
+    case bfd_mach_arm_8_1M_MAIN: ARM_SET_FEATURES (ARM_ARCH_V8_1M_MAIN); break;
       /* If the machine type is unknown allow all architecture types and all
 	 extensions.  */
     case bfd_mach_arm_unknown:	 ARM_SET_FEATURES (ARM_FEATURE_ALL); break;