Bug 98627 - GCC emits unaligned memory access instructions causing address error exceptions with the 68000 architecture
Summary: GCC emits unaligned memory access instructions causing address error exceptio...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 9.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-01-11 17:22 UTC by Fredrik Noring
Modified: 2021-01-12 19:20 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fredrik Noring 2021-01-11 17:22:32 UTC
The 68000 architecture requires that (16-bit) word and (32-bit) long memory accesses are aligned with even addresses, but GCC frequently emits code that breaks this when compiling with optimisations (O1 or higher). This causes address error exceptions, which are fatal errors that crash programs.

For example, consider

struct s { char a, b, c, d, e; };
struct s f(char a)
{
	return (struct s) { .a = a, .d = 'd' };
}

that GCC with O1 will compile into

00000000 <f>:
   0:	2049           	moveal %a1,%a0
   2:	202f 0004      	movel %sp@(4),%d0
   6:	42a9 0001      	clrl %a1@(1)        /* <<<--- unaligned long clear */
   a:	1280           	moveb %d0,%a1@
   c:	137c 0064 0003 	moveb #100,%a1@(3)
  12:	4e75           	rts

where offset 6 has "clrl %a1@(1)", which is an unaligned 32-bit long clear. GCC can emit several similar variants of this, for example unaligned 16-bit word clears, and possibly others.
Comment 1 Andreas Schwab 2021-01-11 18:04:28 UTC
How did you configure the compiler?
Comment 2 Fredrik Noring 2021-01-11 19:12:30 UTC
To obtain the object file I can run the command

m68k-unknown-linux-gnu-gcc -O1 -march=68000 -c -o address-error.o address-error.c

with a cross-compiler made using the Gentoo package sys-devel/crossdev having the target m68k-unknown-linux-gnu.
Comment 3 Andreas Schwab 2021-01-11 19:24:30 UTC
m68k-linux requires m68020+, you cannot combine that with -march=68000.
Comment 4 Fredrik Noring 2021-01-11 20:02:29 UTC
Well, GCC accepts -march=68000 as a valid option and so it doesn't seem to make sense that it then proceeds to generate code for something incompatible like the 68020. As far as I understand, other targets such as MIPS don't behave like that: a MIPS III compiler can generate code for MIPS I without problems, for instance.

What target(s) would you recommend for the compiler to (completely and without exceptions) honour the given -march=68000 option?
Comment 5 Andreas Schwab 2021-01-11 20:13:17 UTC
Anything but linux.
Comment 6 Fredrik Noring 2021-01-11 20:36:53 UTC
Then I would suggest it's a bug that GCC doesn't reject -march=68000
in combination with linux. Unsuspecting projects use this, and in fact
it almost works except for random crashes every now and then, which is
a grave quality problem to be sure.
Comment 7 Mikael Pettersson 2021-01-12 16:26:27 UTC
The correct target to use in this case is m68k-elf.
Comment 8 Fredrik Noring 2021-01-12 19:20:37 UTC
Thanks, Mikael. Users evidently take whatever m68k-* GCC they have at hand and
so 68000-projects therefore must have a special configure test to verify that
-march=68000 isn't broken with the user's choice of GCC. I must say I do think
it's quite wrong to blame the user for this problem.