aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2015-12-24 17:16:19 +0800
committerThomas Preud'homme <thomas.preudhomme@arm.com>2015-12-24 17:26:54 +0800
commit4ed7ed8db2289a9cd61312c14344cb210dc229b7 (patch)
tree93f6ac4a25e12f348e4b74226ec858d0e45ff3a2 /gas
parentfc289b0a832c536a2ec324634cb420f39b212696 (diff)
downloadfsf-binutils-gdb-4ed7ed8db2289a9cd61312c14344cb210dc229b7.zip
fsf-binutils-gdb-4ed7ed8db2289a9cd61312c14344cb210dc229b7.tar.gz
fsf-binutils-gdb-4ed7ed8db2289a9cd61312c14344cb210dc229b7.tar.bz2
Add assembler support for ARMv8-M Mainline
2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com> bfd/ (tag_cpu_arch_combine): Adjust v4t_plus_v6_m and comb array to account for new TAG_CPU_ARCH_V4T_PLUS_V6_M value. Deal with NULL values in comb array. binutils/ * readelf.c (arm_attr_tag_CPU_arch): Add ARMv8-M Mainline Tag_CPU_arch value. (arm_attr_tag_THUMB_ISA_use): Add ARMv8-M Mainline Tag_THUMB_ISA_use value. gas/ * config/tc-arm.c (arm_ext_m): Include ARMv8-M. (arm_ext_v8m): New feature for ARMv8-M. (arm_ext_atomics): New feature for ARMv8 atomics. (do_tt): New encoding function for TT* instructions. (insns): Add new entries for ARMv8-M specific instructions and reorganize the ones shared by ARMv8-M Mainline and ARMv8-A. (arm_archs): Define armv8-m.main architecture. (cpu_arch_ver): Define ARM_ARCH_V8M_MAIN architecture version and clarify the ordering rule. (aeabi_set_public_attributes): Use TAG_CPU_ARCH_* macro to refer to Tag_CPU_arch values for ARMv7e-M detection. Add logic to keep setting Tag_CPU_arch to ARMv8-A for -march=all. Also set Tag_CPU_arch_profile to 'A' if extension bit for atomic instructions is set, unless it is ARMv8-M. Set Tag_THUMB_ISA_use to 3 for ARMv8-M. Set Tag_DIV_use to 0 for ARMv8-M Mainline. gas/testsuite/ * gas/arm/archv8m.s: New file. * gas/arm/archv8m-main.d: Likewise. * gas/arm/attr-march-armv8m.main.d: Likewise. * gas/arm/any-armv8m.s: Likewise. * gas/arm/any-armv8m.d: Likewise. include/elf/ * arm.h (TAG_CPU_ARCH_V8M_MAIN): Declare. (MAX_TAG_CPU_ARCH): Define to TAG_CPU_ARCH_V8M_MAIN. (TAG_CPU_ARCH_V4T_PLUS_V6_M): Define to unused value 15. include/opcode/ * arm.h (ARM_EXT2_ATOMICS): New extension bit. (ARM_EXT2_V8M): Likewise. (ARM_EXT_V8): Adjust comment with regards to atomics and remove mention of legacy use for that bit. (ARM_AEXT2_V8_1A): New architecture extension bitfield. (ARM_AEXT2_V8_2A): Likewise. (ARM_AEXT_V8M_MAIN): Likewise. (ARM_AEXT2_V8M): Likewise. (ARM_ARCH_V8A): Use ARM_EXT2_ATOMICS for features in second bitfield. (ARM_ARCH_V8_1A): Likewise with ARM_AEXT2_V8_1A. (ARM_ARCH_V8_2A): Likewise with ARM_AEXT2_V8_2A. (ARM_ARCH_V8M_MAIN): New architecture feature bitfield. (ARM_ARCH_V8A_FP): Use ARM_EXT2_ATOMICS for features in second bitfield and reindent. (ARM_ARCH_V8A_SIMD): Likewise. (ARM_ARCH_V8A_CRYPTOV1): Likewise. (ARM_ARCH_V8_1A_FP): Use ARM_AEXT2_V8_1A to set second bitfield of feature bits. (ARM_ARCH_V8_1A_SIMD): Likewise. (ARM_ARCH_V8_1A_CRYPTOV1): Likewise. opcodes/ * arm-dis.c (arm_opcodes): Guard lda, ldab, ldaex, ldaexb, ldaexh, stl, stlb, stlh, stlex, stlexb and stlexh by ARM_EXT2_ATOMICS instead of ARM_EXT_V8. (thumb32_opcodes): Add entries for wide ARMv8-M instructions.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog18
-rw-r--r--gas/config/tc-arm.c95
-rw-r--r--gas/testsuite/ChangeLog8
-rw-r--r--gas/testsuite/gas/arm/any-armv8m.d12
-rw-r--r--gas/testsuite/gas/arm/any-armv8m.s4
-rw-r--r--gas/testsuite/gas/arm/archv8m-main.d47
-rw-r--r--gas/testsuite/gas/arm/archv8m.s45
-rw-r--r--gas/testsuite/gas/arm/attr-march-armv8m.main.d13
8 files changed, 217 insertions, 25 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8a62482..a4c0db6 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,23 @@
2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * config/tc-arm.c (arm_ext_m): Include ARMv8-M.
+ (arm_ext_v8m): New feature for ARMv8-M.
+ (arm_ext_atomics): New feature for ARMv8 atomics.
+ (do_tt): New encoding function for TT* instructions.
+ (insns): Add new entries for ARMv8-M specific instructions and
+ reorganize the ones shared by ARMv8-M Mainline and ARMv8-A.
+ (arm_archs): Define armv8-m.main architecture.
+ (cpu_arch_ver): Define ARM_ARCH_V8M_MAIN architecture version and
+ clarify the ordering rule.
+ (aeabi_set_public_attributes): Use TAG_CPU_ARCH_* macro to refer to
+ Tag_CPU_arch values for ARMv7e-M detection. Add logic to keep setting
+ Tag_CPU_arch to ARMv8-A for -march=all. Also set Tag_CPU_arch_profile
+ to 'A' if extension bit for atomic instructions is set, unless it is
+ ARMv8-M. Set Tag_THUMB_ISA_use to 3 for ARMv8-M. Set Tag_DIV_use to 0
+ for ARMv8-M Mainline.
+
+2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* config/tc-arm.c (move_or_literal_pool): Check mov.w, mvm and movw
availability against arm_ext_v6t2 instead of checking arm_arch_t2,
fixing comments along the way.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 23e3506..7992360 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -201,13 +201,17 @@ static const arm_feature_set arm_ext_v7r = ARM_FEATURE_CORE_LOW (ARM_EXT_V7R);
static const arm_feature_set arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
static const arm_feature_set arm_ext_v8 = ARM_FEATURE_CORE_LOW (ARM_EXT_V8);
static const arm_feature_set arm_ext_m =
- ARM_FEATURE_CORE_LOW (ARM_EXT_V6M | ARM_EXT_OS | ARM_EXT_V7M);
+ ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_OS | ARM_EXT_V7M, ARM_EXT2_V8M);
static const arm_feature_set arm_ext_mp = ARM_FEATURE_CORE_LOW (ARM_EXT_MP);
static const arm_feature_set arm_ext_sec = ARM_FEATURE_CORE_LOW (ARM_EXT_SEC);
static const arm_feature_set arm_ext_os = ARM_FEATURE_CORE_LOW (ARM_EXT_OS);
static const arm_feature_set arm_ext_adiv = ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV);
static const arm_feature_set arm_ext_virt = ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT);
static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
+static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
+/* Instructions shared between ARMv8-A and ARMv8-M. */
+static const arm_feature_set arm_ext_atomics =
+ ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS);
static const arm_feature_set arm_arch_any = ARM_ANY;
static const arm_feature_set arm_arch_full = ARM_FEATURE (-1, -1, -1);
@@ -8148,6 +8152,13 @@ do_rn_rd (void)
inst.instruction |= inst.operands[1].reg << 12;
}
+static void
+do_tt (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+}
+
static bfd_boolean
check_obsolete (const arm_feature_set *feature, const char *msg)
{
@@ -19178,31 +19189,35 @@ static const struct asm_opcode insns[] =
/* AArchv8 instructions. */
#undef ARM_VARIANT
#define ARM_VARIANT & arm_ext_v8
+
+/* Instructions shared between armv8-a and armv8-m. */
#undef THUMB_VARIANT
-#define THUMB_VARIANT & arm_ext_v8
+#define THUMB_VARIANT & arm_ext_atomics
- tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
- TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
+ TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
+ TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
+ TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
+ TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
+ TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
+ TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
- TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
- ldrexd, t_ldrexd),
TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
stlex, t_stlex),
- TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
- strexd, t_strexd),
TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
stlex, t_stlex),
TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
stlex, t_stlex),
- TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
- TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
- TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
- TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
- TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
- TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & arm_ext_v8
+ tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
+ TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
+ TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
+ ldrexd, t_ldrexd),
+ TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
+ strexd, t_strexd),
/* ARMv8 T32 only. */
#undef ARM_VARIANT
#define ARM_VARIANT NULL
@@ -20500,6 +20515,13 @@ static const struct asm_opcode insns[] =
cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
+
+#undef ARM_VARIANT
+#define ARM_VARIANT NULL
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & arm_ext_v8m
+ TUE("tt", 0, e840f000, 2, (RRnpc, RRnpc), 0, tt),
+ TUE("ttt", 0, e840f040, 2, (RRnpc, RRnpc), 0, tt),
};
#undef ARM_VARIANT
#undef THUMB_VARIANT
@@ -24940,6 +24962,7 @@ static const struct arm_arch_option_table arm_archs[] =
ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP),
+ ARM_ARCH_OPT ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP),
@@ -25538,8 +25561,9 @@ typedef struct
arm_feature_set flags;
} cpu_arch_ver_table;
-/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
- least features first. */
+/* Mapping from CPU features to EABI CPU arch values. As a general rule, table
+ must be sorted least features first but some reordering is needed, eg. for
+ Thumb-2 instructions to be detected as coming from ARMv6T2. */
static const cpu_arch_ver_table cpu_arch_ver[] =
{
{1, ARM_ARCH_V4},
@@ -25558,6 +25582,7 @@ static const cpu_arch_ver_table cpu_arch_ver[] =
{10, ARM_ARCH_V7R},
{10, ARM_ARCH_V7M},
{14, ARM_ARCH_V8A},
+ {17, ARM_ARCH_V8M_MAIN},
{0, ARM_ARCH_NONE}
};
@@ -25638,11 +25663,18 @@ aeabi_set_public_attributes (void)
actually used. Perhaps we should separate out the specified
and implicit cases. Avoid taking this path for -march=all by
checking for contradictory v7-A / v7-M features. */
- if (arch == 10
+ if (arch == TAG_CPU_ARCH_V7
&& !ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
&& ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m)
&& ARM_CPU_HAS_FEATURE (flags, arm_ext_v6_dsp))
- arch = 13;
+ arch = TAG_CPU_ARCH_V7E_M;
+
+ /* In cpu_arch_ver ARMv8-A is before ARMv8-M for atomics to be detected as
+ coming from ARMv8-A. However, since ARMv8-A has more instructions than
+ ARMv8-M, -march=all must be detected as ARMv8-A. */
+ if (arch == TAG_CPU_ARCH_V8M_MAIN
+ && ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
+ arch = TAG_CPU_ARCH_V8;
/* Tag_CPU_name. */
if (selected_cpu_name[0])
@@ -25666,7 +25698,9 @@ aeabi_set_public_attributes (void)
/* Tag_CPU_arch_profile. */
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
- || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8))
+ || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
+ || (ARM_CPU_HAS_FEATURE (flags, arm_ext_atomics)
+ && !ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m)))
profile = 'A';
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7r))
profile = 'R';
@@ -25686,8 +25720,18 @@ aeabi_set_public_attributes (void)
/* Tag_THUMB_ISA_use. */
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
|| arch == 0)
- aeabi_set_attribute_int (Tag_THUMB_ISA_use,
- ARM_CPU_HAS_FEATURE (flags, arm_arch_t2) ? 2 : 1);
+ {
+ int thumb_isa_use;
+
+ if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
+ && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
+ thumb_isa_use = 3;
+ else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
+ thumb_isa_use = 2;
+ else
+ thumb_isa_use = 1;
+ aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
+ }
/* Tag_VFP_arch. */
if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
@@ -25751,12 +25795,13 @@ aeabi_set_public_attributes (void)
in ARM state, or when Thumb integer divide instructions have been used,
but we have no architecture profile set, nor have we any ARM instructions.
- For ARMv8 we set the tag to 0 as integer divide is implied by the base
- architecture.
+ For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
+ by the base architecture.
For new architectures we will have to check these tests. */
- gas_assert (arch <= TAG_CPU_ARCH_V8);
- if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8))
+ gas_assert (arch <= TAG_CPU_ARCH_V8 || arch == TAG_CPU_ARCH_V8M_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);
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
|| (profile == '\0'
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index eac24c2..baad934 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ * gas/arm/archv8m.s: New file.
+ * gas/arm/archv8m-main.d: Likewise.
+ * gas/arm/attr-march-armv8m.main.d: Likewise.
+ * gas/arm/any-armv8m.s: Likewise.
+ * gas/arm/any-armv8m.d: Likewise.
+
2015-12-24 Andre Vieira <andre.simoesdiasvieira@arm.com>
* gas/arm/automatic-bw.d: New.
diff --git a/gas/testsuite/gas/arm/any-armv8m.d b/gas/testsuite/gas/arm/any-armv8m.d
new file mode 100644
index 0000000..fc0b22d
--- /dev/null
+++ b/gas/testsuite/gas/arm/any-armv8m.d
@@ -0,0 +1,12 @@
+# name: attributes for 'any' CPU with ARMv8-M security extension
+# source: any-armv8m.s
+# as: -mthumb
+# readelf: -A
+# This test is only valid on EABI based ports.
+# target: *-*-*eabi* *-*-nacl*
+
+Attribute Section: aeabi
+File Attributes
+ Tag_CPU_arch: v8-M.mainline
+ Tag_CPU_arch_profile: Microcontroller
+ Tag_THUMB_ISA_use: Yes
diff --git a/gas/testsuite/gas/arm/any-armv8m.s b/gas/testsuite/gas/arm/any-armv8m.s
new file mode 100644
index 0000000..f0e4084
--- /dev/null
+++ b/gas/testsuite/gas/arm/any-armv8m.s
@@ -0,0 +1,4 @@
+tt r0, r1
+tt r8, r9
+ttt r0, r1
+ttt r8, r9
diff --git a/gas/testsuite/gas/arm/archv8m-main.d b/gas/testsuite/gas/arm/archv8m-main.d
new file mode 100644
index 0000000..c86bab3
--- /dev/null
+++ b/gas/testsuite/gas/arm/archv8m-main.d
@@ -0,0 +1,47 @@
+#name: ARM V8-M mainline instructions
+#source: archv8m.s
+#as: -march=armv8-m.main
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+.* <[^>]*> 47a0 blx r4
+0+.* <[^>]*> 47c8 blx r9
+0+.* <[^>]*> 4720 bx r4
+0+.* <[^>]*> 4748 bx r9
+0+.* <[^>]*> e841 f000 tt r0, r1
+0+.* <[^>]*> e849 f800 tt r8, r9
+0+.* <[^>]*> e841 f040 ttt r0, r1
+0+.* <[^>]*> e849 f840 ttt r8, r9
+0+.* <[^>]*> f24f 1023 movw r0, #61731 ; 0xf123
+0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123
+0+.* <[^>]*> f2cf 1023 movt r0, #61731 ; 0xf123
+0+.* <[^>]*> f2cf 1823 movt r8, #61731 ; 0xf123
+0+.* <[^>]*> b154 cbz r4, 0+.* <[^>]*>
+0+.* <[^>]*> b94c cbnz r4, 0+.* <[^>]*>
+0+.* <[^>]*> f000 b808 b.w 0+.* <[^>]*>
+0+.* <[^>]*> fb91 f0f2 sdiv r0, r1, r2
+0+.* <[^>]*> fb99 f8fa sdiv r8, r9, sl
+0+.* <[^>]*> fbb1 f0f2 udiv r0, r1, r2
+0+.* <[^>]*> fbb9 f8fa udiv r8, r9, sl
+0+.* <[^>]*> 4408 add r0, r1
+0+.* <[^>]*> f3bf 8f2f clrex
+0+.* <[^>]*> e851 0f01 ldrex r0, \[r1, #4\]
+0+.* <[^>]*> e8d1 0f4f ldrexb r0, \[r1\]
+0+.* <[^>]*> e8d1 0f5f ldrexh r0, \[r1\]
+0+.* <[^>]*> e842 1001 strex r0, r1, \[r2, #4\]
+0+.* <[^>]*> e8c2 1f40 strexb r0, r1, \[r2\]
+0+.* <[^>]*> e8c2 1f50 strexh r0, r1, \[r2\]
+0+.* <[^>]*> e8d1 0faf lda r0, \[r1\]
+0+.* <[^>]*> e8d1 0f8f ldab r0, \[r1\]
+0+.* <[^>]*> e8d1 0f9f ldah r0, \[r1\]
+0+.* <[^>]*> e8c1 0faf stl r0, \[r1\]
+0+.* <[^>]*> e8c1 0f8f stlb r0, \[r1\]
+0+.* <[^>]*> e8c1 0f9f stlh r0, \[r1\]
+0+.* <[^>]*> e8d1 0fef ldaex r0, \[r1\]
+0+.* <[^>]*> e8d1 0fcf ldaexb r0, \[r1\]
+0+.* <[^>]*> e8d1 0fdf ldaexh r0, \[r1\]
+0+.* <[^>]*> e8c2 1fe0 stlex r0, r1, \[r2\]
+0+.* <[^>]*> e8c2 1fc0 stlexb r0, r1, \[r2\]
+0+.* <[^>]*> e8c2 1fd0 stlexh r0, r1, \[r2\]
diff --git a/gas/testsuite/gas/arm/archv8m.s b/gas/testsuite/gas/arm/archv8m.s
new file mode 100644
index 0000000..8aca8ba
--- /dev/null
+++ b/gas/testsuite/gas/arm/archv8m.s
@@ -0,0 +1,45 @@
+.thumb
+.syntax unified
+
+blx r4
+blx r9
+bx r4
+bx r9
+tt r0, r1
+tt r8, r9
+ttt r0, r1
+ttt r8, r9
+movw r0, #0xF123
+movw r8, #0xF123
+movt r0, #0xF123
+movt r8, #0xF123
+cbz r4, .L1
+cbnz r4, .L1
+b.w .L1
+sdiv r0, r1, r2
+sdiv r8, r9, r10
+udiv r0, r1, r2
+udiv r8, r9, r10
+.L1:
+ add r0, r1
+clrex
+ldrex r0, [r1, #0x4]
+ldrexb r0, [r1]
+ldrexh r0, [r1]
+strex r0, r1, [r2, #0x4]
+strexb r0, r1, [r2]
+strexh r0, r1, [r2]
+lda r0, [r1]
+ldab r0, [r1]
+ldah r0, [r1]
+stl r0, [r1]
+stlb r0, [r1]
+stlh r0, [r1]
+ldaex r0, [r1]
+ldaexb r0, [r1]
+ldaexh r0, [r1]
+stlex r0, r1, [r2]
+stlexb r0, r1, [r2]
+stlexh r0, r1, [r2]
+
+
diff --git a/gas/testsuite/gas/arm/attr-march-armv8m.main.d b/gas/testsuite/gas/arm/attr-march-armv8m.main.d
new file mode 100644
index 0000000..7a194e2
--- /dev/null
+++ b/gas/testsuite/gas/arm/attr-march-armv8m.main.d
@@ -0,0 +1,13 @@
+# name: attributes for -march=armv8-m.main
+# source: blank.s
+# as: -march=armv8-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-M.MAIN"
+ Tag_CPU_arch: v8-M.mainline
+ Tag_CPU_arch_profile: Microcontroller
+ Tag_THUMB_ISA_use: Yes