Signed multiply in PASM - need one
Hi Follks
Somehow I painted myself into a corner with the PASM multiply example which is published in the new Prop manual.· I even asked for help on how to use it and was warned about it working with 16 bit values and postive numbers only.· Yet, I went ahead and used my selective reading skills to think it could work with signed numbers.
Now I am stuck and am hoping someone has a PASM multiply routine that can handle signed numbers.
I recall many months ago what I think was one posted by someone and I can't find it again.· I seem to recall the poster's avatar looking like an open cockpit pilot with bugs in his teeth - maybe goes by the name of Cessna pilot.· Even if you can't recall that one in particular, I am not that picky :-)· I just need one that can handle signed values.
Chris
Somehow I painted myself into a corner with the PASM multiply example which is published in the new Prop manual.· I even asked for help on how to use it and was warned about it working with 16 bit values and postive numbers only.· Yet, I went ahead and used my selective reading skills to think it could work with signed numbers.
Now I am stuck and am hoping someone has a PASM multiply routine that can handle signed numbers.
I recall many months ago what I think was one posted by someone and I can't find it again.· I seem to recall the poster's avatar looking like an open cockpit pilot with bugs in his teeth - maybe goes by the name of Cessna pilot.· Even if you can't recall that one in particular, I am not that picky :-)· I just need one that can handle signed values.
Chris

Comments
Chris
This is a signed 32-bit by 32-bit with a 64-bit result.
mov __temp1,mult1 ' mult3 = mult1 * mult2 mov __temp2,mult2 abs __temp1,__temp1 WC ' make values positive, __temp3 holds sign of result muxc __temp3,#1 abs __temp2,__temp2 WC, WZ IF_C xor __temp3,#1 mov __temp4,#0 ' Setup for 32 bits of multiply loop mov __temp5,#32 shr __temp1,#1 WC __L0001 ' Main multiply loop IF_C add __temp4,__temp2 WC rcr __temp4,#1 WC rcr __temp1,#1 WC djnz __temp5,#__L0001 test __temp3,#1 WZ ' Check if result should be negative IF_NZ neg __temp4,__temp4 IF_NZ neg __temp1,__temp1 WZ IF_NZ sub __temp4,#1 mov mult3,__temp1 ' Store lower 32-bit of result, __temp4 = upper 32-bits of result__temp1 is the lower 32-bits of the result
__temp4 is the upper 32-bits of the result
Bean
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Use BASIC on the Propeller with the speed of assembly language.
PropBASIC thread http://forums.parallax.com/showthread.php?p=867134
March 2010 Nuts and Volts article·http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp5.pdf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
There are two rules in life:
· 1) Never divulge all information
Post Edited (Bean) : 4/11/2010 2:38:40 PM GMT
Thank you VERY MUCH!· I will give that a go and see if I can get it working for me.
Chris
Any chance of there being an equivalent divide routine?
Thanks,
Parsko
mov __temp1,__param2 ' __param1 = __param2 / __param3 mov __temp2,__param3 mov __temp4,#0 ' Set result to zero ' Get sign of result in __temp5 while making values positive abs __temp1,__temp1 WC ' __temp1 = abs(__temp1) carry is set if __temp1 was negative muxc __temp5,#1 ' If carry was set set __temp5 to 1 (1 means result is negative) abs __temp2,__temp2 WC, WZ ' __temp2 = abs(__temp2) carry is set if __temp2 was negative, and zero flag is set if __temp2 is zero IF_Z mov __temp1,#0 ' If divisor is zero return zero IF_Z jmp #__L0001 IF_C xor __temp5,#1 ' If __temp2 was negative then invert result sign (neg / neg = pos) ' Shift dividend until a 1 is in the MSB mov __temp3,#0 ' __temp3 counts how many shifts min __temp2,#1 ' Make sure __temp2 is not zero __L0002 add __temp3,#1 shl __temp2,#1 WC IF_NC jmp #__L0002 rcr __temp2,#1 ' This is the main divide loop __L0003 cmpsub __temp1,__temp2 WC rcl __temp4,#1 shr __temp2,#1 djnz __temp3,#__L0003 ' Handle result sign test __temp5,#1 WZ ' Should result be negative ? IF_NZ neg __temp4,__temp4 ' If negative, negate result IF_NZ neg __temp1,__temp1 ' and also negate remainder too __L0001 mov __param1,__temp4The remainder is in __temp1 after the routine.
You can strip a lot of code if your values are always positive.
Bean