paul@UUNET.UU.NET (Paul Hudson) (02/14/89)
The following bit of (poorly written) code seems to do a better job
of finding shifts and add/subs to do constant multiplies than
output_mul_by_constant from output-sparc.c.
If the sparc had decent instructiions like the Acorn RISC Machine, an even
better job could be done! (The arm allows one operand of an move or add
to be shifted, so shift+add, shift+sub and shift+reverse-sub are all possible).
Go stick your head in a pig!
(For those who don't know, this is what the slogan of the Sirius Cybernetics
Corporation says when it's half embedded in the ground. When not so embedded,
it says "Share and Enjoy!").
Paul Hudson
Snail mail: Monotype ADG Email: ...!ukc!acorn!moncam!paul
Science Park, paul@moncam.co.uk
Milton Road, "Sun Microsysytems:
Cambridge, The Company is Arrogant (TM)"
CB4 4FQ
int domul(c)
{
int first = 1;
int n;
int c2;
int ones, zeros;
char *op;
/* find the topmost bit, counting the 0's as we go */
c2 = c;
ones = 0;
zeros = 0;
while (c2)
{
if (c2 & 01)
ones += 1;
else
zeros += 1;
c2 >>= 1;
}
if (ones > zeros + 1)
{
/* peek ahead to find which shift of "a" we'll want first */
c = (1 << (ones + zeros)) - c;
for (n = 0; (c & 01) == 0; n += 1, c >>= 1)
;
if (n)
printf("b = (a << %d)\n", n);
else printf("b = a\n");
printf("a <<= %d\n", (ones + zeros));
printf("a -= b\n");
c -= 1;
first = 0;
op = "-";
}
else
{
op = "+";
for (n = 0; (c & 01) == 0; n += 1, c >>= 1)
;
if (n)
printf("a <<= %d\n", n);
c -= 1;
}
while (c)
{
for (n = 0; (c & 01) == 0; n += 1, c >>= 1)
;
if (first)
{
printf("b = (a << %d)\n", n);
first = 0;
}
else printf("b = (b << %d)\n", n);
printf("a %s= b\n", op);
c -= 1;
}
}