Double Long Math?
JLT7
Posts: 19
Are there any objects available that do double long (64-bit) integer math? E.g. add/subtract two 64-bit values, divide a 64 bit value by a 32 bit divisor, multiply a 32 bit by a 32 bit value -> 64 bit result. Both signed and unsigned for all of these.
I looked in the object exchange and didn't see anything obvious.The only thing I found was an object called "Unsigned Integer Math Functions", which is just a small subset of the list above.
I looked in the object exchange and didn't see anything obvious.The only thing I found was an object called "Unsigned Integer Math Functions", which is just a small subset of the list above.
Comments
Yes, it's easy to do in assembly, but my main code is written in Spin and I don't want to waste a cog just to do math functions. Too bad it's not easily possible to mix Spin and in-line PASM on the same cog. :-(
Cheers,
Istvan
Sure does. A long long addition compiles nicely to an add and addx when using size optimizations.
Might be a good idea as long as:
1) You know or would like to use C
2) The resulting program fits in the Prop.
3) You are willing to convert any Spin/PASM objects you are using from OBEX or wherever to C/PASM
Size might be an issue as compiling to LMM code is a bit bigger than spin byte codes.
Heater, a few questions for you:
1) Is either Catalina or propgcc a turn-key install? I'm under a very tight time deadline (this project is an instrument that's going on a balloon launch, and the balloon is launching with or without my hardware). I probably have enough time to convert my code to C (which I know well), but not enough time to futz with getting a build environment working.
2) Do these compilers support all of the functionality of Spin? Do they, for example, support bit ranges like this: outa[12..15] := %0110? I use this type of Spin shortcut heavily in my code and would have to convert everything to using | and & ~ in C, which will take time.
3) How much larger will the C code typically be? With my existing spin code, I have around 2000 longs free.
4) Does C use a cog for some purpose such as running a supervisor or interpreter? I'm using all 8 cogs in my current application and would need to do some serious restructuring if one or more cogs became unavailable.
propgcc is still alpha software, and is missing an IDE and debugger. If you're comfortable with command line tools and the "make" program it's a straightforward install.
They support the functionality of Spin, but not the syntax -- you have to use C syntax (so "outa[12..15] := %0100" would have to be recoded as something like "_OUTA = (_OUTA & 0xFFFF0FFF) | (0xb0010 << 12)").
It don't think we have a good feeling for this -- it depends on the application. The C code is compiled to LMM code, which can be twice as big as spin bytecodes, but the C compilers are usually better at doing things like common subexpression elimination to reduce code size. Both Catalina and GCC support putting code in external memory if you need more than 32K.
GCC doesn't need any cogs beyond the one its running on. I think Catalina can be configured that way too.
Eric
The problem with doing other wide arithmetic in Spin is that Spin doesn't make the carry and zero bits available after performing instructions like ADD and SUB. If you don't need all 64 bits and performance isn't an issue you can cheat by treating the high bit of the result as carry, masking it off, conditionally adding 1 to the high word, then clear the high bit, do the high long addition, test bit 0 of the high result to set bit 31 of the low long, then shift the high result right 1 and sign-extend it to set the sign bit. That should give you a properly signed 63 bit range.
It should be possible to implement 64 over 32 bit division similarly, but you will have to test and conditionally set bits that would normally get carried over in the shift operations. Considering your cog situation and that you have plenty of code space left, I'd attempt something like this before getting more complicated.
That's what I'm doing now. As I said above, this would be easy if I could mix PASM code with Spin, but, alas, that's a can of worms.
I'm surprised Parallax hasn't implemented this functionality as one of their "golden reference" objects as it's needed reasonably often when dealing with scaled fixed-point math that won't quite fit in 32 bit variables or where intermediate results are too large.
I tried the propgcc compiler mentioned above, and it handles long long ints wonderfully, but I concluded I just don't have time to convert everything to C in the short time I have left for this project.
The other solution is spin LMM, available in the obex
Massimo