#define ITERATIONS 3 #define N (3 * ITERATIONS) /* number of bits in the input numbers */ #define HI_OVERFLOW 3 #define BITS_IN_INT 32 #define HI_HALF (BITS_IN_INT - HI_OVERFLOW - N) #define LO_HALF (HI_HALF - N) /* #define ADD_ACC(P,B) (P += ((B) << HI_HALF)) */ #define ADD_ACC(P,B) add_acc(&P, B) #define GET_RESULT(P) (((P << HI_OVERFLOW) >> HI_OVERFLOW) >> LO_HALF) #define GET_LOW_FOUR(P) ((P >> (LO_HALF -1)) & 0x0f) void add_acc(int* p, int b){ int a = b << HI_HALF; *p += a; } typedef enum { zero, plusB, plus2B, plus3B, plus4B, subB, sub2B, sub3B, sub4B } command; static const command command_table[16] = { zero, plusB, plusB, plus2B, plus2B, plus3B, plus3B, plus4B, sub4B, sub3B, sub3B, sub2B, sub2B, subB, subB, zero }; int mul(int a, int b) { int p = 0; int i; int threeB; a &= ((1 << N) - 1); /* b &= ((1 << N) - 1); */ p = (a << LO_HALF); threeB = b + (b << 1); for(i = 0; i < ITERATIONS; ++i){ switch( command_table[ GET_LOW_FOUR(p) ] ){ case plusB: ADD_ACC(p,b); break; case plus2B: ADD_ACC(p,b << 1); break; case plus3B: ADD_ACC(p,threeB); break; case plus4B: ADD_ACC(p,b << 2); break; case subB: ADD_ACC(p,-b); break; case sub2B: ADD_ACC(p,-(b << 1)); break; case sub3B: ADD_ACC(p,-threeB); break; case sub4B: ADD_ACC(p,-(b << 2)); break; case zero: default: } p >>= 3; } return GET_RESULT(p); }