32-bit multiplication via 16-bit offset

I am writing a soft multiplication function call using shift and add. An existing function call is as follows:

unsigned long __mulsi3 (unsigned long a, unsigned long b) {

    unsigned long answer = 0;

    while(b)
    {
        if(b & 1) {
            answer += a;
        };

        a <<= 1;
        b >>= 1;
    }
    return answer;
}

Although my equipment does not have a multiplier, I have a hard shift. The switch is capable of shifting up to 16 bits at a time.

If I want to make full use of my 16-bit shift. Any suggestions on how I can adapt the code above to reflect my hardware capabilities? This code only shifts 1 bit per iteration.

A 16-bit shifter can shift 32-bit unsigned long values ​​up to 16 places at a time. Sizeof (unsigned long) == 32 bits

+4
4

( 1): -

  • 16
  • 16 16
  • 16

...

: -

  • , unsigned long - 32
  • , Big Endian

: -

 union Data32
        {
           unsigned long l;
           unsigned short s[2];
        }; 

unsigned long shiftleft32(unsigned long valueToShift, unsigned short bitsToShift)
{
    union Data32 u;
    u.l  = valueToShift
    u.s[0] <<= bitsToShift;
    u.s[0] |= (u.s[1] >> (16 - bitsToShift);
    u.s[1] <<= bitsToShift

    return u.l;
}

0

16- , :

(U1 * P + U0) * (V1 * P + V0) =
= U1 * V1 * P * P + U1 * V0 * P + U0 * V1 * P + U0 * V0 =
= U1 * V1 * (P*P+P) + (U1-U0) * (V0-V1) * P + U0 * V0 * (1-P)

, P - 2 (, 2 ^ 16, 2 ^ 32), - . 4 3 , , O (N ^ 1,58) O (N ^ 2) .

. .

(, 8 8 ) , :

a * b = square(a+b)/4 - square(a-b)/4

int(square(x)/4), 1022 510 .

+1

, :

:

    0101
  * 0111
  -------
    0101
   0101.
  0101..
 --------
  100011

, , , 1- ! , , :

unsigned long _mult(unsigned long a, unsigned long b)
{
    unsigned long res =0;

    while (a > 0)
    {
        res += b;
        a--;
    }

    return res;
} 

, , , (, ...)

0

, , 8 x 8 , RAM/ROM () 4- 4- .

( ) , .

16- , 32- "a" "a1: a0" 16- , "b", . 32 , "a1 * b1" - , ! , ls 16- "a0 * b1", 16-, b1 ( b <= a) , , , "a * b0" 32- "a" 32- "", - 16 ..., .

- .

FWIW: "a1 * b1", "(a1-a0) * (b0-b1)", "a0 * b0" , , , ... "(a1-a0)", "(b0-b1)" , , . , , , ! , ... ... , - .

0

All Articles