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