How to do an ASM signed multiply.
Kye
Posts: 2,200
I've been trying to do a signed multiply in ASM - 16x16. But I've come up with a piece of code that seems just a bit rather unoptimized:
So the input would be sampleBuffer and multiply buffer and the output is sampleBuffer. Sample buffer contains a signed value on entry while mulitply buffer does not. Multiply buffer basically holds a volume from 0 to 65535 which is used to scale the sample.
So, is there a better way to do this?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
abs sampleBuffer, sampleBuffer wc ' Store sign. muxc multiplyTest, #1 ' multiplicand rdword multiplyBuffer, leftVolumeAddress ' Setup inputs. shl sampleBuffer, #16 ' shr multiplyBuffer, #1 wc ' mov multiplyCounter, #16 ' Setup counter multiplyLoop if_c add multiplyBuffer, sampleBuffer wc ' Preform multiplication. rcr multiplyBuffer, #1 wc ' djnz multiplyCounter, #multiplyLoop ' Repeat. multiplyTest test multiplyTest, #1 wc ' Negate/swap negc sampleBuffer, multiplyBuffer '
So the input would be sampleBuffer and multiply buffer and the output is sampleBuffer. Sample buffer contains a signed value on entry while mulitply buffer does not. Multiply buffer basically holds a volume from 0 to 65535 which is used to scale the sample.
So, is there a better way to do this?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Comments
Remember that you have to xor both signs and if you get a 1 then the result will be negative... in your code you are ignoring the sign of multiplyBuffer unless you know it will not be negative... You do not use the Z flag so you could use it to store the sign and then use negz, sorry it is 7:15 in the morning and I have to get ready to work and I cannot test your code right now... maybe later I can do it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
In both cases the negative number has to be a 32 bit quantity for abs to work.
Depending on what you call optimizations... if you want speed or you prefer smaller code size... you cam either unroll the loop..
Another piece of code could be this one. The loop is longer but if you do not have higher bits set in y it could be shorter... note the nice trick to use the Z flag to contain the sign of the number
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
Okay, I'll use this code variant.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,