[gnu.gcc.bug] "Better" open-coded multiply for the sparc

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;
    }
}