Hi there, Inspired by the recent FOSDEM keynote, I've tried to write an LLVM backend for the STM8 microcontroller platform. The STM8S-Discovery evaluation board [1] has been handed out for free or is sold dirt- cheap, but there is no Open Source cross-compiler for it. The available ST assembler, linker and USB flash programmer are closed- source Windows binaries. And the compiler vendor I contacted for an evaluation license has failed to react at all. So, I was hoping to piece together an STM8 backend for LLVM, for Clang to be able to compile C code into STM8 assembler code that - as a first step - I might be able to use with the ST assembler on some Windows box and transfer it to the board there. Here's what I've put together so far: http://repo.or.cz/w/llvm/stm8.git http://repo.or.cz/w/clang/stm8.git The first issue I stumbled upon was that the Program Counter register is 24 bits. It seems that despite having been discussed in the past [2], value type i24 was never added. On my branch I did so and, due to ordering assumptions, had to adjust ~30 type enum values in both files [3]. Would such a binary-incompatible change be acceptable for trunk at all? Further, as pointer width I chose 16 bits since there currently seems to be no way to distinguish between near and far pointers? Anyway, I've put together enough skeleton code to successfully compile, but on Mac OS X v10.5 ppc host this is what I get: $ Debug+Asserts/bin/clang -ccc-host-triple stm8-unknown-elf ../hello.c -S -o ../hello.s 0 clang 0x0168c4f0 llvm::SearchForAddressOfSpecialSymbol(char const*) + 448 1 clang 0x0168cc8c llvm::sys::RunInterruptHandlers() + 456 2 libSystem.B.dylib 0x9422d9fc _sigtramp + 68 3 clang 0x0159692c std::_Rb_tree<void const*, std::pair<void const* const, llvm::Pass*>, std::_Select1st<std::pair<void const* const, llvm::Pass*> >, std::less<void const*>, std::allocator<std::pair<void const* const, llvm::Pass*> > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<void const* const, llvm::Pass*> const&) + 132 4 clang 0x0f1c1cc0 std::_Rb_tree<void const*, std::pair<void const* const, llvm::Pass*>, std::_Select1st<std::pair<void const* const, llvm::Pass*> >, std::less<void const*>, std::allocator<std::pair<void const* const, llvm::Pass*> > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<void const* const, llvm::Pass*> const&) + 230863896 Stack dump: 0. Program arguments: /Users/andreas/STM8S-Discovery/llvm-stm8/Debug +Asserts/bin/clang -cc1 -triple stm8-unknown-elf -S -disable-free - main-file-name hello.c -mrelocation-model static -mdisable-fp-elim - mconstructor-aliases -target-linker-version 85.2.1 -momit-leaf-frame- pointer -resource-dir /Users/andreas/STM8S-Discovery/llvm-stm8/Debug +Asserts/bin/../lib/clang/2.9 -ferror-limit 19 -fmessage-length 274 - fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics -o ../ hello.s -x c ../hello.c 1. <eof> parser at end of file clang: error: unable to execute command: Bus error clang: error: clang frontend command failed due to signal 1 (use -v to see invocation) Same for stm8-unknown-none. Configured with --enable- targets=host,stm8. (It still works for the default Darwin/ppc target.) I'm fairly sure there's things I haven't implemented yet but I'm missing an assertion or error message as hint where to continue. Neither printf()s nor gdb breakpoints in the above llvm::SearchForAddressOfSpecialSymbol() are reached. Any hint what's going wrong or how to debug? Thanks! Regards, Andreas [1] http://www.st.com/stm8s-discovery [2] http://lists.cs.uiuc.edu/pipermail/llvmdev/2008-November/018663.html [3] http://repo.or.cz/w/llvm/stm8.git/commitdiff/79de4e74e2bc33894cfef4487be06e4005a1a7a0
On Sun, Feb 20, 2011 at 4:23 PM, Andreas Färber <andreas.faerber at web.de> wrote:> Hi there, > > Inspired by the recent FOSDEM keynote, I've tried to write an LLVM > backend for the STM8 microcontroller platform. The STM8S-Discovery > evaluation board [1] has been handed out for free or is sold dirt- > cheap, but there is no Open Source cross-compiler for it. The > available ST assembler, linker and USB flash programmer are closed- > source Windows binaries. And the compiler vendor I contacted for an > evaluation license has failed to react at all. So, I was hoping to > piece together an STM8 backend for LLVM, for Clang to be able to > compile C code into STM8 assembler code that - as a first step - I > might be able to use with the ST assembler on some Windows box and > transfer it to the board there. > > Here's what I've put together so far: > http://repo.or.cz/w/llvm/stm8.git > http://repo.or.cz/w/clang/stm8.git > > The first issue I stumbled upon was that the Program Counter register > is 24 bits. It seems that despite having been discussed in the past > [2], value type i24 was never added. On my branch I did so and, due to > ordering assumptions, had to adjust ~30 type enum values in both files > [3]. Would such a binary-incompatible change be acceptable for trunk > at all?LLVM doesn't do binary compatibility outside of the representation used in bitcode files, so that isn't an issue. That said, if the only 24-bit register is the program counter, you could probably get away with pretending it's a 32-bit register.> Further, as pointer width I chose 16 bits since there currently seems > to be no way to distinguish between near and far pointers?LLVM doesn't support distinguishing between near and far pointers. Depending on how much work you want to put in and what exactly you're trying to build, you might be able to get away with just pretending all pointers are near and implementing __builtin_stm8_far_loadn() and __builtin_stm8_far_storen() intrinsics, though.> Anyway, I've put together enough skeleton code to successfully > compile, but on Mac OS X v10.5 ppc host this is what I get: > > $ Debug+Asserts/bin/clang -ccc-host-triple stm8-unknown-elf ../hello.c > -S -o ../hello.s > 0 clang 0x0168c4f0 > llvm::SearchForAddressOfSpecialSymbol(char const*) + 448 > 1 clang 0x0168cc8c llvm::sys::RunInterruptHandlers() + 456 > 2 libSystem.B.dylib 0x9422d9fc _sigtramp + 68 > 3 clang 0x0159692c std::_Rb_tree<void const*, > std::pair<void const* const, llvm::Pass*>, > std::_Select1st<std::pair<void const* const, llvm::Pass*> >, > std::less<void const*>, std::allocator<std::pair<void const* const, > llvm::Pass*> > >::_M_insert(std::_Rb_tree_node_base*, > std::_Rb_tree_node_base*, std::pair<void const* const, llvm::Pass*> > const&) + 132 > 4 clang 0x0f1c1cc0 std::_Rb_tree<void const*, > std::pair<void const* const, llvm::Pass*>, > std::_Select1st<std::pair<void const* const, llvm::Pass*> >, > std::less<void const*>, std::allocator<std::pair<void const* const, > llvm::Pass*> > >::_M_insert(std::_Rb_tree_node_base*, > std::_Rb_tree_node_base*, std::pair<void const* const, llvm::Pass*> > const&) + 230863896 > Stack dump: > 0. Program arguments: /Users/andreas/STM8S-Discovery/llvm-stm8/Debug > +Asserts/bin/clang -cc1 -triple stm8-unknown-elf -S -disable-free - > main-file-name hello.c -mrelocation-model static -mdisable-fp-elim - > mconstructor-aliases -target-linker-version 85.2.1 -momit-leaf-frame- > pointer -resource-dir /Users/andreas/STM8S-Discovery/llvm-stm8/Debug > +Asserts/bin/../lib/clang/2.9 -ferror-limit 19 -fmessage-length 274 - > fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics -o ../ > hello.s -x c ../hello.c > 1. <eof> parser at end of file > clang: error: unable to execute command: Bus error > clang: error: clang frontend command failed due to signal 1 (use -v to > see invocation) > > Same for stm8-unknown-none. Configured with --enable- > targets=host,stm8. (It still works for the default Darwin/ppc target.) > > I'm fairly sure there's things I haven't implemented yet but I'm > missing an assertion or error message as hint where to continue. > Neither printf()s nor gdb breakpoints in the above > llvm::SearchForAddressOfSpecialSymbol() are reached. > > Any hint what's going wrong or how to debug? Thanks!Try valgrind? That looks like some sort of memory corruption bug. -Eli
Am 21.02.2011 um 02:44 schrieb Eli Friedman:> On Sun, Feb 20, 2011 at 4:23 PM, Andreas Färber <andreas.faerber at web.de > > wrote: >> The first issue I stumbled upon was that the Program Counter register >> is 24 bits. [...] > > [...] if the only > 24-bit register is the program counter, you could probably get away > with pretending it's a 32-bit register. > >> Further, as pointer width I chose 16 bits since there currently seems >> to be no way to distinguish between near and far pointers? > > LLVM doesn't support distinguishing between near and far pointers. > Depending on how much work you want to put in and what exactly you're > trying to build, you might be able to get away with just pretending > all pointers are near and implementing __builtin_stm8_far_loadn() and > __builtin_stm8_far_storen() intrinsics, though.The example C code uses far pointers, e.g., to set up interrupt vectors: typedef void @far (*interrupt_handler_t)(void); struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; }; So I do need support for 24-bit pointers in the Clang frontend, in order for the struct to fill four bytes here. Not sure how intrinsics could help there. I assume that @far is a non- standard keyword. Is it possible to derive a new language standard similar to GCC's --std=gnu99 to handle such extensions? The only guide I could find was on how to add an attribute... Andreas
Am 21.02.2011 um 02:44 schrieb Eli Friedman:> On Sun, Feb 20, 2011 at 4:23 PM, Andreas Färber <andreas.faerber at web.de > > wrote: >> [...] I've put together enough skeleton code to successfully >> compile, but on Mac OS X v10.5 ppc host this is what I get: >> >> $ Debug+Asserts/bin/clang -ccc-host-triple stm8-unknown-elf ../ >> hello.c >> -S -o ../hello.s >> 0 clang 0x0168c4f0 >> llvm::SearchForAddressOfSpecialSymbol(char const*) + 448 >> 1 clang 0x0168cc8c llvm::sys::RunInterruptHandlers() + >> 456 >> 2 libSystem.B.dylib 0x9422d9fc _sigtramp + 68 >> 3 clang 0x0159692c std::_Rb_tree<void const*, >> std::pair<void const* const, llvm::Pass*>, >> std::_Select1st<std::pair<void const* const, llvm::Pass*> >, >> std::less<void const*>, std::allocator<std::pair<void const* const, >> llvm::Pass*> > >::_M_insert(std::_Rb_tree_node_base*, >> std::_Rb_tree_node_base*, std::pair<void const* const, llvm::Pass*> >> const&) + 132 >> 4 clang 0x0f1c1cc0 std::_Rb_tree<void const*, >> std::pair<void const* const, llvm::Pass*>, >> std::_Select1st<std::pair<void const* const, llvm::Pass*> >, >> std::less<void const*>, std::allocator<std::pair<void const* const, >> llvm::Pass*> > >::_M_insert(std::_Rb_tree_node_base*, >> std::_Rb_tree_node_base*, std::pair<void const* const, llvm::Pass*> >> const&) + 230863896 >> Stack dump: >> 0. Program arguments: /Users/andreas/STM8S-Discovery/llvm-stm8/ >> Debug >> +Asserts/bin/clang -cc1 -triple stm8-unknown-elf -S -disable-free - >> main-file-name hello.c -mrelocation-model static -mdisable-fp-elim - >> mconstructor-aliases -target-linker-version 85.2.1 -momit-leaf-frame- >> pointer -resource-dir /Users/andreas/STM8S-Discovery/llvm-stm8/Debug >> +Asserts/bin/../lib/clang/2.9 -ferror-limit 19 -fmessage-length 274 - >> fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics -o ../ >> hello.s -x c ../hello.c >> 1. <eof> parser at end of file >> clang: error: unable to execute command: Bus error >> clang: error: clang frontend command failed due to signal 1 (use -v >> to >> see invocation) >> >> Same for stm8-unknown-none. Configured with --enable- >> targets=host,stm8. (It still works for the default Darwin/ppc >> target.) >> >> I'm fairly sure there's things I haven't implemented yet but I'm >> missing an assertion or error message as hint where to continue. >> Neither printf()s nor gdb breakpoints in the above >> llvm::SearchForAddressOfSpecialSymbol() are reached. >> >> Any hint what's going wrong or how to debug? Thanks! > > Try valgrind? That looks like some sort of memory corruption bug.Not being familiar with valgrind, I went on to implement some random parts of the backend and it seems the above error was resolved by overriding the remaining get*Info() methods of LLVMTargetMachine. I've filed a ticket: http://llvm.org/bugs/show_bug.cgi?id=9334 Andreas