Fails to build on powerpcspe because of inline assembly
Hello!
I'm currently bootstrapping GHC on powerpcspe (e500v2) which is a PowerPC architecture without an FPU but with signal processing extensions (hence SPE).
When building GHC on this architecture, it detects the host architecture as powerpc-linux-gnuspe or short "powerpc" which works most of the time.
However, GHC contains some inline assembly in rts/StgCRunAsm.s which uses FPU instructions not available on e500v2 CPUs resulting in assembler error, here with GHC 7.10.3:
"inplace/bin/ghc-stage1" -optc-fno-stack-protector -optc-Wall -optc-Wextra -optc-Wstrict-prototypes -optc-Wmissing-prototypes -optc-Wmissing-declarations -optc-Winline -optc-Waggregate-return -optc-Wpointer-arith -optc-Wmissing-noreturn -optc-Wnested-externs -optc-Wredundant-decls -optc-Iincludes -optc-Iincludes/dist -optc-Iincludes/dist-derivedconstants/header -optc-Iincludes/dist-ghcconstants/header -optc-Irts -optc-Irts/dist/build -optc-DCOMPILING_RTS -optc-DUSE_LIBFFI_FOR_ADJUSTORS -optc-fno-strict-aliasing -optc-fno-common -optc-Irts/dist/build/autogen -optc-O2 -optc-fomit-frame-pointer -optc-g -optc-DRtsWay=\"rts_v\" -optc-w -static -H32m -O -lffi -optl-pthread -lffi -optl-pthread -Iincludes -Iincludes/dist -Iincludes/dist-derivedconstants/header -Iincludes/dist-ghcconstants/header -Irts -Irts/dist/build -DCOMPILING_RTS -this-package-key rts -dcmm-lint -i -irts -irts/dist/build -irts/dist/build/autogen -Irts/dist/build -Irts/dist/build/autogen -O2 -c rts/StgCRun.c -o rts/dist/build/StgCRun.o
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/tmp/ghcf20d_0/ghc_1.s: Assembler messages:
/tmp/ghcf20d_0/ghc_1.s:24:0: Error: unrecognized opcode: `stfd'
(...)
/tmp/ghcf20d_0/ghc_1.s:67:0: Error: unrecognized opcode: `lfd'
/tmp/ghcf20d_0/ghc_1.s:68:0: Error: unrecognized opcode: `lfd'
/tmp/ghcf20d_0/ghc_1.s:69:0: Error: unrecognized opcode: `lfd'
rts/ghc.mk:236: recipe for target 'rts/dist/build/StgCRun.o' failed
make[3]: *** [rts/dist/build/StgCRun.o] Error 1
Makefile:71: recipe for target 'all' failed
make[2]: *** [all] Error 2
make[2]: Leaving directory '/usr/src/ghc-7.10.3'
dh_auto_build: make -j1 returned exit code 2
debian/rules:109: recipe for target 'override_dh_auto_build' failed
make[1]: *** [override_dh_auto_build] Error 2
make[1]: Leaving directory '/usr/src/ghc-7.10.3'
debian/rules:47: recipe for target 'binary-arch' failed
make: *** [binary-arch] Error 2
(sid2-powerpcspe-sbuild)root@atlantis:/usr/src/ghc-7.10.3#
This can be verified by commenting out the assembly which will make the above compile command execute without any problems. Trying to continue compiling GHC will still fail with:
"inplace/bin/ghc-stage1" -static -H32m -O -lffi -optl-pthread -lffi -optl-pthread -Iincludes -Iincludes/dist -Iincludes/dist-derivedconstants/header -Iincludes/dist-ghcconstants/header -Irts -Irts/dist/build -DCOMPILING_RTS -this-package-key rts -dcmm-lint -i -irts -irts/dist/build -irts/dist/build/autogen -Irts/dist/build -Irts/dist/build/autogen -O2 -c rts/HeapStackCheck.cmm -o rts/dist/build/HeapStackCheck.o
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/tmp/ghcca51_0/ghc_3.s: Assembler messages:
/tmp/ghcca51_0/ghc_3.s:525:0: Error: unrecognized opcode: `lfs'
/tmp/ghcca51_0/ghc_3.s:538:0: Error: unrecognized opcode: `lfd'
/tmp/ghcca51_0/ghc_3.s:592:0: Error: unrecognized opcode: `stfs'
/tmp/ghcca51_0/ghc_3.s:604:0: Error: unrecognized opcode: `stfd'
rts/ghc.mk:236: recipe for target 'rts/dist/build/HeapStackCheck.o' failed
make[3]: *** [rts/dist/build/HeapStackCheck.o] Error 1
Makefile:71: recipe for target 'all' failed
make[2]: *** [all] Error 2
make[2]: Leaving directory '/usr/src/ghc-7.10.3'
dh_auto_build: make -j1 returned exit code 2
debian/rules:109: recipe for target 'override_dh_auto_build' failed
make[1]: *** [override_dh_auto_build] Error 2
make[1]: Leaving directory '/usr/src/ghc-7.10.3'
debian/rules:47: recipe for target 'binary-arch' failed
make: *** [binary-arch] Error 2
(sid2-powerpcspe-sbuild)root@atlantis:/usr/src/ghc-7.10.3#
So, there is obviously more assembly code that needs to be disabled on powerpcspe.
For that, I suggest testing whether the compiler sets __NO_FPRS__which is only set on powerpc hosts without FP registers:
root@atlantis:~# echo | gcc -E -dM -|grep -i FP
#define __NO_FPRS__ 1
root@atlantis:~# dpkg --print-architecture
powerpcspe
root@atlantis:~# uname -m
ppc
root@atlantis:~#
For reference, on a real powerpc host, the output is as follows:
(sid_powerpc-dchroot)glaubitz@partch:~$ echo | gcc -E -dM -|grep -i FP
#define __FP_FAST_FMAF 1
#define __FP_FAST_FMA 1
(sid_powerpc-dchroot)glaubitz@partch:~$ dpkg --print-architecture
powerpc
(sid_powerpc-dchroot)glaubitz@partch:~$ uname -m
ppc
(sid_powerpc-dchroot)glaubitz@partch:~$
If you need any more input, please let me know.
For reference, the list of supported instructions on e500(v2) CPUs can be found here:
http://www.nxp.com/files/32bit/doc/ref_manual/E500CORERM.pdf (page 3-66 or 196)
Adrian