SPIN to ASM
Jim Edwards
Posts: 54
Is there a compiler that takes a SPIN program and generates the ASM for it? To clarify further, I mean a small SPIN program where the resulting ASM can fit into 1 cog.
Comments
There are just too many things that would be Spin or PASM specific to make a compilier worth the bother.
Spin only uses variables in hub RAM while PASM uses both hub and cog RAM.
This would make any kind of conversion from one to the other problematic. IMO.
The thing is that using tricks like reducing "n x 15" to "n bitshift left 4 places and subract n from the answer" are not the sort of things an automatic translation program can do very easily.
I believe the very clever C programmers have got code that you can tell the compiler whether to put it in hub or cog.
If you like, maybe post some of your spin code and we can think about how to convert it to asm?
I'm often surprised by the optimizations gcc performs :-). Here's a log of converting a simple .spin function to PASM, automatically:
This is under Linux, so the "$" is a command prompt and "cat" is the program to type a file out. The weird name "_ZN8testSpin5Mul15Ei" is due to the way C++ encodes type information in function names. Also note that I did give -O3 to propeller-elf-gcc to tell it to optimize for speed as much as it can; if it's optimizing for space (the normal case in the Propeller world) it'll generate a call to a multiply routine instead because that takes less space than the shift and sub.
Of course the .pasm isn't a complete program, you'd need the register declarations and some interface code. Giving the "-mspin" argument to propeller-elf-gcc will make it output a lot of that for you. Also, it's using the normal C calling convention (where return addresses are stored in the "lr" register) instead of the PASM calling convention (where you return with "ret"); there are ways to force gcc to use that, but they require editing the .cpp file that spin2cpp creates.
Eric
Ok, just another question because I'm not familiar with how ASM works. But, I notice at end you have a data section for the pins. If you have multiple cogs, is this pin data created separately for each cog or is it shared (latter would be a problem I think). Thanks!
That is quite a clever technique kuroneko. Better than what I have used, which is to hard code the pins into variables.
So - you declare a variable as a 00000000_00000000_00000000_00000001
Then in the setup you pass the pin number. Maybe it is pin 12.
Then you bitshift this by 12 places.
Now you have 00000000_00000000_00010000_00000000 which can be used as a mask.
That is very clever.
I haven't copied the code over yet to test out so that was ok. I will be doing this on the weekend. Will get back to you on results. Thanks.
- full_cycle is a local variable so should be initialised to FALSE
- cnt can be -1 (minor, you'd just spend one more cycle in the init state)
- when switching back to mirror mode you should make sure to at least sample one more cycle, full_cycle is still TRUE and the clamp input may already be 0 again
Anyway, I had to make a minor adjustment in that the clamp release test is now done during output being high (previously low). Also when switching to clamp mode I output at least one clamped cycle whereas the SPIN version could skip that (and wait for the rising edge immediately before returning to mirror mode). Do you expect clamp pin changes within the same cycle?To summarise the differences:
@kuroneka: Good catch on not initializing full_cycle. It needs to be set false at entry to both the _STATE_INIT and _STATE_MIRROR states. I've corrected my original code (also source shows the full source of the project including my test waveform generator). I guess full_cycle was set by the interpreter to 0 to begin with before entry to _STATE_INIT and it didn't matter that it was TRUE on entering _STATE_MIRROR because the clamp pin was always high at that point for my test waveforms. Now it is fixed. The reason I changed the code is that c1 needs to be initialized to the clock count before entering _STATE_MIRROR, either from _STATE_INIT (where c1 gets initially set up) or _STATE_CLAMP. For both of these states the code will have detected the first rising edge and so c1 needs to be set to start the measurement cycle of high and low counts within _STATE_MIRROR. I do not expect the clamp pin to ever change within one cycle. This project is for a car, it reads a Mass Airflow Signal that varies between 20 to 200 Hz and normally the clamp pin signal will change around the same frequency every time, say F, between 20 and 200. So, as the frequency rises from 20 Hz, it hits the clamp frequency F and the mafout pins stay at the last recorded frequency. Then as frequency falls from 200 Hz, it again hits the clamp frequency F but this time reverts to mirror mode. The clamped maf out pin will drive the stock ECU of the car and a piggyback ECU will read the raw maf in pin and take over the car control when the clamp point is hit but we need to fool the stock ECU that everything is ok by clamping it's maf input with the maf out pin of this circuit.
Anyway, I tested the code again using both my spin based control cog and your asm based control cog. The logic analyzer shows they work exactly the same, only the delay of the spin cog from input edge to output edge is something like 60-80 uSecs and for your asm cog it's only about 10 uSecs with little variation from that.
Thanks for the help! The circuit and code work exactly as I had hoped.
I thought this might just be due to the sample rate I had my logic analyzer set on initially, which was 100 KHz, i.e. 10 uSec resolution. However, I just tried setting my LA to acquire at 100 MHz (10 nSec resolution) using deep memory mode and it is showing that the delay from input to output is 7.5 to 8 uSec. I can't explain why the real world results differ from your expectations.
When you measure this I'd be interested in the delay seen directly on the propeller pins (taking any external h/w out of the equation).
PCB artist, a free schematic and board layout software package from Advanced Circuits. See http://www.4pcb.com/free-pcb-layout-software/