Bug 85606 - [8,9 regression] Assembly file generated for ARM Cortex-M0 should not specify `.arch armv6-m` at all or use `.arch armv6s-m`
Summary: [8,9 regression] Assembly file generated for ARM Cortex-M0 should not specify...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 8.0.1
: P3 normal
Target Milestone: 8.2
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-05-02 10:17 UTC by Freddie Chopin
Modified: 2018-05-11 09:33 UTC (History)
0 users

See Also:
Host:
Target: arm-none-eabi
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-05-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Freddie Chopin 2018-05-02 10:17:14 UTC
This issue is inspired by following bug report for GAS - https://sourceware.org/bugzilla/show_bug.cgi?id=23126

Following test case works perfectly fine for GCC 5, 6 and 7, however it fails with GCC 8.0.1 20180427:

-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --

$ cat svc.cpp 
__attribute__ ((naked))
int supervisorCall(int (& function)(int, int, int, int), const int argument1, const int argument2, const int argument3,
		const int argument4)
{
	asm volatile
	(
			"	mov		r12, r0		\n"
			"	ldr		r0, [sp]	\n"
			"	svc		0			\n"
			"						\n"
			"	bx		lr			\n"
	);

	__builtin_unreachable();

	// suppress warnings
	(void)function;
	(void)argument1;
	(void)argument2;
	(void)argument3;
	(void)argument4;
}
$ arm-none-eabi-g++ -c svc.cpp -mcpu=cortex-m0 -save-temps
svc.s: Assembler messages:
svc.s:31: Error: SVC is not permitted on this architecture
$ diff -u svc-7.s svc.s 
--- svc-7.s	2018-05-01 20:14:09.031910734 +0200
+++ svc.s	2018-05-01 20:16:36.751143427 +0200
@@ -12,6 +12,7 @@
 	.text
 	.align	1
 	.global	_Z14supervisorCallRFiiiiiEiiii
+	.arch armv6-m
 	.syntax unified
 	.code	16
 	.thumb_func
@@ -37,4 +38,4 @@
 	.cantunwind
 	.fnend
 	.size	_Z14supervisorCallRFiiiiiEiiii, .-_Z14supervisorCallRFiiiiiEiiii
-	.ident	"GCC: (bleeding-edge-toolchain) 7.3.0"
+	.ident	"GCC: (bleeding-edge-toolchain) 8.0.1 20180427 (prerelease)"
$ cat svc.s 
	.cpu cortex-m0
	.eabi_attribute 20, 1
	.eabi_attribute 21, 1
	.eabi_attribute 23, 3
	.eabi_attribute 24, 1
	.eabi_attribute 25, 1
	.eabi_attribute 26, 1
	.eabi_attribute 30, 6
	.eabi_attribute 34, 0
	.eabi_attribute 18, 4
	.file	"svc.cpp"
	.text
	.align	1
	.global	_Z14supervisorCallRFiiiiiEiiii
	.arch armv6-m
	.syntax unified
	.code	16
	.thumb_func
	.fpu softvfp
	.type	_Z14supervisorCallRFiiiiiEiiii, %function
_Z14supervisorCallRFiiiiiEiiii:
	.fnstart
.LFB0:
	@ Naked Function: prologue and epilogue provided by programmer.
	@ args = 4, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	.syntax divided
@ 12 "svc.cpp" 1
		mov		r12, r0		
	ldr		r0, [sp]	
	svc		0			
						
	bx		lr			

@ 0 "" 2
	.thumb
	.syntax unified
	.cantunwind
	.fnend
	.size	_Z14supervisorCallRFiiiiiEiiii, .-_Z14supervisorCallRFiiiiiEiiii
	.ident	"GCC: (bleeding-edge-toolchain) 8.0.1 20180427 (prerelease)"

-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --

(svc-7.s is a temp file generated with GCC 7.3.0)

Nick Clifton in his comment (https://sourceware.org/bugzilla/show_bug.cgi?id=23126#c4) to the mentioned GAS bug report suggested that GCC 8 should either specify just `.cpu` (behaviour as in previous versions) or specify `.arch armv6s-m` instead of `.arch armv6-m`. Personally I think the first option should be more reliable in that case, however this is just a guess.
Comment 1 Richard Earnshaw 2018-05-10 13:20:10 UTC
This is the convergence of a number of niggly issues.

Initially Arm defined both ARMv6-M and ARMv6S-M.  The two differed only by support for the SVC instruction in the latter.  Later, they dropped the name ARMv6S-M but added support for SVC to ARMv6-M (in effect they made ARMv6-M equivalent to ARMv6S-M).

To avoid massive churn on the assembler every time new CPU names are added, we changed GCC-8 to not emit CPU names directly into the assembler files (architecture names are much more stable and smaller in number); this makes it far more likely that you won't have to update GAS each time a new CPU name is added (a Good Thing TM).

Cortex-m0, cortex-m0plus and cortex-m1 are all ARMv6-M parts, but they are really, in GCC/gas terminology ARMv6S-M parts.  Gas seems to treat these CPUs as ARMv6S-M, but still distinguishes between v6-M and v6S-M, hence the failure reported.

So I think the compiler should treat all these parts as ARMv6S-M going forward.  That's a fairly simple change to arm-cpus.in.

I think GAS needs some changes as well, to make .arch armv6-m be treated in the same way as armv6s-m, but that's a separate issue.
Comment 2 Richard Earnshaw 2018-05-11 09:28:42 UTC
Author: rearnsha
Date: Fri May 11 09:28:10 2018
New Revision: 260157

URL: https://gcc.gnu.org/viewcvs?rev=260157&root=gcc&view=rev
Log:
[arm] PR target/85606 prefer armv6s-m for armv6-m parts

When Arm introduced ARMv6-M there were two variants, ARMv6-M and
ARMv6S-M.  The two differed only in support for the SVC instruction.
Later on SVC was then made a mandatory part of ARMv6-M and the
ARMv6S-M name was dropped.  GCC and GAS, however still recognize both
names and at least some versions of GAS still distinguish between the
two.

To address this, this patch changes the architecture for the ARMv6-m
cortex parts (m0, m0plus, m1 and the variants will small multiply
units) to use the ARMv6S-M name in conjunction with the assembler.
This avoids problems with them rejecting code that was previously
accepted with older versions of GCC where we did not pass an explicit
architecture string through to the compiler when using -mcpu on the
command line.

	PR target/85606
	* config/arm/arm-cpus.in: Add comment that ARMv6-m and ARMv6S-m are now
	equivalent.
	(cortex-m0): Use armv6s-m isa.
	(cortex-m0plus): Likewise.
	(cortex-m1): Likewise.
	(cortex-m0.small-multiply): Likewise.
	(cortex-m0plus.small-multiply): Likewise.
	(cortex-m1.small-multiply): Likewise.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/arm/arm-cpus.in
Comment 3 Richard Earnshaw 2018-05-11 09:31:21 UTC
Author: rearnsha
Date: Fri May 11 09:30:49 2018
New Revision: 260158

URL: https://gcc.gnu.org/viewcvs?rev=260158&root=gcc&view=rev
Log:
[arm] PR target/85606 prefer armv6s-m for armv6-m parts

When Arm introduced ARMv6-M there were two variants, ARMv6-M and
ARMv6S-M.  The two differed only in support for the SVC instruction.
Later on SVC was then made a mandatory part of ARMv6-M and the
ARMv6S-M name was dropped.  GCC and GAS, however still recognize both
names and at least some versions of GAS still distinguish between the
two.

To address this, this patch changes the architecture for the ARMv6-m
cortex parts (m0, m0plus, m1 and the variants will small multiply
units) to use the ARMv6S-M name in conjunction with the assembler.
This avoids problems with them rejecting code that was previously
accepted with older versions of GCC where we did not pass an explicit
architecture string through to the compiler when using -mcpu on the
command line.

	PR target/85606
	* config/arm/arm-cpus.in: Add comment that ARMv6-m and ARMv6S-m are now
	equivalent.
	(cortex-m0): Use armv6s-m isa.
	(cortex-m0plus): Likewise.
	(cortex-m1): Likewise.
	(cortex-m0.small-multiply): Likewise.
	(cortex-m0plus.small-multiply): Likewise.
	(cortex-m1.small-multiply): Likewise.

Modified:
    branches/gcc-8-branch/gcc/ChangeLog
    branches/gcc-8-branch/gcc/config/arm/arm-cpus.in
Comment 4 Richard Earnshaw 2018-05-11 09:33:24 UTC
Fixed.