Hi, I'm currently using gcc 4.2.4 to build uClinux for a 68000 target (68HC000 cpu). I've update my toolchain to newer tool versions but now gcc (4.6.4) is producing bad assembly for this target. I'm almost sure that it is producing only 68020 assembly code and/or ignoring the -m68000 switch (I checked that when specifying -m68000 or -m68020 gcc is producing the same assembly code). Here is a simple testcase (a line from the kernel where my system was hanging): C instruction (from 'proc_net_ns_init' function): [...] memcpy(netd->name, "net", 4); [...] 4.2.4 assembly output: [...] 60: 157c 006e 004d moveb #110,%a2@(77) 66: 157c 0065 004e moveb #101,%a2@(78) 6c: 157c 0074 004f moveb #116,%a2@(79) 72: 422a 0050 clrb %a2@(80) [...] 4.6.4 assembly output: [...] 42: 217c 6e65 7400 movel #1852142592,%a0@(77) 48: 004d [...] Since the opcode movel has an odd displacement, it is causing an address/bus error exception, halting the cpu. Another difference I've noticed while tracing the above issue, is the way parameters are placed in the stack for the function call: 4.2.4 assembly: [...] movel absolute_address,%sp- [...] 4.6.4 assembly: [...] moveaw value1,%a0 addal value2,%a0 movel %a0@,%sp- [...] This is not critical but at a first look, it look it has slower execution and produces larger code (is this correct?). Command line used in this test (from the kernel build): m68k-uclinux-gcc -m68000 -Wp,-MD,net/sunrpc/.rpc_pipe.o.d -isystem /usr/local/lib/gcc/m68k-uclinux/4.5.1/include -I/root/m68k/20120401/uClinux-dist/linux-3.x/arch/m68k/include -Iarch/m68k/include/generated -Iinclude -include /root/m68k/20120401/uClinux-dist/linux-3.x/include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -pipe -DUTS_SYSNAME=\"uClinux\" -D__uClinux__ -fomit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(rpc_pipe)" -D"KBUILD_MODNAME=KBUILD_STR(sunrpc)" -c -o fs/proc/proc_net.o fs/proc/proc_net.c Anyone knows what is the latest gcc version where code for 68000 is still ok? (I didn't want to go and build version by version until I find the one that's broken...) Regards, Luis Alves
config/m68k/linux.h: /* for 68k machines this only needs to be TRUE for the 68000 */ #undef STRICT_ALIGNMENT #define STRICT_ALIGNMENT 0 #undef M68K_HONOR_TARGET_STRICT_ALIGNMENT #define M68K_HONOR_TARGET_STRICT_ALIGNMENT 0
Thanks a lot Andreas, Changes those flags to true and it's working good now. Also a minor correction: I was trying to build gcc 4.6.3 (not 4.6.4). (I've changed status to RESOLVED-INVALID since this is not a bug but a configuration issue) Regards, Luis Alves
Thanks a lot Andreas, Changed those flags to true and it's working good now. Also a minor correction: I was trying to build gcc 4.6.3 (not 4.6.4). (I've changed status to RESOLVED-INVALID since this is not a bug but a configuration issue) Regards, Luis Alves
(In reply to comment #3) > (I've changed status to RESOLVED-INVALID since this is not a bug but a > configuration issue) I'm not so sure about that. For supported target triplets you are not supposed to have to edit any gcc sources to get a correct compiler.
I agree with that. I'll just leave it UNCONFIRMED until someone decides what to do with this.
The behaviour changed between gcc-4.2.4 (ok) and gcc-4.3.6 (bad).
gcc-4.3.x changed gcc/config.gcc: --- gcc-4.2.4/gcc/config.gcc 2008-03-13 20:11:43.000000000 +0100 +++ gcc-4.3.6/gcc/config.gcc 2011-02-25 00:02:14.000000000 +0100 ... -m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux with uClibc - tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/uclinux.h" - tm_defines="${tm_defines} MOTOROLA USE_GAS" - tmake_file=m68k/t-uclinux +m68k-*-uclinuxoldabi*) # Motorola m68k/ColdFire running uClinux + # with uClibc, using the original + # m68k-elf-based ABI + default_m68k_cpu=68020 + default_cf_cpu=5206 + tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/uclinux-oldabi.h" + tm_defines="${tm_defines} MOTOROLA=1" + tmake_file="m68k/t-floatlib m68k/t-uclinux" + use_fixproto=no + ;; +m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux + # with uClibc, using the new GNU/Linux-style + # ABI. + default_m68k_cpu=68020 + default_cf_cpu=5206 + tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h flat.h m68k/linux.h m68k/uclinux.h ./sysroot-suffix.h" + tm_defines="${tm_defines} MOTOROLA=1 UCLIBC_DEFAULT=1" + extra_options="${extra_options} linux.opt" + tmake_file="m68k/t-floatlib m68k/t-uclinux m68k/t-mlibs" use_fixproto=no ;; Upping the default m68k cpu to 020 is suspicious, but the real problem is the inclusion of m68k/linux.h in tm_files, as that disables strict-alignment support, even when compiling with an explicit -m68000 option. I don't know anthing about the uClinux m68k "old" and "new" ABIs, but it looks like you will get correct behaviour if you build for m68k-uclinuxoldabi --with-cpu=m68000.
Fallout from a deliberate ABI change in 4.3.x, see <http://gcc.gnu.org/ml/gcc-patches/2007-01/msg00773.html> and its followups. I don't like the way an existing target triplet was reassigned an entirely different meaning, but it's too late to do anything about that now. Configuring for m68k-uclinuxoldabi is the correct solution for gcc-4.3 and newer if you need m68000-compatible code. You can close this as invalid now.
Thanks Mikael, But... will I have any (future) problems if I just change the flags in the <config/m68k/linux.h> ? In a small test I've made that solutions seems to produce good code for the 68000 but I'm afraid I might end up with a 'crippled' gcc.
See the gcc-patches thread I referred to in #c8, gcc-4.3 also changed low-level ABI details, with the consequence that gcc-4.2 and gcc-4.3 generate incompatible code for m68k-uclinux. If you want 4.3 and newer to behave as 4.2 and older you should use m68k-uclinuxoldabi. Patching m68k/linux.h might work, but it's not a supported configuration.
I would be ok with changing linux.h to honor -mstrict-align, though m68k_return_in_memory would have to be left out. The default will of course continue to be -mno-strict-align.
(In reply to comment #10) > See the gcc-patches thread I referred to in #c8, gcc-4.3 also changed low-level > ABI details, with the consequence that gcc-4.2 and gcc-4.3 generate > incompatible code for m68k-uclinux. If you want 4.3 and newer to behave as 4.2 > and older you should use m68k-uclinuxoldabi. Patching m68k/linux.h might work, > but it's not a supported configuration. Just wanted to add that I use gcc to fully build a uClinux-dist (kernel+userland binaries) so it really doesn't bother me if the gcc >= 4.3 generates incompatible code with gcc-4.2. And I dare to say that this is the case for everyone using uClinux.
I've built gcc with the m68k/linux.h patched for the 68000 but it's not working as expected. As test I've used linux kernel 3.3 Results are compared to the use of gcc-4.2.4 vs gcc-4.6.3 (gcc-4.7.0 doesn't even build itself because of an ICE). (Using the same kernel configuration, only changed gcc version) Kernel Size: 4.2.4: 2158592 bytes 4.6.3: 2244608 bytes (around 4% increase) Using 4.2.4 kernel boots as expected and everything works fine. With 4.6.3 the kernel boots and after a few seconds starts a non-stop SPAM of BUGs: [...] BUG: scheduling while atomic: ksoftirqd/0/3/0x00000000 [...] BUG: scheduling while atomic: kthreadd/2/0x00000000 [...] BUG: scheduling while atomic: kworker/0:0/4/0x04000002 [...] Until eventually panics. Anyway, building gcc for target "m68k-uclinuxoldabi" is a bit awkward. I've tried to build and the message I got is that target will be removed soon. Also it would give a lot of work to integrate it with the existing tools because of the resulting prefix (binutils, elf2flt, ...). As of "gcc -m68000" not generating correct code for the 68000 I would still say that IT IS a gcc bug...
We really need a testcase for the issue raised in c#13. Without a reasonable testcase, there really isn't anything we can do.
Nothing we can do without a testcase.