A survey of C compilers available for P2
ersmith
Posts: 6,053
There is no complete C solution available yet for the P2, but there are a number of incomplete/in progress ones. This is an overview of what's available as of the date of writing (2019-04-07).
P2GCC
Probably the most popular C solution for P2 right now. Works by converting the P1 output of PropGCC to P2 instructions. The standard library has not all been ported yet, and the default front end doesn't support C++ (but since PropGCC does have C++ this should be easy to change).
FASTSPIN
Homegrown C (and Spin and BASIC) compiler for P2. The C support is still incomplete and buggy. Optimizer is not up to GCC standards on generic code, but does have P2 specific optimizations. Noteworthy for its ability to seamlessly interoperate with Spin and BASIC functions.
RISC-V JIT
Can support any RISC-V compiler, but I've been using GCC. Works by converting RISC-V instructions to P2 instructions at run time. Many P2 specific features (including COGINIT of arbitrary P2 code) are supported via custom RISC-V instructions. A full newlib standard library is available, but is a bit awkward to use (there's no package giving P2 board support). Documentation is sparse.
ZOG for P2
GCC compiler to ZPU bytecode, which is then interpreted on the P2. A full newlib standard library is available. P2 specific registers like OUTA are accessible, but there isn't any other P2 support yet (the original ZOG for P1 did have COGINIT, so this should be easy to add).
CATALINA
The new kid on the block. P2 version not yet released, but sounds very promising. Based on the LCC compiler, so code is probably not as fast as GCC.
P2GCC
URL: https://github.com/davehein/p2gcc Type: Native code Standard Library: incomplete P2 support: full (inline and out-of-line assembly) C support: full C1x C++ support: not yet, should be easy to add
Probably the most popular C solution for P2 right now. Works by converting the P1 output of PropGCC to P2 instructions. The standard library has not all been ported yet, and the default front end doesn't support C++ (but since PropGCC does have C++ this should be easy to change).
FASTSPIN
URL: https://github.com/totalspectrum/spin2gui Type: Native code Standard Library: incomplete P2 support: full (inline and out-of-line assembly) C support: eventually C99, but incomplete at present C++ support: no
Homegrown C (and Spin and BASIC) compiler for P2. The C support is still incomplete and buggy. Optimizer is not up to GCC standards on generic code, but does have P2 specific optimizations. Noteworthy for its ability to seamlessly interoperate with Spin and BASIC functions.
RISC-V JIT
URL: https://github.com/totalspectrum/riscvemu Type: JIT compiler Standard Library: complete, but awkward to use P2 support: partial, via custom Risc-V instructions C support: full C1x C++ support: yes
Can support any RISC-V compiler, but I've been using GCC. Works by converting RISC-V instructions to P2 instructions at run time. Many P2 specific features (including COGINIT of arbitrary P2 code) are supported via custom RISC-V instructions. A full newlib standard library is available, but is a bit awkward to use (there's no package giving P2 board support). Documentation is sparse.
ZOG for P2
URL: https://github.com/totalspectrum/zog Type: XBYTE interpreter or JIT compiler Standard Library: complete P2 support: limited (memory mapped registers) C support: full C1x C++ support: yes
GCC compiler to ZPU bytecode, which is then interpreted on the P2. A full newlib standard library is available. P2 specific registers like OUTA are accessible, but there isn't any other P2 support yet (the original ZOG for P1 did have COGINIT, so this should be easy to add).
CATALINA
URL: https://sourceforge.net/projects/catalina-c/ Type: Native code or CMM interpreter Standard Library: not released yet P2 support: yes, via out of line assembly C support: full C89, some C99 features C++ support: no
The new kid on the block. P2 version not yet released, but sounds very promising. Based on the LCC compiler, so code is probably not as fast as GCC.
Comments
XXTEA
This is the xxtea decompression benchmark.
Speed is cycles to decompress the sample (so lower is better).
Size is the size of the btea function.
The GCC results all use -Os; fastspin uses -O2.
FFTBENCH
Time to complete in microseconds at 80 MHz (so lower is better).
Size was difficult to compute, because different compilers inlined
different functions, so I have left it out.
DHRYSTONE
This is the dhyrstone 1.1 benchmark.
Speed is dhrystones/second with an 80 MHz system clock. Higher is better.
Size gives the total size in bytes of the Proc_n and Func_n functions.
For this benchmark I've tried some different optimization options to see what difference they make.
Overall the native compilers (fastspin and p2gcc) are the fastest and produce pretty similar results. riscvjit has more variable results (probably depending on exactly where things end up in its code cache), sometimes matching the native compilers for speed but sometimes a bit slower. The emulators are quite a bit further back. The ZPU xbyte interpreter is noticeably faster than the RISC-V interpreter (which does not use xbyte, because RISC-V instructions are 32 bits long). The ZPU JIT compiler is pretty much the same speed as xbyte, and with some optimization work could probably surpass it.
Really want to get MPEG and PNG decoding (and encoding) going. I'm sure there are C examples of this out there...
* Supports clean in-line assembly
to the fastpin feature list.
On a P2, I rank that as a vitally important feature, as being able to intermix assembler and any HLL, easily, is a key differentiation.
GCC scores a clear 'F' there.
The numbers you quote, also suggest those P2 specific optimizations already have fastspin in front of gcc, in some cases.
Your JIT effort is proving remarkably fruitful.
The speed is quite good, and it is what allows Python to start to have a pulse on P2 already.
Have you tried Blockly-Generated-C into any of your C flows yet ? How close is that to being supported ?
Yes, I'd like to. I've had some other projects distracting me, but eventually I do plan to come back to fastspin/C.
No. Personally I never use Blockly, and I don't think there's much overlap between Blockly users and P2-ES users. I think most developers who have engineering samples are interested in a different class of tool.
Whenever Blockly produces standard C code any of the GCC compilers will certainly handle it. The Propeller specific code that Blockly produces is another matter, but porting it will "just" be a matter of fixing up the libraries to work on P2. Which probably isn't much fun, so it may be difficult to find a volunteer for that.
thank you for your comprehensive and concise overview of C compilers.
This really helps non-specialist observers like me understand the state-of-play.
What I really cannot understand is why there is so much duplicated effort.
I understand competition is good, but it would seem that some sort of merging or selection process would lead to better outcomes for all.
There could be a P2 stick that plugs in to HDMI port on monitor. Sorta like Fire TV Stick...
But, with keyboard and mouse... Complete programming environment...
You are right about benefits of merging, but there is not as much duplicated effort as may first appear.
ZOG for P2 & RISC-V JIT are MPU emulators, and look like ersmith's own ports, and the latter one allows P2 to run Python.
P2-GCC also not quite native P2, as it currently says "It uses the PropGCC compiler to generate a P1 .s assembly file. The assembly file is converted to a P2 .spin2 file using the utility s2pasm. The P2 assembly file is assembled into an object file using p2asm. p2link is then used to link the object file with other object files and libraries to produce an executable binary file."
CATALINA is being ported from a P1 code generator, so that work is to preserve the effort that went into P1 version.
If you are developing a C compiler, it makes sense to be able to run 'second opinion' type tests, and those other ports allow that.
Before any merging/selection process can take place there has to be options to select from. So part of this whole process is people trying out different approaches to see what works. That's natural, and it may seem confusing at first but without experimentation and variety you can never really make progress.
High quality compilers like GCC and LLVM are big, complicated projects. They're difficult to come up to speed on, and not necessarily much fun to port to a new architecture. To work around this there are different approaches:
(1) Use a simpler compiler. That was @RossH's approach with porting LCC to first P1 and now P2.
(2) Start with a different compiler for the architecture, and add C support to it. That's what I"m trying to do with fastspin. Under the hood C, BASIC, and Spin are not really much different; most of the differences are in syntax. (The few semantic differences can be a pain too, of course, but they're rare.)
(3) Find a way to adapt a compiler for a different architecture to the P2. Rather than trying to port a whole compiler and toolchain, they just implement a translator for another architecture (a much simpler process) and then all the tools for that architecture become available for P2. The ZPU effort does this by interpreting the instructions for another machine. The RISC-V JIT approach translates from RISC-V to P2 instructions at run-time. The p2gcc approach translates from P1 to P2 at compile time.
I don't think it's a question for Parallax, it's a question for us. Unless and until Parallax provides some direction and support, the C effort on P2 is going to have to be community driven, which means we get to make the decisions. If Parallax has some particular needs or desires then they'll have to make those known, but right now Parallax does not give the impression that they are interested in P2 tools.
As far as C++ support is concerned, it should be very straightforward to add it to p2gcc -- it's just a matter of changing the p2gcc compiler driver to recognize C++ extensions (.cpp, .cxx, .c++... any others?) and pass the appropriate flags along to PropGCC compiler to compile these. For simple C++ programs there aren't any flags necessary, but for more complicated ones we may need to link with libstdc++ and/or some other libraries.
Of course the ZPU and RISC-V compilers already support C++ as is. In fact I'd suggest that the RISC-V path is a good one for C++ support on P2; we'd get a mature compiler (GCC 8.x) with all the latest C++ features, and the RISC-V JIT framework has custom instructions that map to many of the P2 instructions, so writing an equivalent to <propeller.h> is very feasible (in fact the lib/riscv.h file in the git repo is a start on this).
#17 wasn't confirmed either but it would have been done along with the PLL tweaks (which aren't in the list) I'd say.
Here's confirmation of #16 plus the late fixes - https://forums.parallax.com/discussion/169695/new-fpga-files-for-next-silicon-version-5th-final-release-contains-new-rom/p1
Indeed, I see no particular reason to expect that a "truly" native C++ compiler will ever become available. p2gcc is pretty close, but it still targets another architecture (P1). And unless PropGCC gets updated it will continue to fall further and further behind of current C++ standards, which are changing rapidly.
Well, I expect commercial users would generally be pragmatic: they'll want something that works and lets them get a product to market quickly. Struggling with custom tools for a unique ISA is not something most commercial users are going to be keen on.
Every C compiler for the P1 involved an interpreter of some kind, either a minimal LMM one or a more complicated CMM one. Are people put off by Spin because it targets a virtual architecture? It seems like the sticking point isn't the interpreter, it's the fact that it interprets a well known 3rd party instruction set. But I'd argue that's a *good* thing. The Spin bytecode instructions are still not particularly well known or documented, and the only compilers that target it are for the Spin language (AFAIK; were there ever any others?) RISC-V, in contrast, is a well documented standard with multiple implementations available. The P2 RISC-V interpreter would be just another RV32IM implementation, with an option to run special custom microcode (PASM) on the other CPUs. That special microcode, and the P2 custom RISC-V instructions for accessing smart pins, are the "special sauce" that will make P2 unique and interesting.
Now, perhaps RISC-V isn't the best final base architecture. Maybe something like Web Assembly or JVM would be better. I suspect in terms of performance though RISC-V, with it's register based architecture, is a better fit to the P2 than most other virtual machines are.
I think that is viable, but the issues I see around CPU emulation are less to do with language, and more related to the usage details
I think this emulation path means listing files and map files show RISV V based memory maps, not native P2 memory maps.
* How will Debug experience work, can users BREAK and STEP in their source code ?
* Can users in-line P2 Assembler, in this flow, like they can on fastspin-C ?
* Can users manage multiple COGs and shared memory, in a clean manner ?