Shop OBEX P1 Docs P2 Docs Learn Events
automatic spin to C++ translator — Parallax Forums

automatic spin to C++ translator

ersmithersmith Posts: 6,099
edited 2012-01-05 15:36 in Propeller 1
Here's a very incomplete Spin to C++ translator. Please note that this is not an official part of the propgcc project; it's just a little tool that I threw together over the holidays on my own time. It has awful error handling and many missing features, but it may be useful for some simple drivers. For example, I've been able to translate FullDuplexSerial.spin (see below for issues) and VGA64_PIXEngine.spin with it.

spin2cpp is a command line tool takes a Spin object and turns it into a C++ class; or at least, it's supposed to do that, although there are many Spin features which aren't implemented yet and there are some things that don't translate well. For example, the FullDuplexSerial.spin object has code that looks like:
PUB start(rxpin, txpin, mode, baudrate) : okay
...
  longmove(@rx_pin, @rxpin, 3)
This relies on parameters being on the stack, which doesn't work in C++; you have to change the code to:
PUB start(rxpin, txpin, mode, baudrate) : okay
...
  rx_pin := rxpin
  tx_pix := txpin
  rxtx_mode := mode
With that change FullDuplexSerial.spin will work, with a caveat: some of the variables are not declared "volatile" that should be, so if you try to print too much data at once a race condition can cause it to hang. If you leave off optimization in the C++ compile then it's slow enough for the PASM to always stay ahead of the C++ code.

Usage is just:
spin2cpp foo.spin
it produces as output "foo.h" and "foo.cpp".

There's still lots of work to be done to make this into a really useful tool. It's open source, so I welcome contributions!

Eric

Comments

  • David BetzDavid Betz Posts: 14,516
    edited 2012-01-05 08:59
    That's very cool Eric!

    I have a question though. You say that the start method relies on parameters being on the stack but doesn't GCC automatically generate code to spill register parameters to the stack when their address is needed? Why would you need to explictly store them in variables?
  • ersmithersmith Posts: 6,099
    edited 2012-01-05 09:06
    David Betz wrote: »
    That's very cool Eric!

    I have a question though. You say that the start method relies on parameters being on the stack but doesn't GCC automatically generate code to spill register parameters to the stack when their address is needed? Why would you need to explictly store them in variables?

    The FullDuplexSerial code initializes 3 variables from 3 parameters by doing a "memcpy" (well, actually "longmove") of 12 bytes from the first parameter to the first variable. But GCC passes parameters in registers, not on the stack, so this doesn't work in the translated C++ code. The first parameter is spilled (GCC notices that its address is taken and passed to memcpy) but the other parameters aren't spilled to the stack because their addresses weren't taken. There's also no guarantee that parameters that are spilled will be stored on the stack in the same order that Spin does, although in practice they probably are.

    Eric
  • David BetzDavid Betz Posts: 14,516
    edited 2012-01-05 09:07
    Okay, I understand now. I forgot that it was assuming that the parameters were in consecutive locations in memory. Probably a dangerous assumption anyway.
  • Heater.Heater. Posts: 21,230
    edited 2012-01-05 11:35
    Damn cunning.
    Have to find a minute to try it out.
    So it handles the PASM parts, things like Lonesock's F32 would probably hard to fix up, it does funky things on the Spin stack which gets passed straight into PASM.
    Which reminds me, is there any advantage, speed wise, in using a dedicated floating point COG like lonesock's in propgcc?
  • jazzedjazzed Posts: 11,803
    edited 2012-01-05 12:30
    Heater. wrote: »
    Which reminds me, is their any advantage, speed wise, in using a dedicated floating point COG like lonesock's in propgcc?
    Jonathan was invited to work on this. Guess he figured we didn't need it.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-01-05 12:33
    Eric,

    That looks great. I played around with converting Spin to C several months ago, but I haven't looked at it since September. My code is in the attached zip file. I treated constants a bit differently, where I used a #define instead of const. The header file contains a different version of the constant name with the file name prepended.

    The source code is in stoc.c, spinsubs.c and spinsubs.h. The genereated cpp files include spin.h, which defines some basic Spin functions as macros and static functions.

    Dave
  • ersmithersmith Posts: 6,099
    edited 2012-01-05 12:45
    Heater. wrote: »
    So it handles the PASM parts, things like Lonesock's F32 would probably hard to fix up, it does funky things on the Spin stack which gets passed straight into PASM.
    Which reminds me, is their any advantage, speed wise, in using a dedicated floating point COG like lonesock's in propgcc?

    Some programs might get a speed advantage to having a dedicated COG for floating point. To take advantage of this there would be some work involved in getting the GCC scheduler to arrange things better (so that the floating point and integer code could run in parallel). I get the impression that this is considered a low priority, but if I'm wrong I can dig into it.

    Eric
  • ersmithersmith Posts: 6,099
    edited 2012-01-05 12:49
    Thanks for the code, Dave! I'll take a look at it... I'm sure there are some things you solved better than I did.

    Eric
  • Heater.Heater. Posts: 21,230
    edited 2012-01-05 15:36
    Eric,
    Thing is, when I made the Zog interpreter, which runs ZPU byte codes compiled from C/C++ with zpu-gcc, I just had to get F32 to provide the floating point "coprocessor" as the interpreted floating point libs were so slow and even worse very large. I basically just wanted to get the whetstone benchmark running.
    I guess with propgcc's LMM speed is not such an issue. I have no idea about any code size saving.
    So it looks like a low priority objective. Especially if it needs some sophisticated instruction scheduling by the compiler. Wish I could find the time to get Zog's F32 working with propgcc in the simplistic way it works with Zog.
Sign In or Register to comment.