64 bit math
After some work I'm ready to release the first version of my 64 bit (unsigned) math object. It allows adding or subtracting 64 bit numbers, as well as multiplying or dividing a 64 bit number by a 32 bit number. It's far from perfect. There's no checking for overflows or any other safeguards. This first version starts a cog, does the math, then stops the cog. I will be creating a second version that keeps the cog running as time permits.


Comments
I think step one should be to use 64 bit signed numbers (63 bit + sign) for everything. Here's a for instance on why.
a - b = c
c + d = f
if: b > a then c < 0
if d < c*-1 then e < 0
for example.
a = 0 , b = 10 , d = 0
a - b = 0 - 10 = c = -10
c + d = -10 + 0 = e = -10
in summary: a = 0, b = 10 , c = -10 , d = 0 , e = -10
a, b, and d are fine as unsigned numbers, but c and e would need to be signed numbers.
....
In turn, your life is easier if you you use signed math for everything. Otherwise you need to spend more time being careful that numbers never leave the positive number interval.
PUB Subtract(hostPtr, nodePtr) | cog cog := cognew(@address, @hostPtr) +1 repeat while nodePtr cogstop (cog -1) DAT org address nop host_ptr mov address, par node_ptr rdlong host_ptr, address host_long1 add address, #4 host_long2 rdlong node_ptr, address node_long1 rdlong host_ptr, host_long1 node_long2 add host_ptr, #4 rdlong host_ptr, host_long2 rdlong node_ptr, node_long1 add node_ptr, #4 subs host_long1, node_long1 wc rdlong node_ptr, node_long2 sub node_ptr, #4 subsx host_long2, node_long2 wrlong host_long2, host_ptr sub host_ptr, #4 wrlong host_long1, host_ptr wrlong node_ptr, #0Any thoughts would be helpful!
{{ ////////////////////////////////////////////////////////////////////////////////// // 64 bit signed addition and subtraction methods // // Author : Joe Heinz // // Copyright : Joe Heinz // // // // data structure as follows : // // VAR long hostLong1, hostLong2, nodeLong1, nodeLong2 // ////////////////////////////////////////////////////////////////////////////////// }} PUB Subtraction(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time, minuend // // nodePtr is pointer to least significant long of node time, subtractend // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "s") PUB Addition(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time // // nodePtr is pointer to least significant long of node time // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "a") PRI DoMath(hPtr, nPtr, function) : cog '' cog := cognew(@address, @hPtr) +1 ' start asm cog repeat while nPtr ' wait for asm cog to finish cogstop (cog -1) ' stop cog DAT org address nop host_ptr mov address, par ' get first address of passing method node_ptr rdword host_ptr, address ' read the address to get pointer to Least Significant long of host time host_long1 add address, #2 ' add a word offset to address host_long2 rdword node_ptr, address ' read the address to get pointer to Least Significant long of node time funct add address, #2 ' add a word offset to address rdbyte funct, address ' read the function type *add or subtract* cmp funct, sub_funct wz ' if subtract function, set z flag rdlong host_ptr, host_long1 ' get least significant long of host time node_long1 add host_ptr, #4 ' add long offset to host pointer node_long2 rdlong host_ptr, host_long2 ' get most significant long of host time rdlong node_ptr, node_long1 ' get least significant long of node time add node_ptr, #4 ' add long offset to node pointer if_z subs host_long1, node_long1 wc ' do first subtraction and write c flag if_nz adds host_long1, node_long1 wc ' do first addition and write c flag rdlong node_ptr, node_long2 ' get most significant long of node time sub node_ptr, #4 ' subtract long offset from node pointer if_z subsx host_long2, node_long2 ' do second subtraction if_nz addsx host_long2, node_long2 ' do second addition wrlong host_long2, host_ptr ' write most significant long of result sub host_ptr, #4 ' subtract long offset from host pointer wrlong host_long1, host_ptr ' write least significant long of result wrlong node_ptr, #0 ' clear node pointer to stop cog and return to caller sub_funct long "s"*edit*
Just updated code with fully commented version. Still looking for any advice!
Also, fixed the address / data swap. Thanks for pointing that out!
*edit*
Code with suggested improvements :
{{ ////////////////////////////////////////////////////////////////////////////////// // 64 bit signed addition and subtraction methods // // Author : Joe Heinz // // Copyright : Joe Heinz - 2013 // // // // data structure as follows : // // VAR long hostLong1, hostLong2, nodeLong1, nodeLong2 // ////////////////////////////////////////////////////////////////////////////////// }} PUB Subtraction(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time, minuend // // nodePtr is pointer to least significant long of node time, subtractend // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "s") PUB Addition(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time // // nodePtr is pointer to least significant long of node time // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "a") PRI DoMath(hPtr, nPtr, function) : cog '' cog := cognew(@entry, @hPtr) +1 ' start asm cog repeat while nPtr ' wait for asm cog to finish DAT org entry cogid p_cog mov address, par ' get first address of passing method rdword host_ptr, address ' read the address to get pointer to Least Significant long of host time add address, #2 ' add a word offset to address rdword node_ptr, address ' read the address to get pointer to Least Significant long of node time add address, #2 ' add a word offset to address rdbyte funct, address ' read the function type *add or subtract* cmp funct, sub_funct wz ' if subtract function, set z flag rdlong host_long1, host_ptr ' get least significant long of host time add host_ptr, #4 ' add long offset to host pointer rdlong host_long2, host_ptr ' get most significant long of host time rdlong node_long1, node_ptr ' get least significant long of node time add node_ptr, #4 ' add long offset to node pointer if_z subs host_long1, node_long1 wc ' do first subtraction and write c flag if_nz adds host_long1, node_long1 wc ' do first addition and write c flag rdlong node_long2, node_ptr ' get most significant long of node time sub node_ptr, #4 ' subtract long offset from node pointer if_z subsx host_long2, node_long2 ' do second subtraction if_nz addsx host_long2, node_long2 ' do second addition wrlong host_long2, host_ptr ' write most significant long of result sub host_ptr, #4 ' subtract long offset from host pointer wrlong host_long1, host_ptr ' write least significant long of result wrlong zero, node_ptr ' clear node pointer to stop cog and return to caller cogstop p_cog sub_funct long "s" zero long 0 address res host_ptr res node_ptr res host_long1 res host_long2 res node_long1 res node_long2 res funct res p_cog resAnyway, if that's your style, stick with it.
Just noticed, function parameters are still longs, so even if you only read words you'll have to advance by 4 (not 2, @nPtr == @hPtr + 4).
Re: long address. That's a great point! When I started writing, I had word variables to store the pointers in. But I decided that passing the DoMath variables to be better. And then never went back and changed the advance.
{{ ////////////////////////////////////////////////////////////////////////////////// // 64 bit signed addition and subtraction methods // // Author : Joe Heinz // // Copyright : Joe Heinz - 2013 // // Grateful acknowledgement to kuroneko (parallax forum // // data structure as follows : // // VAR long hostLong1, hostLong2, nodeLong1, nodeLong2 // ////////////////////////////////////////////////////////////////////////////////// }} PUB Subtraction(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time, minuend // // nodePtr is pointer to least significant long of node time, subtractend // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "s") PUB Addition(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time // // nodePtr is pointer to least significant long of node time // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "a") PRI DoMath(hPtr, nPtr, function) : cog '' cog := cognew(@entry, @hPtr) +1 ' start asm cog repeat while nPtr ' wait for asm cog to finish DAT org entry cogid p_cog mov address, par ' get first address of passing method rdword host_ptr, address ' read the address to get pointer to Least Significant long of host time add address, #2 ' add a word offset to address rdword node_ptr, address ' read the address to get pointer to Least Significant long of node time add address, #2 ' add a word offset to address rdbyte funct, address ' read the function type *add or subtract* cmp funct, sub_funct wz ' if subtract function, set z flag rdlong host_long1, host_ptr ' get least significant long of host time add host_ptr, #4 ' add long offset to host pointer rdlong host_long2, host_ptr ' get most significant long of host time rdlong node_long1, node_ptr ' get least significant long of node time add node_ptr, #4 ' add long offset to node pointer if_z subs host_long1, node_long1 wc ' do first subtraction and write c flag if_nz adds host_long1, node_long1 wc ' do first addition and write c flag rdlong node_long2, node_ptr ' get most significant long of node time sub node_ptr, #4 ' subtract long offset from node pointer if_z subsx host_long2, node_long2 ' do second subtraction if_nz addsx host_long2, node_long2 ' do second addition wrlong host_long2, host_ptr ' write most significant long of result sub host_ptr, #4 ' subtract long offset from host pointer wrlong host_long1, host_ptr ' write least significant long of result wrlong zero, node_ptr ' clear node pointer to stop cog and return to caller cogstop p_cog sub_funct long "s" zero long 0 address res host_ptr res node_ptr res host_long1 res host_long2 res node_long1 res node_long2 res funct res p_cog res{{ ////////////////////////////////////////////////////////////////////////////////// // 64 bit signed addition and subtraction methods // // Author : Joe Heinz // // Copyright : Joe Heinz - 2013 // // Grateful acknowledgement to kuroneko (parallax forum) // // data structure as follows : // // VAR long hostLong1, hostLong2, nodeLong1, nodeLong2 // ////////////////////////////////////////////////////////////////////////////////// }} PUB Subtraction(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time, minuend // // nodePtr is pointer to least significant long of node time, subtractend // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "s") PUB Addition(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time // // nodePtr is pointer to least significant long of node time // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "a") PRI DoMath(hPtr, nPtr, function) : cog '' cog := cognew(@entry, @hPtr) +1 ' start asm cog repeat while nPtr ' wait for asm cog to finish DAT org entry cogid p_cog mov address, par ' get first address of passing method rdword host_ptr, address ' read the address to get pointer to Least Significant long of host time add address, #4 ' add a word offset to address rdword node_ptr, address ' read the address to get pointer to Least Significant long of node time add address, #4 ' add a word offset to address rdbyte funct, address ' read the function type *add or subtract* cmp funct, sub_funct wz ' if subtract function, set z flag rdlong host_long1, host_ptr ' get least significant long of host time add host_ptr, #4 ' add long offset to host pointer rdlong host_long2, host_ptr ' get most significant long of host time rdlong node_long1, node_ptr ' get least significant long of node time add node_ptr, #4 ' add long offset to node pointer if_z subs host_long1, node_long1 wc ' do first subtraction and write c flag if_nz adds host_long1, node_long1 wc ' do first addition and write c flag rdlong node_long2, node_ptr ' get most significant long of node time if_z subsx host_long2, node_long2 ' do second subtraction if_nz addsx host_long2, node_long2 ' do second addition wrlong host_long2, host_ptr ' write most significant long of result sub host_ptr, #4 ' subtract long offset from host pointer wrlong host_long1, host_ptr ' write least significant long of result sub address, #4 ' subtract long offset from address, points to nPtr wrlong zero, address ' clear node pointer to return to caller cogstop p_cog sub_funct long "s" zero long 0 address res host_ptr res node_ptr res host_long1 res host_long2 res node_long1 res node_long2 res funct res p_cog resPRI DoMath(hPtr, nPtr, function) : cog '' cog := cognew(@entry, @hPtr) +1 ' start asm cog repeat while function ' wait for asm cog to finish DAT org 0 entry mov address, par ' get first address of passing method rdword host_ptr, address ' read the address to get pointer to Least Significant long of host time add address, #4 ' add a word offset to address rdword node_ptr, address ' read the address to get pointer to Least Significant long of node time add address, #4 ' add a word offset to address rdbyte funct, address ' read the function type *add or subtract* cmp funct, #"s" wz ' if subtract function, set z flag rdlong host_long1, host_ptr ' get least significant long of host time add host_ptr, #4 ' add long offset to host pointer rdlong node_long1, node_ptr ' get least significant long of node time add node_ptr, #4 ' add long offset to node pointer rdlong node_long2, node_ptr ' get most significant long of node time if_z [COLOR="#FF0000"]sub[/COLOR] host_long1, node_long1 wc ' do first subtraction and write c flag if_nz [COLOR="#FF0000"]add[/COLOR] host_long1, node_long1 wc ' do first addition and write c flag rdlong host_long2, host_ptr ' get most significant long of host time if_z subsx host_long2, node_long2 ' do second subtraction if_nz addsx host_long2, node_long2 ' do second addition wrlong host_long2, host_ptr ' write most significant long of result sub host_ptr, #4 ' subtract long offset from host pointer wrlong host_long1, host_ptr ' write least significant long of result wrlong zero, address ' clear node pointer to stop cog and return to caller cogid p_cog cogstop p_cog p_cog res alias address res host_ptr res node_ptr res host_long1 res host_long2 res node_long1 res node_long2 res funct res tail fit CON zero = $1F0 alias = 0 DATNote that the math is still slightly off (somehow the connections isn't made to the high part).The lower 32 bits should be manipulated with add/sub instead of adds/subs.
CON {{ // 64 bit clock source // // Author : Joe Heinz // // Copyright : Joe Heinz - 2013 // }} _ctr1_apin = 0 ' pin to use as output from counter A to counter B _sample_pin = 1 ' pin to sample both counters phase _pll_mode = %111 ' pll divisor = 1:1 VAR long long1, long2 ' two longs to store 64 bit variable byte cog ' byte to store cog running timer in PUB NULL '' not a top level object PUB Start '' Start timing cog long1 := _sample_pin ' move sample pin into longa cog := cognew(@entry, @long1) +1 ' start assembly cog outa[_sample_pin] := 0 ' set samplePin to LOW dira[_sample_pin] := 1 ' make samplePin an output result := cog PUB Stop '' Stop timing cog if cog ' if cog started cogstop(cog ~~ -1) ' stop cog and clear cog variable PUB GetSample '' Get a sample time outa[_sample_pin] := 1 ' make samplePin HIGH if long1 > $FFFF_FFFC ' if near overflow at sample long2 -= 1 ' subtract 1 from high 32 bits outa[_sample_pin] := 0 ' make samplePin LOW result := @long1 ' return address of longa DAT org entry rdlong trigger, par mov dira, diraval 'set APIN to output mov frqa, #1 'set counter to increment 1 each cycle mov frqb, #1 'set counter to increment 1 each cycle mov wr2add, par ' move par address to wr2add add wr2add, #4 ' add long offset mov ctrb, ctramode ' establish counter A mode and APIN mov ctra, ctramode ' establish counter B mode and APIN :loop waitpeq zero, trigger ' wait for trigger pin to be idle 4 + waitpne zero, trigger ' wait for trigger pin to be active 4 + mov long_1, phsa ' move phsa to long1 4 mov long_2, phsb ' move phsb to long2 4 wrlong long_1,par ' write long1 to longa 8 + wrlong long_2, wr2add ' write long2 to longb 16 jmp :loop ' repeat 4 ' min 48 clock cycles, diraval long |< _ctr1_apin ctramode long (%00010 << 26) + ( _pll_mode << 23) + _ctr1_apin ' PLL mode - single ended, APIN is input for counter B ctrbmode long (%01110 << 26) + _ctr1_apin ' neg edge triggered, APIN is output from counter A zero long 0 trigger res ' pin to trigger sample long_1 res long_2 res wr2add res*edit*
Found a couple errors already
The 64bit value is emitted to the serial console after each key press.
This logger uses 64 bit math.
http://code.google.com/p/propforth/wiki/Logger1Simple
The source code is included in the comments. The stuff that gets loaded is the same, but in base 64 encoding to load faster. Skip past that and the forth source to the assembler code.
{{ ////////////////////////////////////////////////////////////////////////////////// // 64 bit signed addition and subtraction methods // // Author : Joe Heinz // // Copyright : Joe Heinz - 2013 // // Grateful acknowledgement to kuroneko (parallax forum) // // data structure as follows : // // VAR long hostLong1, hostLong2, nodeLong1, nodeLong2 // ////////////////////////////////////////////////////////////////////////////////// }} PUB Addition(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time // // nodePtr is pointer to least significant long of node time // // result of addition is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "a") PUB Subtraction(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of host time, minuend // // nodePtr is pointer to least significant long of node time, subtractend // // result of subtraction is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "s") PUB multiply(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of multiplicand // // nodePtr is pointer to multiplier // // result of multiplication is stored in host longs // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "m") PUB divide(hostPtr, nodePtr) '' Perform 64 bit subtraction {{ ////////////////////////////////////////////////////////////////////////////////// // hostPtr is pointer to least significant long of dividend // // nodePtr is pointer to divisor // // result of division is stored in host longs // // remainder is stored in nodelong1 // // returns cog ASM engine was run in or false if no cog available // ////////////////////////////////////////////////////////////////////////////////// }} result := DoMath(hostPtr, nodePtr, "d") PRI DoMath(hPtr, nPtr, function) : cog '' cog := cognew(@entry, @hPtr) +1 ' start asm cog repeat while function ' wait for asm cog to finish DAT org entry cogid p_cog ' get running cog number 8+ 1*2 1 mov address, par ' get first address of passing method, hPtr 4 3 rdword host_ptr, address ' read the address to get pointer to Least Significant long of host time 8 1*2 2 add address, #4 ' add a word offset to address, points to nPtr 4 3 rdword node_ptr, address ' read the address to get pointer to Least Significant long of node time 8 1*2 3 add address, #4 ' add a word offset to address, points to function 4 3 rdbyte funct, address ' read the function type *add or subtract* 8 1*2 4 rdlong host_long1, host_ptr ' get least significant long of host time 8 1*2 5 add host_ptr, #4 ' add long offset to host pointer 4 3 rdlong host_long2, host_ptr ' get most significant long of host time 8 1*2 6 rdlong node_long1, node_ptr ' get least significant long of node time 8 1*2 7 add node_ptr, #4 ' add long offset to node pointer 4 3 rdlong node_long2, node_ptr ' get most significant long of node time cmp funct, #"a" wz if_z call #addi cmp funct, #"s" wz if_z call #subt cmp funct, #"m" wz if_z call #mult cmp funct, #"d" wz if_z call #div write wrlong host_long2, host_ptr ' write most significant long of result 8 1*2 9 sub host_ptr, #4 ' subtract long offset from host pointer 4 3 wrlong host_long1, host_ptr ' write least significant long of result 8 1*2 10 wrlong node_long2, node_ptr sub node_ptr, #4 wrlong node_long1, node_ptr wrlong zero, address ' clear function to return to caller 8 1*2 11 cogstop p_cog ' stop the cog 8 1*2 12 div cmp node_long1, zero wz ' check to see if divisor is zero if_z mov host_long1, zero ' and zero out result if_z mov host_long2, zero ' undefined if_z jmp write ' write to buffers ' find most significant bit shift offset of divisor < mplace = 0 to 31 > mov mplace, #0 ' prepare MSB place findm rol node_long1, #1 wc ' rotate divisor left 1 place and check for overflow if_nc add mplace, #1 ' if no overflow, add 1 to MSB place if_nc jmp #findm ' repeat loop until overflow ror node_long1, #1 ' rotate back one mov mask, #1 ' prepare mask mov tmp, mplace ' move msb shift factor to tmp for itteration count shl mask, mplace ' move mask by msb shift factor div2 cmpsub host_long2, node_long1 wc ' subtract divsor from dividend and watch for subtraction muxc d2, mask ' mux c flag to d2 at mask place cmpsub tmp, #1 wz ' subtract 1 from shift factor watching for last division if_nz shr mask, #1 ' shift mask right by 1 if_nz shr node_long1, #1 ' shift divisor right by 1 if_nz jmp #div2 ' and do loop again shr mask, #1 ' shift mask right by 1 shr node_long1, #1 ' shift divisor right by 1 cmpsub host_long2, node_long1 wc ' subtract divsor from dividend and watch for subtraction muxc d2, mask ' mux c flag to d2 at mask place sub tmp, #1 wz ' subtract 1 from shift factor watching for last division mov tmp, #1 ' move 1 to tmp for muxc shl mask, #31 ' move mask to MSB mov temp, #32 ' move 32 to temp for itteration count div1 shl host_long2, #1 ' make room for next bit from LSL shl host_long1, #1 wc ' shift next bit from LSL watching for carry muxc host_long2, tmp ' mux carry into MSL cmpsub host_long2, node_long1 wc ' subtract divisor from MSL, watch for subtraction muxc d1, mask ' mux c flag to d1 sub temp, #1 wz ' subtract 1 from itteration count if_nz shr mask, #1 ' move mask to next place if_nz jmp #div1 ' do loop again mov node_long1, host_long2 ' move remainder in node_long2 mov node_long2, #0 mov host_long2, d2 ' move d2 to host_long2 mov host_long1, d1 ' move d1 to host_long1 div_ret ret mult mov multiplier, node_long1 ' get multiplier from node_long1 and place in multiplier cmp multiplier, zero wz ' check for multiply by 0 if_z mov host_long1, zero ' if multiply by zero just zero host_long1 if_z mov host_long2, zero ' and zero host_long2 if_z jmp write ' jump to write mov node_long1, host_long1 ' else copy longs for repeated addidion mov node_long2, host_long2 ' copy the next long sub multiplier, #1 :loop call #addi djnz multiplier, #:loop mult_ret ret subt sub host_long1, node_long1 wc ' do first subtraction and write c flag 4 4 subsx host_long2, node_long2 ' do second subtraction subt_ret ret addi add host_long1, node_long1 wc ' do first addition and write c flag addsx host_long2, node_long2 ' do second addition addi_ret ret sub_funct long "s" '' 192 clock cycles min ~ 127 us zero long 0 address res host_ptr res node_ptr res host_long1 res host_long2 res node_long1 res node_long2 res funct res p_cog res multiplier res mask res tmp res temp res mplace res d2 res d1 resNot sure if anyone else will find this helpful but once it's done I will be releasing under MIT license.
This is very interesting to me. I wonder why you have it launch the cog with each call instead of having a normal "Start" method to launch the cog? I don't remember the exact time, but launching a cog takes a bit of time and if one had a lot of math to perform, the current arrangement sure seems like it would slow the process down significantly.
I was envisioning something like F32 that launched a cog and waited for a command.
Did you not what to tie the cog up permanently?
Still doing some sanity checks and it seems to work okay. I do need to put in the comments that mul-div only use 32 bit multiplier / divisor...
Sounds good.
I haven't run into the need for 64-bit math myself but I'm pretty sure it's just a matter of time until I'll need/want it.
Thanks for posting your code.
Lawson
Honestly, no I don't want to keep it that way. Sadly I don't have much time to continue working on this. I have a TON of code to write and my deadline is quickly approaching. It will work for now since 99 iterations won't take that long and it's not called very often. I admit this object still could use quite a bit of work but it will have to wait.
http://academic.evergreen.edu/projects/biophysics/technotes/misc/bin_math.htm
for multiplying two 64 bit numbers that would be 64 iterations of 64 comparisons, then 64 numbers to add together. This would leave you with a 128 bit result. This would be pretty straight forward to program and would be a bit costly to run (~4100 simple math operations plus the add)...but not nearly as costly as adding the multiplicand the multiplier number of times (~2^64 add operations)
Nice job Joe on tackling this problem. Maybe this can be revisited in the future to expand and optimize a 64 bit math library.