ARM BE8 Support

Is there any support in LLVM for building code targeting the ARM BE8 architecture? e.g. the equivalent of armeb-linux-gnueabi in GCC using the -mbe8 argument? If so, how do I go about using it?

Many Thanks for any advice you can offer.

The only reference to it in llvm is a FIXME (llvm-project/ARMTargetParser.h at main · llvm/llvm-project · GitHub). There’s no references elsewhere, nothing in lld in particular.

From what I read this is a linker option, so you could use a linker that supports the flag and pass it by giving -Wl,-mbe8 to clang. I’m not sure that it needs any special compiler support.

Thanks for the quick response. For GCC -mbe8 is both a compile time flag and link time flag, but that may be just because it doesn’t target an intermediate language like clang/llvm. I would understand that maybe that the front-end (apologies if my terminology is wrong) generating the IL from the source would not need to know about BE8. But I would expect that the back-end (where IL is converted to .o files) would?

Looking at the GCC docs:
-mbe8
-mbe32

When linking a big-endian image select between BE8 and BE32 formats. The option has no effect for little-endian images and is ignored. The default is dependent on the selected target architecture. For ARMv6 and later architectures the default is BE8, for older architectures the default is BE32. BE32 format has been deprecated by ARM.

BE32 is used in Arm architectures prior to ARMv6. For example the arm7tdmi and arm926ej-s. Practically all Arm CPUs running linux will use BE8. In this case compiling with clang with big-endian output but without the -mbe8 flag will give you the right relocatable object. LLD doesn’t support big-endian for Arm, either BE8 or BE32, at the moment. You should be able to use GNU arm-linux-gnueabihf-ld.bfd as the linker with clang -fuse-ld=bfd -Wl,–be8 (I think -mbe8 just passes through --be8 to the linker).

As I understand it there is very little difference to the compiler for BE8 and BE32. In both cases the compiler outputs a big-endian ELF relocatable object file. With ELF file, Instructions and Data both big-endian.

The difference is that at link time, for BE8 a linker must endian reverse the instructions to little-endian. So the output ELF file is big-endian, the data is big-endian but the instructions are little-endian.

Thanks very much for your advice. I have now been able to build LLVM/CLANG from source and use it to cross compile a source file to an object file for ARMBE. Then used armeb-linux-gnueabi-ld to link to create a simple binary with -mbe8 and it seems to work just fine!

Are there any parameters for CMake when building LLVM which can be used to set the default linker to use? The default LDFLAGS and the default SYSROOT?

When building clang you can choose the default linker Building LLVM with CMake — LLVM 16.0.0git documentation

As far as I can see there are no CMake options for default sysroot and ldflags. There is a way using Clang Compiler User’s Manual — Clang 16.0.0git documentation that can come close to this at runtime though.

It seems the linker option may affect the linker used when building clang, rather than the linker the resulting clang uses? In any case, clang no longer builds when I set that.

However, the runtime options should work marvelously for me! Thanks so much for all your help. You’ve all saved me a huge amount of time!