riscvp2: a C and C++ compiler for P2

ersmithersmith Posts: 3,140
edited 2019-07-17 - 04:37:28 in Propeller 2
I've posted what I hope are useful instructions for compiling C and C++ applications for P2 using a RISC-V toolchain. The repository is at https://github.com/totalspectrum/riscvp2. The README.md should describe everything you need, including where to find a pre-built RISC-V toolchain. Once your RISC-V toolchain is installed, edit the Makefile to have the correct paths and then do "make install". That should update your RISC-V toolchain so that it can build P2 binaries as well, by just giving the "-T riscvp2.ld" switch to riscv-none-embed-gcc or riscv-none-embed-g++.

"make hello-c++.binary" will build a simple C++ demo application that should run on the P2 Eval board (it works for me, at least!)

Feedback is very welcome. I've been using this kind of setup for a while, so I may well have overlooked some step in the descriptions, or perhaps not made something as clear as it should be. If so, please let me know!

(Tested on Debian Linux. It should work the same for any Linux or Mac OSX. For Windows it *should* work if you have some kind of POSIX system like msys or cygwin installed, but I haven't actually tested it there.)

Comments

  • Here's a sample pin toggling program. As compiled it will toggle pin 0 as quickly as possible; there's also a version to toggle pin 56 at visible speeds for testing.
    // simple pin toggle demo
    #include <stdint.h>
    #include <propeller2.h>
    
    #if 0
    #define PIN 56
    #define DELAY 40000000
    #else
    #define PIN 0
    #endif
    
    void main()
    {
        for(;;) {
            _pinnot(PIN);
    #ifdef DELAY        
            _waitx(DELAY);
    #endif        
        }
    }
    

    I compiled it with:
    riscv-none-embed-gcc -specs=nano.specs -T riscvp2_lut.ld -o toggle.elf -Os toggle.c
    riscv-none-embed-objcopy -O binary toggle.elf toggle.binary
    

    (This uses the LUT caching version of the JIT compiler, which is the fastest but has a small cache, so best for small programs like this.)

    If I've done everything right, the inner loop will compile in the end to two instructions:
    loop
        drvnot x15
        jmp    #loop
    

    Running from LUT cache this should take just 6 cycles per loop. The system clock is 160 MHz, so we should get about 27 million toggles per second. I don't have an oscilloscope to check this, but I've attached the binary so interested readers can double check my work.

    You'll also probably notice that the binary is huge, relatively speaking. That's a consequence of the newlib library that comes with most RISC-V toolchains, which for an "embedded" library is incredibly bulky. We'll probably want to port proplib or some other P2 library to RISC-V to get a more compact binary.
  • I've updated my github repository with some improvements and bug fixes. Most notably there was a bug in _sbrk() which caused malloc() to fail randomly; I also made read() work (although characters are not echoed right now).

    Has anyone tried this out? If you've tried and failed (or couldn't understand the docs) please let me know -- I would like to improve the installation instructions.
  • I'll at least try and run the binary and confirm the rate today Eric
  • Looks really good. I gave it a try and was able to get PropWare to recognize the tools and start attempting compilation. It quickly failed out as there are lots of P1-specific things throughout the codebase, ranging from "-m32bit-doubles" to "CNT" and "__builtin_propeller_rev(x, bits)"

    I started fixing some but quickly grew tired. Porting PropWare to P2 is going to require far more than an hour on a weeknight :tongue:

    But, it does seem feasible, and the fact that this is all based on a GCC toolchain means no crazy hacks need to be applied to CMake. It's very promising!
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: https://ci.zemon.name?guest=1
  • Tubular wrote: »
    I'll at least try and run the binary and confirm the rate today Eric

    Thanks!
  • DavidZemon wrote: »
    Looks really good. I gave it a try and was able to get PropWare to recognize the tools and start attempting compilation. It quickly failed out as there are lots of P1-specific things throughout the codebase, ranging from "-m32bit-doubles" to "CNT" and "__builtin_propeller_rev(x, bits)"

    I started fixing some but quickly grew tired. Porting PropWare to P2 is going to require far more than an hour on a weeknight :tongue:

    But, it does seem feasible, and the fact that this is all based on a GCC toolchain means no crazy hacks need to be applied to CMake. It's very promising!

    Ah, __builtin_propeller_rev reveals something we're missing from propeller2.h -- a way to access the _rev() instruction. We should add that. There are probably a few other things that are operators in Spin2 that we'll want to add as C functions.

    CNT of course is now _cnt() on P2.

    Thanks for giving this a try. I hope you were able to run something simple like "hello world"?
  • There are a few gotchas with condition codes too
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Cluso99 wrote: »
    There are a few gotchas with condition codes too

    Sorry, what kind of gotchas with condition codes? Oh, you mean porting P1 assembly code to P2. Yeah, in general there are lots of gotchas there. Even more so if you're using the RISC-V toolchain which only supports RISC-V inline assembly :). If you stick with the macros in propeller2.h you should be OK though.
Sign In or Register to comment.