3

I have an empty program in LLVM IR:

define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
    ret i32 0
}

I'm cross-compiling it on Intel x86-64 Windows for ARM Linux using ELLCC, with the following command:

ecc++ hw.ll -o hw.o -target arm-linux-engeabihf

It completes without errors and generates an ELF binary.

When I take the binary to a Raspberry Pi Model B+ (running Raspbian), I get only the following error:

Illegal instruction

I don't know how to tell what's wrong from the disassembled code. I tried other ARM Linux targets but the behavior was the same. What's wrong?


The exact same file builds, links and runs fine for other targets like i386-linux-eng, x86_64-w64-mingw32, etc (that I could test on), again using the ELLCC toolchain.


Assuming the library and startup code isn't at fault, this is what the disassembly of main itself looks like:

.text:00010188  e24dd008    sub sp, sp, #8
.text:0001018c  e3002000    movw r2, #0
.text:00010190  e58d0004    str r0, [sp, #4]
.text:00010194  e1a00002    mov r0, r2
.text:00010198  e58d1000    str r1, [sp]
.text:0001019c  e28dd008    add sp, sp, #8
.text:000101a0  e12fff1e    bx lr
Notlikethat
  • 20,095
  • 3
  • 40
  • 77
Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
  • What version of ELLCC are you using? Can you use gdb (or the ecc-gdb supplied with ELLCC) to debug and see where the illegal instruction is? – Richard Pennington May 14 '15 at 17:03

1 Answers1

3

I'd guess it's choking on the movw at 0x0001018c. The movw/movt encodings which can handle full 16-bit immediate values first appeared in the ARMv6T2 version of the architecture - the ARM1176 in the original Pi models predates that, only supporting original ARMv6*.

You need to tell the compiler to generate code appropriate to the thing you're running on - I don't know ELLCC, but I'd guess from this it's fairly modern and up-to-date and thus defaulting to something newer like ARMv6T2 or ARMv7. Otherwise, it's akin to generating code for a Pentium and hoping it works on an 80486 - you might be lucky, you might not. That said, there's no good reason it should have chosen that encoding in the first place - it's not as if 0 can't be encoded in a 'classic' mov instruction...

The decadent option, however, would be to consider this a perfect excuse to replace the Pi with a Pi 2 - the Cortex-A7s in that are nice capable ARMv7 cores ;)

* Lies for clarity. I think 1176 might actually be v6K, but that's irrelevant here. I'm not sure if anything actually exists as plain ARMv6, and all the various architecture extensions are frankly a hideous mess

Notlikethat
  • 20,095
  • 3
  • 40
  • 77
  • 2
    You're right, ELLCC is generating code for an ARMv7 by default. This is the config file: http://ellcc.org/viewvc/svn/ellcc/trunk/libecc/config/arm-linux-engeabihf?view=markup It would be possible to make a config for ARMv6, but I haven't gotten to it yet. – Richard Pennington May 14 '15 at 17:19
  • @RichardPennington I see. Is there any easy way to make ELLCC (latest version) target ARMv6? I'm assuming it's not just a matter of me writing a new config file (I'm guessing the object files under `/libecc/lib/arm-linux-engeabihf` are ARMv7-specific and would have to be rebuilt), am I correct? – Theodoros Chatzigiannakis May 14 '15 at 19:53
  • @Theodoros Actually it shouldn't be too hard. What I would do is copy arm-linux-engeabihf to something like armv6-linux-engeabihf and modify it. Then go to the libecc directory and type "make armv6-linux-engeabihf". That should make what you need under libecc/lib/armv6-linux-engeabihf. I'll try it when I get out of my day job today. – Richard Pennington May 14 '15 at 20:04
  • 1
    @TheodorosChatzigiannakis I added a config file and was able to build the library as I described. I haven't tried it on a Raspberry B+ yet, though. http://ellcc.org/viewvc/svn/ellcc/trunk/libecc/config/armv6-linux-engeabihf?view=markup – Richard Pennington May 14 '15 at 21:05
  • @TheodorosChatzigiannakis Sorry. The first update of the config file was incorrect. I uploaded a new version. The library built correctly but the linker arguments were wrong. – Richard Pennington May 14 '15 at 21:19
  • @RichardPennington Thank you for taking the time to do this! I'll make sure to try it out in the next release, as soon as I get back to the project I was working on. – Theodoros Chatzigiannakis May 15 '15 at 20:05