Feb 6, 2010 1:02 PM
integer multiplication - stupid assembly question
-
Like (0)
Using the standard mpy instruction works great for fixed-point multiplication. But for regular integer multiplication (e.g., 5*4 = 20) you can't just do this:
move #$5,x0
move #$4,x1
mpy x0,x1,b
Because $000005 and $000004 are really small fractions. You end up getting 0 in b. Is there an equivalent integer multiplication instruction? I haven't found one. Performing the multiplication by a loop of additions is really, really slow.
Edit: ok, I'm confused. The below actually results in the value 0x001e00.
move #$5,x0
move #$3,x1
mpy x0,x1,b
What is going on here? If I take 0x001e00 and shift it down 9 bits I get the answer I'm looking for. Also, $5 comes out as 0x050000 in the GUI. I'm not sure how I got this far without understanding the multiplication (I've got a semi-complicated effect sorta-working).
Think of the integers being scaled by some factor so that all numbers lie in the range [-1,+1). The scaling factor is a tradeoff between magnitude and precision. If the maximum possible value is 20 you could use 1/32 as the scaling factor, but I will use 1/128 in this example so that it is easier to see in the ToneCore UI hex display (not 1/256 - one bit is the sign bit). You need to rescale the multiplication results, which can be done using arithmetic shifts if the scaling factor is a power of 2.
Integer: 5 * 4 = 20
Fixed point: 5/128 *4/128 = 20/16384
multiply by 128 to get 20/128, which is the number you are looking for.
Here is some code:
move #>$050000,x0
move #>$040000,x1
mpy x0,x1,b
asl #7,b,b
move b,x:Debug_Read_from_DSP_4 ; displays 140000
Thanks, RedPanda. It makes sense, I was just hoping for something more automatic. The accumulator shifter part of the processor is somewhat configurable from my read of the 56300 family manual, but I didn't see any option or instruction to prevent it from shifting.
For the data I need to handle I need to spend some time analyzing my algorithm to determine out the right precision to use, but it will work. I guess I could dynamically choose the precision based on the data, but that could burn a lot of cycles.
Stay in the mix and in the know.
Latest offers, special deals and insider updates.