TL;DR: I want a modern C/C++ toolchain for Propeller 2 that compiles to native instructions directly, so I made one, on the shoulders of giants. It lives here: https://github.com/ne75/p2llvm
First things first that I think is important: I'm not a computer scientist and I've never studied compilers. I'm just an eager EE who really likes Propeller (and Propeller 2!). I've probably done some dumb things in this project. If I did, let me know, I want to learn.
Second things second, the immediate question I'm sure everyone will have is: "Why are you writing another compiler for Propeller 2?" I will answer that with a bit of a rant.
Propeller (and Propeller 2) are power chips that can do A LOT of a small, simple, and power efficient package. The high flexibility allows it to be used in a very wide variety of applications without having to include a lot of support hardware. As such, it should be used widely in industry, but it's not (I work in aerospace where a multicore chip like this would be extremely useful, yet no-one I work with has even heard of it). I think there are several reasons for its lack of adoption, but one of the biggest ones is the lack of a modern toolchain and lack of modern language support. Propeller 1 addressed this with PropGCC, but it was several years after the release of Propeller 1 and built around GCC 4, which is outdated in the modern world. Additionally, there appears to be a game of chicken going on between Parallax and the Propeller community, where Parallax is focused on Spin and the development of Propeller hardware (which is where their focus should be right now), so they are hoping the community steps up (again) and develops the tools they desire, while the community is hoping to see something official come out and not put too much effort into developing something that might be pushed aside by an "official" toolchain. (As a general note, I'm not trying to start a debate about that here, it's just my observation). As a result, we have a few toolchains that are not quite good enough by industry standards (sorry to those who work on them, I know these tools take a lot of work and I do appreciate all the work that has been put in so far) that don't fully support C/C++ (like fastspin), and some that do have full C++ support, but do not support the full functionality of Propeller hardware (like RISCV-P2), and some in between, like p2gcc, which is more or less a bandaid for make use of PropGCC for Propeller 2 (p2gcc also doesn't support the most "standard" P2 library which makes code developed with it not very portable). While these are excellent tools to demonstrate the capabilities of the hardware, they make developing scalable products difficult if not impossible. There has also been several requests for various language support (microPython, Arduino, Rust, etc), all of which will require developing a compiler for Propeller's architecture.
This project aims to solve all of the problems listed above. LLVM is a modern toolchain used by many companies around the world, developed at Berkley a while back and supported primarily by Apple at this point. It has an intermediate representation that frontends (such as clang for C/C++/Objective C) compile down to, and target specific backends the compile the IR down to target machine instructions. The majority of the work to add a new backend is baked into LLVM as it, and the P2 target is another backend (same as the existing x86, AArch64, MIPS, AVR, MSP430, etc etc backends) that provides basic information (such as registers, instruction encoding, and ABI information) to connect the dots between the various compiler passes that LLVM does. Once complete, it will provide access to the full functionality of several languages for Propeller.
I am developing this project with two main goals in mind:
1. create as much backward compatibility as possible with PropGCC projects. This won't be completely possible due to a few differences in Propeller 1 to Propeller 2 architecture, but the hope is that porting those P1 projects to P2 will be easy. I don't want to rewrite a ton of my existing code.
2. provide a tool that the community finds useful, regardless of adoption by Parallax as a formal tool. I know there's been some gripe on forums about the community's hard work not being adopted as much as people hope, but I am not pushing this for formal adoption. We'll just see what happens.
So without further ado, here it is: https://github.com/ne75/p2llvm
. I went ahead and actually copied the entire LLVM repo (rather than making a fork) to not copy over the 1M+ commits in the main LLVM repo, but maybe that's not a good idea--I can always fix it later.
What you can do with it:
- compile and link C/C++ programs using the p2 target in clang and lld into elf binaries for loading onto a P2 board.
- disassemble compiled binaries using llvm-objdump
- generate printed PASM listings. These aren't perfectly formatted so they won't immediately compile with spin tools, but you can at least see the instructions being generated.
What I've tested so far:
- basic math operations
- flow control and branching
- function calling
- clock configuration
- starting cogs with parameters
- variable argument functions
- basic C++ classes.
What I still need to test:
- dynamic memory allocation
- more complicated programs with complex flow control and complex loops
- inheritance and virtual functions (C++)
- A lot of other things I can't immediately think of.
What still needs implementation
- the majority of instructions
- more hardware control (smart pins, streamer, etc etc)
- more efficient use of cog/lut RAM
- a math library
Over the next few weeks I'll try to put together some demoes of what we can do with it. This will also help flesh out the remaining functionality needed. with 400+ instructions, it will take a while to add them all. The current tests folder was really just a scratch pad to test out features and find bugs. First one I expect to do is my LVDS display driver I wrote a few months back but was never able to really use in the project I was designing it for. If there's something anyone would like to see demoed, let me know, I need ideas.
I'd also appreciate any pointers on what is our current "standard" P2 library, so that I can implement/port a version for this compiler.
What I'm currently not planning on doing is porting the entire C standard library. That's a big undertaking and I need to learn a lot more about the standard and what I can steal from PropGCC and what needs to be fundamentally changed. I did however compile the stdlib portion of the C standard library. I haven't tested it yet but it does compile.
I encourage everyone to read the wiki.md to see roughly how this works, and more importantly, what doesn't work. This whole project is a heavy work in progress. Expect bugs, missing features, or things that just don't seem right. I'll keep working on it as I can, burning down the todo list and continuously adding to it. If you want to work on it, feel free! just make a PR. If you see something that's weird, doesn't make sense, or doesn't work, please let me know so I can take a look and fix it. Eventually I'll write up details on how LLVM is actually structured, but that's an entirely separate project.