64 bit addition/subtraction with Spin
Andy Gombos
Posts: 2
I've been reading this forum for a while, and there are lots of smart people here; the community around the Propeller chip seems very active.
I have written a 64 bit -> 32 bit square root routine in PASM. It works fine, but after I used PASM I realized that Spin would provide a much cleaner control structure for the rest of the program, as well as remove the 496 long limit I was probably going to hit soon.
However, I can't think of a way to do 64 bit addition (and subtraction) with Spin. I don't particularly want to waste an entire cog for running square roots. I was looking into restarting the Spin interpreter at the end of my square root routine, but I don't think that would let me emulate a PASM function call (the old Spin interpreter state would be destroyed).
I know that Spin is going to be significantly slower, but that doesn't matter much for my application. I've attached the PASM routine in case someone has any alternate suggestions.
Thanks!
I have written a 64 bit -> 32 bit square root routine in PASM. It works fine, but after I used PASM I realized that Spin would provide a much cleaner control structure for the rest of the program, as well as remove the 496 long limit I was probably going to hit soon.
However, I can't think of a way to do 64 bit addition (and subtraction) with Spin. I don't particularly want to waste an entire cog for running square roots. I was looking into restarting the Spin interpreter at the end of my square root routine, but I don't think that would let me emulate a PASM function call (the old Spin interpreter state would be destroyed).
I know that Spin is going to be significantly slower, but that doesn't matter much for my application. I've attached the PASM routine in case someone has any alternate suggestions.
Thanks!
Comments
Subtraction would be similar.
The Boolean value is true=0 if there is not a carry, and false=-1 with carry. The low long addition is always treated as unsigned. The overall value can be either signed or unsigned, with the sign in bit 63. Note that greater than or equal has to be written as =>.
Similar logic for subtract/borrow.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
for addition if the result is less than either of the operands then you had a 1 in the carry(correct me if I am wrong, please)
for subtraction, if the result is greater than either of the operands then you had a 1 in the carry bit
just my thoughts
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Parallax Forums - If you're ready to learn, we're ready to help.
Because the comparison is signed, lowA =< lowB (which is what I think you meant) could be true if there was no carry (e.g. $7FFF_FFFF + $7FFF_FFFF).
-Phil
Q1: How long does your SQRT take now?
Q2: What would you accept with SPIN?
Note there is always a response time and throughput aspect!
I should start a COG each time I needed a square root. Loading takes 100µs. Of course you need a COG, but that COG is versatile and re-usable..
If I counted right, ~3500 cycles, so ~44us at 80Mhz
It could take about .25 sec or so before it should start to become a problem (it's hard to say exactly because I'm guesstimating how long the physical system can pause while the calculation is being performed). At any rate, using your rough 80:1 Spin:PASM ratio, it would only be a few milliseconds - definitely fast enough.
This algorithm could be one of the cases where SPIN will be even slower So just for this benchmark I would be very interested in your SPIN implementation...
IF lowA<lowB THEN carry=1
either.
I think it can be salvaged by offsetting both sides by 2^31=2,147,483,648, so that the compare of the original values effectively becomes unsigned.
highA := highA + highB - (lowA + 2_147_483_648 => lowB + 2_147_483_648)
I'm not 100% confident in that though. Can't test it now and thinking fuzzy before afternoon stimulant!
I think I did mean, =>, not =<. Considering A => B as unsigned, it should generate a carry -(-1) when the condition is false, namely when A < B.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
EDIT: I think I fixed the final bit.
Jonathan
Jonathan
If you use it to calculate a distance given the difference along two axis you can also use a cordic routine. It gives you back atan2 and dist with little effort.
This one can be implemented in spin, SpinLMM, in Pasm in a new Cog or in Pasm using the embedded object.
It depends on your needs...
So many options, so much power in your hands...
Massimo
clo = alo + blo ;
chi = ahi + bhi + (((alo >> 31) + (blo >> 31) + 1 - (clo >> 31)) >> 1) ;
I'm sure some of the experts here will be able to simplify it further.