void
mulparam(ulong m, Mparam *mp)
{
int c, i, j, n, o, q, s;
int bc, bi, bn, bo, bq, bs, bt;
char *p;
long u;
ulong t;
bc = bq = 10;
bi = bn = bo = bs = bt = 0;
for(i = 0; i < nelem(malgs); i++) {
for(p = malgs[i].vals, j = 0; (o = p[j]) < 100; j++)
for(s = 0; s < 2; s++) {
c = 10;
q = 10;
u = m - o;
if(u == 0)
continue;
if(s) {
o = -o;
if(o > 0)
continue;
u = -u;
}
n = lowbit(u);
t = (ulong)u >> n;
switch(i) {
case 0:
if(t == 1) {
c = s + 1;
q = 0;
break;
}
switch(t) {
case 3:
case 5:
case 9:
c = s + 1;
if(n)
c++;
q = 0;
break;
}
if(s)
break;
switch(t) {
case 15:
case 25:
case 27:
case 45:
case 81:
c = 2;
if(n)
c++;
q = 1;
break;
}
break;
case 1:
if(t == 1) {
c = 3;
q = 3;
break;
}
switch(t) {
case 3:
case 5:
case 9:
c = 3;
q = 2;
break;
}
break;
case 2:
if(t == 1) {
c = 3;
q = 2;
break;
}
break;
case 3:
if(s)
break;
if(t == 1) {
c = 3;
q = 1;
break;
}
break;
case 4:
if(t == 1) {
c = 3;
q = 0;
break;
}
break;
}
if(c < bc || (c == bc && q > bq)) {
bc = c;
bi = i;
bn = n;
bo = o;
bq = q;
bs = s;
bt = t;
}
}
}
mp->value = m;
if(bc <= 3) {
mp->alg = bi;
mp->shift = bn;
mp->off = bo;
mp->neg = bs;
mp->arg = bt;
}
else
mp->alg = -1;
}
int
m0(int a)
{
switch(a) {
case -2:
case 2:
return 2;
case -3:
case 3:
return 2;
case -4:
case 4:
return 4;
case -5:
case 5:
return 4;
case 6:
return 2;
case -8:
case 8:
return 8;
case -9:
case 9:
return 8;
case 10:
return 4;
case 12:
return 2;
case 15:
return 2;
case 18:
return 8;
case 20:
return 4;
case 24:
return 2;
case 25:
return 4;
case 27:
return 2;
case 36:
return 8;
case 40:
return 4;
case 45:
return 4;
case 72:
return 8;
case 81:
return 8;
}
diag(Z, "bad m0");
return 0;
}
int
m1(int a)
{
switch(a) {
case 15:
return 4;
case 25:
return 4;
case 27:
return 8;
case 45:
return 8;
case 81:
return 8;
}
diag(Z, "bad m1");
return 0;
}
int
m2(int a)
{
switch(a) {
case 6:
return 2;
case 10:
return 2;
case 12:
return 4;
case 18:
return 2;
case 20:
return 4;
case 24:
return 8;
case 36:
return 4;
case 40:
return 8;
case 72:
return 8;
}
diag(Z, "bad m2");
return 0;
}
void
shiftit(Type *t, Node *s, Node *d)
{
long c;
c = (long)s->vconst & 31;
switch(c) {
case 0:
break;
case 1:
gopcode(OADD, t, d, d);
break;
default:
gopcode(OASHL, t, s, d);
}
}
static int
mulgen1(ulong v, Node *n)
{
int i, o;
Mparam *p;
Node nod, nods;
if(v == 0){
zeroregm(n);
return 1;
}
for(i = 0; i < nelem(multab); i++) {
p = &multab[i];
if(p->value == v)
goto found;
}
p = &multab[mulptr];
if(++mulptr == nelem(multab))
mulptr = 0;