p = code;
if(p[1] == 'i')
p += 2;
regalloc(&nod1, n, nn);
cgen(l, &nod1);
if(v < 0)
gopcode(ONEG, &nod1, Z, &nod1);
regalloc(&nod2, n, Z);
loop:
switch(*p) {
case 0:
regfree(&nod2);
gopcode(OAS, &nod1, Z, nn);
regfree(&nod1);
return 1;
case '+':
o = OADD;
goto addsub;
case '-':
o = OSUB;
addsub: /* number is r,n,l */
v = p[1] - '0';
r = &nod1;
if(v&4)
r = &nod2;
n = &nod1;
if(v&2)
n = &nod2;
l = &nod1;
if(v&1)
l = &nod2;
gopcode(o, l, n, r);
break;
default: /* op is shiftcount, number is r,l */
v = p[1] - '0';
r = &nod1;
if(v&2)
r = &nod2;
l = &nod1;
if(v&1)
l = &nod2;
v = *p - 'a';
if(v < 0 || v >= 32) {
diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
break;
}
gopcode(OASHL, nodconst(v), l, r);
break;
}
p += 2;
goto loop;
}
void
sextern(Sym *s, Node *a, long o, long w)
{
long e, lw;
case TARRAY:
for(v=t; v->etype==TARRAY; v=v->link)
;
return v->etype == TDOUBLE;
case TSTRUCT:
case TUNION:
for(v = t->link; v != T; v = v->down)
if(doubled(v))
return 1;
break;
}
return 0;
}
long
align(long i, Type *t, int op)
{
long o;
Type *v;
int w, pc;
o = i;
w = 1;
pc = 0;
switch(op) {
default:
diag(Z, "unknown align opcode %d", op);
break;
case Asu2: /* padding at end of a struct */
w = doubled(t)? SZ_DOUBLE: SZ_LONG;
if(packflg)
w = packflg;
break;
case Ael1: /* initial align of struct element (also automatic) */
for(v=t; v->etype==TARRAY; v=v->link)
;
w = ewidth[v->etype];
if(w <= 0 || w >= SZ_LONG){
if(doubled(v)){
w = SZ_DOUBLE;
doubleflag = 1;
}else
w = SZ_LONG;
}
if(packflg)
w = packflg;
break;
case Ael2: /* width of a struct element */
o += t->width;
break;
case Aarg0: /* initial passbyptr argument in arg list */
if(typesuv[t->etype]) {
o = align(o, types[TIND], Aarg1);
o = align(o, types[TIND], Aarg2);
}
break;
case Aarg1: /* initial align of parameter */
w = ewidth[t->etype];
if(w <= 0 || w >= SZ_LONG) {
if(doubled(t)){
w = SZ_DOUBLE;
pc = SZ_LONG; /* alignment must account for pc */
hasdoubled = 1;
}else
w = SZ_LONG;
break;
}
o += SZ_LONG - w; /* big endian adjustment */
w = 1;
break;
case Aarg2: /* width of a parameter */
o += t->width;
w = SZ_LONG;
if(doubled(t)){
pc = SZ_LONG;
hasdoubled = 1;
}
break;
case Aaut3: /* total align of automatic */
doubleflag = 0;
o = align(o, t, Ael1);
o = align(o, t, Ael2);
hasdoubled |= doubleflag;
break;
}
o = round(o+pc, w)-pc;
if(debug['A'])
print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
return o;
}
long
maxround(long max, long v)
{
int w;
w = SZ_LONG;
if((debug['8'] || hasdoubled) && !debug['4'])
w = SZ_DOUBLE;
v = round(v, w);
if(v > max)
return v;
return max;
}