mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
gc: align structs according to max alignment of fields
cc: same runtime: test cc alignment (required moving #define of offsetof to runtime.h) fix bug260 Fixes #482. Fixes #609. R=ken2, r CC=golang-dev https://golang.org/cl/3563042
This commit is contained in:
parent
287e45e241
commit
dc9a3b2791
22 changed files with 148 additions and 91 deletions
|
|
@ -606,7 +606,7 @@ zaddr(char *bp, Adr *a, int s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
align(int32 i, Type *t, int op)
|
align(int32 i, Type *t, int op, int32 *maxalign)
|
||||||
{
|
{
|
||||||
int32 o;
|
int32 o;
|
||||||
Type *v;
|
Type *v;
|
||||||
|
|
@ -620,7 +620,9 @@ align(int32 i, Type *t, int op)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Asu2: /* padding at end of a struct */
|
case Asu2: /* padding at end of a struct */
|
||||||
w = SZ_LONG;
|
w = *maxalign;
|
||||||
|
if(w < 1)
|
||||||
|
w = 1;
|
||||||
if(packflg)
|
if(packflg)
|
||||||
w = packflg;
|
w = packflg;
|
||||||
break;
|
break;
|
||||||
|
|
@ -628,10 +630,16 @@ align(int32 i, Type *t, int op)
|
||||||
case Ael1: /* initial align of struct element */
|
case Ael1: /* initial align of struct element */
|
||||||
for(v=t; v->etype==TARRAY; v=v->link)
|
for(v=t; v->etype==TARRAY; v=v->link)
|
||||||
;
|
;
|
||||||
w = ewidth[v->etype];
|
if(v->etype == TSTRUCT || v->etype == TUNION)
|
||||||
if(w <= 0 || w >= SZ_LONG)
|
w = v->align;
|
||||||
w = SZ_LONG;
|
else {
|
||||||
if(packflg)
|
w = ewidth[v->etype];
|
||||||
|
if(w == 8)
|
||||||
|
w = 4;
|
||||||
|
}
|
||||||
|
if(w < 1 || w > SZ_LONG)
|
||||||
|
fatal(Z, "align");
|
||||||
|
if(packflg)
|
||||||
w = packflg;
|
w = packflg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -641,8 +649,8 @@ align(int32 i, Type *t, int op)
|
||||||
|
|
||||||
case Aarg0: /* initial passbyptr argument in arg list */
|
case Aarg0: /* initial passbyptr argument in arg list */
|
||||||
if(typesuv[t->etype]) {
|
if(typesuv[t->etype]) {
|
||||||
o = align(o, types[TIND], Aarg1);
|
o = align(o, types[TIND], Aarg1, nil);
|
||||||
o = align(o, types[TIND], Aarg2);
|
o = align(o, types[TIND], Aarg2, nil);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -661,12 +669,14 @@ align(int32 i, Type *t, int op)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Aaut3: /* total align of automatic */
|
case Aaut3: /* total align of automatic */
|
||||||
o = align(o, t, Ael2);
|
o = align(o, t, Ael2, nil);
|
||||||
o = align(o, t, Ael1);
|
o = align(o, t, Ael1, nil);
|
||||||
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
|
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
o = xround(o, w);
|
o = xround(o, w);
|
||||||
|
if(maxalign != nil && *maxalign < w)
|
||||||
|
*maxalign = w;
|
||||||
if(debug['A'])
|
if(debug['A'])
|
||||||
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
||||||
return o;
|
return o;
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,7 @@ err:
|
||||||
void
|
void
|
||||||
regsalloc(Node *n, Node *nn)
|
regsalloc(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
cursafe = align(cursafe, nn->type, Aaut3);
|
cursafe = align(cursafe, nn->type, Aaut3, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
*n = *nodsafe;
|
*n = *nodsafe;
|
||||||
n->xoffset = -(stkoff + cursafe);
|
n->xoffset = -(stkoff + cursafe);
|
||||||
|
|
@ -402,22 +402,22 @@ regaalloc1(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
nodreg(n, nn, REGARG);
|
nodreg(n, nn, REGARG);
|
||||||
reg[REGARG]++;
|
reg[REGARG]++;
|
||||||
curarg = align(curarg, nn->type, Aarg1);
|
curarg = align(curarg, nn->type, Aarg1, nil);
|
||||||
curarg = align(curarg, nn->type, Aarg2);
|
curarg = align(curarg, nn->type, Aarg2, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regaalloc(Node *n, Node *nn)
|
regaalloc(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
curarg = align(curarg, nn->type, Aarg1);
|
curarg = align(curarg, nn->type, Aarg1, nil);
|
||||||
*n = *nn;
|
*n = *nn;
|
||||||
n->op = OINDREG;
|
n->op = OINDREG;
|
||||||
n->reg = REGSP;
|
n->reg = REGSP;
|
||||||
n->xoffset = curarg + SZ_LONG;
|
n->xoffset = curarg + SZ_LONG;
|
||||||
n->complex = 0;
|
n->complex = 0;
|
||||||
n->addable = 20;
|
n->addable = 20;
|
||||||
curarg = align(curarg, nn->type, Aarg2);
|
curarg = align(curarg, nn->type, Aarg2, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1928,7 +1928,7 @@ vaddr(Node *n, int a)
|
||||||
int32
|
int32
|
||||||
hi64v(Node *n)
|
hi64v(Node *n)
|
||||||
{
|
{
|
||||||
if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
|
if(align(0, types[TCHAR], Aarg1, nil)) /* isbigendian */
|
||||||
return (int32)(n->vconst) & ~0L;
|
return (int32)(n->vconst) & ~0L;
|
||||||
else
|
else
|
||||||
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
||||||
|
|
@ -1937,7 +1937,7 @@ hi64v(Node *n)
|
||||||
int32
|
int32
|
||||||
lo64v(Node *n)
|
lo64v(Node *n)
|
||||||
{
|
{
|
||||||
if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
|
if(align(0, types[TCHAR], Aarg1, nil)) /* isbigendian */
|
||||||
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
||||||
else
|
else
|
||||||
return (int32)(n->vconst) & ~0L;
|
return (int32)(n->vconst) & ~0L;
|
||||||
|
|
|
||||||
|
|
@ -503,7 +503,7 @@ zaddr(Biobuf *b, Adr *a, int s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
align(int32 i, Type *t, int op)
|
align(int32 i, Type *t, int op, int32 *maxalign)
|
||||||
{
|
{
|
||||||
int32 o;
|
int32 o;
|
||||||
Type *v;
|
Type *v;
|
||||||
|
|
@ -517,7 +517,9 @@ align(int32 i, Type *t, int op)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Asu2: /* padding at end of a struct */
|
case Asu2: /* padding at end of a struct */
|
||||||
w = SZ_VLONG;
|
w = *maxalign;
|
||||||
|
if(w < 1)
|
||||||
|
w = 1;
|
||||||
if(packflg)
|
if(packflg)
|
||||||
w = packflg;
|
w = packflg;
|
||||||
break;
|
break;
|
||||||
|
|
@ -525,10 +527,13 @@ align(int32 i, Type *t, int op)
|
||||||
case Ael1: /* initial align of struct element */
|
case Ael1: /* initial align of struct element */
|
||||||
for(v=t; v->etype==TARRAY; v=v->link)
|
for(v=t; v->etype==TARRAY; v=v->link)
|
||||||
;
|
;
|
||||||
w = ewidth[v->etype];
|
if(v->etype == TSTRUCT || v->etype == TUNION)
|
||||||
if(w <= 0 || w >= SZ_VLONG)
|
w = v->align;
|
||||||
w = SZ_VLONG;
|
else
|
||||||
if(packflg)
|
w = ewidth[v->etype];
|
||||||
|
if(w < 1 || w > SZ_VLONG)
|
||||||
|
fatal(Z, "align");
|
||||||
|
if(packflg)
|
||||||
w = packflg;
|
w = packflg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -538,8 +543,8 @@ align(int32 i, Type *t, int op)
|
||||||
|
|
||||||
case Aarg0: /* initial passbyptr argument in arg list */
|
case Aarg0: /* initial passbyptr argument in arg list */
|
||||||
if(typesu[t->etype]) {
|
if(typesu[t->etype]) {
|
||||||
o = align(o, types[TIND], Aarg1);
|
o = align(o, types[TIND], Aarg1, nil);
|
||||||
o = align(o, types[TIND], Aarg2);
|
o = align(o, types[TIND], Aarg2, nil);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -560,11 +565,13 @@ align(int32 i, Type *t, int op)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Aaut3: /* total align of automatic */
|
case Aaut3: /* total align of automatic */
|
||||||
o = align(o, t, Ael1);
|
o = align(o, t, Ael1, nil);
|
||||||
o = align(o, t, Ael2);
|
o = align(o, t, Ael2, nil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
o = xround(o, w);
|
o = xround(o, w);
|
||||||
|
if(maxalign && *maxalign < w)
|
||||||
|
*maxalign = w;
|
||||||
if(debug['A'])
|
if(debug['A'])
|
||||||
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
||||||
return o;
|
return o;
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ err:
|
||||||
void
|
void
|
||||||
regsalloc(Node *n, Node *nn)
|
regsalloc(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
cursafe = align(cursafe, nn->type, Aaut3);
|
cursafe = align(cursafe, nn->type, Aaut3, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
*n = *nodsafe;
|
*n = *nodsafe;
|
||||||
n->xoffset = -(stkoff + cursafe);
|
n->xoffset = -(stkoff + cursafe);
|
||||||
|
|
@ -440,22 +440,22 @@ regaalloc1(Node *n, Node *nn)
|
||||||
diag(n, "regaalloc1 and REGARG<0");
|
diag(n, "regaalloc1 and REGARG<0");
|
||||||
nodreg(n, nn, REGARG);
|
nodreg(n, nn, REGARG);
|
||||||
reg[REGARG]++;
|
reg[REGARG]++;
|
||||||
curarg = align(curarg, nn->type, Aarg1);
|
curarg = align(curarg, nn->type, Aarg1, nil);
|
||||||
curarg = align(curarg, nn->type, Aarg2);
|
curarg = align(curarg, nn->type, Aarg2, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regaalloc(Node *n, Node *nn)
|
regaalloc(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
curarg = align(curarg, nn->type, Aarg1);
|
curarg = align(curarg, nn->type, Aarg1, nil);
|
||||||
*n = *nn;
|
*n = *nn;
|
||||||
n->op = OINDREG;
|
n->op = OINDREG;
|
||||||
n->reg = REGSP;
|
n->reg = REGSP;
|
||||||
n->xoffset = curarg;
|
n->xoffset = curarg;
|
||||||
n->complex = 0;
|
n->complex = 0;
|
||||||
n->addable = 20;
|
n->addable = 20;
|
||||||
curarg = align(curarg, nn->type, Aarg2);
|
curarg = align(curarg, nn->type, Aarg2, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ vaddr(Node *n, int a)
|
||||||
int32
|
int32
|
||||||
hi64v(Node *n)
|
hi64v(Node *n)
|
||||||
{
|
{
|
||||||
if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
|
if(align(0, types[TCHAR], Aarg1, nil)) /* isbigendian */
|
||||||
return (int32)(n->vconst) & ~0L;
|
return (int32)(n->vconst) & ~0L;
|
||||||
else
|
else
|
||||||
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
||||||
|
|
@ -66,7 +66,7 @@ hi64v(Node *n)
|
||||||
int32
|
int32
|
||||||
lo64v(Node *n)
|
lo64v(Node *n)
|
||||||
{
|
{
|
||||||
if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
|
if(align(0, types[TCHAR], Aarg1, nil)) /* isbigendian */
|
||||||
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
return (int32)((uvlong)n->vconst>>32) & ~0L;
|
||||||
else
|
else
|
||||||
return (int32)(n->vconst) & ~0L;
|
return (int32)(n->vconst) & ~0L;
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,7 @@ zaddr(Biobuf *b, Adr *a, int s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
align(int32 i, Type *t, int op)
|
align(int32 i, Type *t, int op, int32 *maxalign)
|
||||||
{
|
{
|
||||||
int32 o;
|
int32 o;
|
||||||
Type *v;
|
Type *v;
|
||||||
|
|
@ -515,7 +515,9 @@ align(int32 i, Type *t, int op)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Asu2: /* padding at end of a struct */
|
case Asu2: /* padding at end of a struct */
|
||||||
w = SZ_LONG;
|
w = *maxalign;
|
||||||
|
if(w < 1)
|
||||||
|
w = 1;
|
||||||
if(packflg)
|
if(packflg)
|
||||||
w = packflg;
|
w = packflg;
|
||||||
break;
|
break;
|
||||||
|
|
@ -523,10 +525,16 @@ align(int32 i, Type *t, int op)
|
||||||
case Ael1: /* initial align of struct element */
|
case Ael1: /* initial align of struct element */
|
||||||
for(v=t; v->etype==TARRAY; v=v->link)
|
for(v=t; v->etype==TARRAY; v=v->link)
|
||||||
;
|
;
|
||||||
w = ewidth[v->etype];
|
if(v->etype == TSTRUCT || v->etype == TUNION)
|
||||||
if(w <= 0 || w >= SZ_LONG)
|
w = v->align;
|
||||||
w = SZ_LONG;
|
else {
|
||||||
if(packflg)
|
w = ewidth[v->etype];
|
||||||
|
if(w == 8)
|
||||||
|
w = 4;
|
||||||
|
}
|
||||||
|
if(w < 1 || w > SZ_LONG)
|
||||||
|
fatal(Z, "align");
|
||||||
|
if(packflg)
|
||||||
w = packflg;
|
w = packflg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -536,8 +544,8 @@ align(int32 i, Type *t, int op)
|
||||||
|
|
||||||
case Aarg0: /* initial passbyptr argument in arg list */
|
case Aarg0: /* initial passbyptr argument in arg list */
|
||||||
if(typesuv[t->etype]) {
|
if(typesuv[t->etype]) {
|
||||||
o = align(o, types[TIND], Aarg1);
|
o = align(o, types[TIND], Aarg1, nil);
|
||||||
o = align(o, types[TIND], Aarg2);
|
o = align(o, types[TIND], Aarg2, nil);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -558,11 +566,13 @@ align(int32 i, Type *t, int op)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Aaut3: /* total align of automatic */
|
case Aaut3: /* total align of automatic */
|
||||||
o = align(o, t, Ael1);
|
o = align(o, t, Ael1, nil);
|
||||||
o = align(o, t, Ael2);
|
o = align(o, t, Ael2, nil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
o = xround(o, w);
|
o = xround(o, w);
|
||||||
|
if(maxalign && *maxalign < w)
|
||||||
|
*maxalign = w;
|
||||||
if(debug['A'])
|
if(debug['A'])
|
||||||
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
||||||
return o;
|
return o;
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ err:
|
||||||
void
|
void
|
||||||
regsalloc(Node *n, Node *nn)
|
regsalloc(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
cursafe = align(cursafe, nn->type, Aaut3);
|
cursafe = align(cursafe, nn->type, Aaut3, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
*n = *nodsafe;
|
*n = *nodsafe;
|
||||||
n->xoffset = -(stkoff + cursafe);
|
n->xoffset = -(stkoff + cursafe);
|
||||||
|
|
@ -399,22 +399,22 @@ regaalloc1(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
nodreg(n, nn, REGARG);
|
nodreg(n, nn, REGARG);
|
||||||
reg[REGARG]++;
|
reg[REGARG]++;
|
||||||
curarg = align(curarg, nn->type, Aarg1);
|
curarg = align(curarg, nn->type, Aarg1, nil);
|
||||||
curarg = align(curarg, nn->type, Aarg2);
|
curarg = align(curarg, nn->type, Aarg2, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regaalloc(Node *n, Node *nn)
|
regaalloc(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
curarg = align(curarg, nn->type, Aarg1);
|
curarg = align(curarg, nn->type, Aarg1, nil);
|
||||||
*n = *nn;
|
*n = *nn;
|
||||||
n->op = OINDREG;
|
n->op = OINDREG;
|
||||||
n->reg = REGSP;
|
n->reg = REGSP;
|
||||||
n->xoffset = curarg;
|
n->xoffset = curarg;
|
||||||
n->complex = 0;
|
n->complex = 0;
|
||||||
n->addable = 20;
|
n->addable = 20;
|
||||||
curarg = align(curarg, nn->type, Aarg2);
|
curarg = align(curarg, nn->type, Aarg2, nil);
|
||||||
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
maxargsafe = maxround(maxargsafe, cursafe+curarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,7 @@ struct Type
|
||||||
uchar nbits;
|
uchar nbits;
|
||||||
uchar etype;
|
uchar etype;
|
||||||
uchar garb;
|
uchar garb;
|
||||||
|
uchar align;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define T ((Type*)0)
|
#define T ((Type*)0)
|
||||||
|
|
@ -785,7 +786,7 @@ int32 outlstring(ushort*, int32);
|
||||||
void sextern(Sym*, Node*, int32, int32);
|
void sextern(Sym*, Node*, int32, int32);
|
||||||
void xcom(Node*);
|
void xcom(Node*);
|
||||||
int32 exreg(Type*);
|
int32 exreg(Type*);
|
||||||
int32 align(int32, Type*, int);
|
int32 align(int32, Type*, int, int32*);
|
||||||
int32 maxround(int32, int32);
|
int32 maxround(int32, int32);
|
||||||
|
|
||||||
extern schar ewidth[];
|
extern schar ewidth[];
|
||||||
|
|
|
||||||
|
|
@ -552,9 +552,10 @@ void
|
||||||
sualign(Type *t)
|
sualign(Type *t)
|
||||||
{
|
{
|
||||||
Type *l;
|
Type *l;
|
||||||
int32 o, w;
|
int32 o, w, maxal;
|
||||||
|
|
||||||
o = 0;
|
o = 0;
|
||||||
|
maxal = 0;
|
||||||
switch(t->etype) {
|
switch(t->etype) {
|
||||||
|
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
|
|
@ -577,13 +578,14 @@ sualign(Type *t)
|
||||||
l->sym->name);
|
l->sym->name);
|
||||||
else
|
else
|
||||||
diag(Z, "incomplete structure element");
|
diag(Z, "incomplete structure element");
|
||||||
w = align(w, l, Ael1);
|
w = align(w, l, Ael1, &maxal);
|
||||||
l->offset = w;
|
l->offset = w;
|
||||||
w = align(w, l, Ael2);
|
w = align(w, l, Ael2, &maxal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w = align(w, t, Asu2);
|
w = align(w, t, Asu2, &maxal);
|
||||||
t->width = w;
|
t->width = w;
|
||||||
|
t->align = maxal;
|
||||||
acidtype(t);
|
acidtype(t);
|
||||||
pickletype(t);
|
pickletype(t);
|
||||||
return;
|
return;
|
||||||
|
|
@ -600,12 +602,13 @@ sualign(Type *t)
|
||||||
diag(Z, "incomplete union element");
|
diag(Z, "incomplete union element");
|
||||||
l->offset = 0;
|
l->offset = 0;
|
||||||
l->shift = 0;
|
l->shift = 0;
|
||||||
o = align(align(0, l, Ael1), l, Ael2);
|
o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal);
|
||||||
if(o > w)
|
if(o > w)
|
||||||
w = o;
|
w = o;
|
||||||
}
|
}
|
||||||
w = align(w, t, Asu2);
|
w = align(w, t, Asu2, &maxal);
|
||||||
t->width = w;
|
t->width = w;
|
||||||
|
t->align = maxal;
|
||||||
acidtype(t);
|
acidtype(t);
|
||||||
pickletype(t);
|
pickletype(t);
|
||||||
return;
|
return;
|
||||||
|
|
@ -663,7 +666,7 @@ argmark(Node *n, int pass)
|
||||||
{
|
{
|
||||||
Type *t;
|
Type *t;
|
||||||
|
|
||||||
autoffset = align(0, thisfn->link, Aarg0);
|
autoffset = align(0, thisfn->link, Aarg0, nil);
|
||||||
stkoff = 0;
|
stkoff = 0;
|
||||||
for(; n->left != Z; n = n->left) {
|
for(; n->left != Z; n = n->left) {
|
||||||
if(n->op != OFUNC || n->left->op != ONAME)
|
if(n->op != OFUNC || n->left->op != ONAME)
|
||||||
|
|
@ -745,9 +748,9 @@ loop:
|
||||||
firstarg = s;
|
firstarg = s;
|
||||||
firstargtype = s->type;
|
firstargtype = s->type;
|
||||||
}
|
}
|
||||||
autoffset = align(autoffset, s->type, Aarg1);
|
autoffset = align(autoffset, s->type, Aarg1, nil);
|
||||||
s->offset = autoffset;
|
s->offset = autoffset;
|
||||||
autoffset = align(autoffset, s->type, Aarg2);
|
autoffset = align(autoffset, s->type, Aarg2, nil);
|
||||||
} else
|
} else
|
||||||
dodecl(pdecl, CXXX, types[TINT], n);
|
dodecl(pdecl, CXXX, types[TINT], n);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1275,7 +1278,7 @@ adecl(int c, Type *t, Sym *s)
|
||||||
}
|
}
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case CAUTO:
|
case CAUTO:
|
||||||
autoffset = align(autoffset, t, Aaut3);
|
autoffset = align(autoffset, t, Aaut3, nil);
|
||||||
stkoff = maxround(stkoff, autoffset);
|
stkoff = maxround(stkoff, autoffset);
|
||||||
s->offset = -autoffset;
|
s->offset = -autoffset;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1285,10 +1288,10 @@ adecl(int c, Type *t, Sym *s)
|
||||||
firstarg = s;
|
firstarg = s;
|
||||||
firstargtype = t;
|
firstargtype = t;
|
||||||
}
|
}
|
||||||
autoffset = align(autoffset, t, Aarg1);
|
autoffset = align(autoffset, t, Aarg1, nil);
|
||||||
if(s)
|
if(s)
|
||||||
s->offset = autoffset;
|
s->offset = autoffset;
|
||||||
autoffset = align(autoffset, t, Aarg2);
|
autoffset = align(autoffset, t, Aarg2, nil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1587,7 +1590,7 @@ contig(Sym *s, Node *n, int32 v)
|
||||||
if(v != 0)
|
if(v != 0)
|
||||||
diag(n, "automatic adjustable array: %s", s->name);
|
diag(n, "automatic adjustable array: %s", s->name);
|
||||||
v = s->offset;
|
v = s->offset;
|
||||||
autoffset = align(autoffset, s->type, Aaut3);
|
autoffset = align(autoffset, s->type, Aaut3, nil);
|
||||||
s->offset = -autoffset;
|
s->offset = -autoffset;
|
||||||
stkoff = maxround(stkoff, autoffset);
|
stkoff = maxround(stkoff, autoffset);
|
||||||
symadjust(s, n, v - s->offset);
|
symadjust(s, n, v - s->offset);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ argsize(void)
|
||||||
int32 s;
|
int32 s;
|
||||||
|
|
||||||
//print("t=%T\n", thisfn);
|
//print("t=%T\n", thisfn);
|
||||||
s = align(0, thisfn->link, Aarg0);
|
s = align(0, thisfn->link, Aarg0, nil);
|
||||||
for(t=thisfn->down; t!=T; t=t->down) {
|
for(t=thisfn->down; t!=T; t=t->down) {
|
||||||
switch(t->etype) {
|
switch(t->etype) {
|
||||||
case TVOID:
|
case TVOID:
|
||||||
|
|
@ -47,8 +47,8 @@ argsize(void)
|
||||||
s += 64;
|
s += 64;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
s = align(s, t, Aarg1);
|
s = align(s, t, Aarg1, nil);
|
||||||
s = align(s, t, Aarg2);
|
s = align(s, t, Aarg2, nil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//print(" %d %T\n", s, t);
|
//print(" %d %T\n", s, t);
|
||||||
|
|
@ -99,7 +99,7 @@ codgen(Node *n, Node *nn)
|
||||||
nod1 = *nodret->left;
|
nod1 = *nodret->left;
|
||||||
nod1.sym = firstarg;
|
nod1.sym = firstarg;
|
||||||
nod1.type = firstargtype;
|
nod1.type = firstargtype;
|
||||||
nod1.xoffset = align(0, firstargtype, Aarg1);
|
nod1.xoffset = align(0, firstargtype, Aarg1, nil);
|
||||||
nod1.etype = firstargtype->etype;
|
nod1.etype = firstargtype->etype;
|
||||||
nodreg(&nod, &nod1, REGARG);
|
nodreg(&nod, &nod1, REGARG);
|
||||||
gmove(&nod, &nod1);
|
gmove(&nod, &nod1);
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ outlstring(ushort *s, int32 n)
|
||||||
r = nstring;
|
r = nstring;
|
||||||
while(n > 0) {
|
while(n > 0) {
|
||||||
c = *s++;
|
c = *s++;
|
||||||
if(align(0, types[TCHAR], Aarg1)) {
|
if(align(0, types[TCHAR], Aarg1, nil)) {
|
||||||
buf[0] = c>>8;
|
buf[0] = c>>8;
|
||||||
buf[1] = c;
|
buf[1] = c;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ widstruct(Type *t, uint32 o, int flag)
|
||||||
if(f->etype != TFIELD)
|
if(f->etype != TFIELD)
|
||||||
fatal("widstruct: not TFIELD: %lT", f);
|
fatal("widstruct: not TFIELD: %lT", f);
|
||||||
dowidth(f->type);
|
dowidth(f->type);
|
||||||
if(f->align > maxalign)
|
if(f->type->align > maxalign)
|
||||||
maxalign = f->align;
|
maxalign = f->type->align;
|
||||||
if(f->type->width < 0)
|
if(f->type->width < 0)
|
||||||
fatal("invalid width %lld", f->type->width);
|
fatal("invalid width %lld", f->type->width);
|
||||||
w = f->type->width;
|
w = f->type->width;
|
||||||
|
|
@ -248,9 +248,11 @@ dowidth(Type *t)
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
if(t->funarg)
|
if(t->funarg)
|
||||||
fatal("dowidth fn struct %T", t);
|
fatal("dowidth fn struct %T", t);
|
||||||
w = widstruct(t, 0, widthptr);
|
w = widstruct(t, 0, 1);
|
||||||
if(w == 0)
|
if(w == 0)
|
||||||
w = 1;
|
w = 1;
|
||||||
|
//if(t->align < widthptr)
|
||||||
|
// warn("align %d: %T\n", t->align, t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TFUNC:
|
case TFUNC:
|
||||||
|
|
@ -272,6 +274,8 @@ dowidth(Type *t)
|
||||||
w = widstruct(*getinarg(t1), w, widthptr);
|
w = widstruct(*getinarg(t1), w, widthptr);
|
||||||
w = widstruct(*getoutarg(t1), w, widthptr);
|
w = widstruct(*getoutarg(t1), w, widthptr);
|
||||||
t1->argwid = w;
|
t1->argwid = w;
|
||||||
|
if(w%widthptr)
|
||||||
|
warn("bad type %T %d\n", t1, w);
|
||||||
t->align = 1;
|
t->align = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1124,7 +1124,7 @@ reswitch:
|
||||||
case OPRINT:
|
case OPRINT:
|
||||||
case OPRINTN:
|
case OPRINTN:
|
||||||
ok |= Etop;
|
ok |= Etop;
|
||||||
typechecklist(n->list, Erv);
|
typechecklist(n->list, Erv | Eindir); // Eindir: address does not escape
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case OPANIC:
|
case OPANIC:
|
||||||
|
|
|
||||||
|
|
@ -730,8 +730,6 @@ type tiny struct {
|
||||||
// Call calls the function fv with input parameters in.
|
// Call calls the function fv with input parameters in.
|
||||||
// It returns the function's output parameters as Values.
|
// It returns the function's output parameters as Values.
|
||||||
func (fv *FuncValue) Call(in []Value) []Value {
|
func (fv *FuncValue) Call(in []Value) []Value {
|
||||||
var structAlign = Typeof((*tiny)(nil)).(*PtrType).Elem().Size()
|
|
||||||
|
|
||||||
t := fv.Type().(*FuncType)
|
t := fv.Type().(*FuncType)
|
||||||
nin := len(in)
|
nin := len(in)
|
||||||
if fv.first != nil && !fv.isInterface {
|
if fv.first != nil && !fv.isInterface {
|
||||||
|
|
@ -757,7 +755,7 @@ func (fv *FuncValue) Call(in []Value) []Value {
|
||||||
size = (size + a - 1) &^ (a - 1)
|
size = (size + a - 1) &^ (a - 1)
|
||||||
size += tv.Size()
|
size += tv.Size()
|
||||||
}
|
}
|
||||||
size = (size + structAlign - 1) &^ (structAlign - 1)
|
size = (size + ptrSize - 1) &^ (ptrSize - 1)
|
||||||
for i := 0; i < nout; i++ {
|
for i := 0; i < nout; i++ {
|
||||||
tv := t.Out(i)
|
tv := t.Out(i)
|
||||||
a := uintptr(tv.Align())
|
a := uintptr(tv.Align())
|
||||||
|
|
@ -767,9 +765,9 @@ func (fv *FuncValue) Call(in []Value) []Value {
|
||||||
|
|
||||||
// size must be > 0 in order for &args[0] to be valid.
|
// size must be > 0 in order for &args[0] to be valid.
|
||||||
// the argument copying is going to round it up to
|
// the argument copying is going to round it up to
|
||||||
// a multiple of 8 anyway, so make it 8 to begin with.
|
// a multiple of ptrSize anyway, so make it ptrSize to begin with.
|
||||||
if size < 8 {
|
if size < ptrSize {
|
||||||
size = 8
|
size = ptrSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// round to pointer size
|
// round to pointer size
|
||||||
|
|
@ -811,7 +809,7 @@ func (fv *FuncValue) Call(in []Value) []Value {
|
||||||
memmove(addr(ptr+off), v.getAddr(), n)
|
memmove(addr(ptr+off), v.getAddr(), n)
|
||||||
off += n
|
off += n
|
||||||
}
|
}
|
||||||
off = (off + structAlign - 1) &^ (structAlign - 1)
|
off = (off + ptrSize - 1) &^ (ptrSize - 1)
|
||||||
|
|
||||||
// Call
|
// Call
|
||||||
call(*(**byte)(fv.addr), (*byte)(addr(ptr)), uint32(size))
|
call(*(**byte)(fv.addr), (*byte)(addr(ptr)), uint32(size))
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
// Breakpoint() executes a breakpoint trap.
|
// Breakpoint() executes a breakpoint trap.
|
||||||
func Breakpoint()
|
func Breakpoint()
|
||||||
|
|
||||||
|
|
@ -73,6 +75,15 @@ type MemStatsType struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sizeof_C_MStats int // filled in by malloc.goc
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if sizeof_C_MStats != unsafe.Sizeof(MemStats) {
|
||||||
|
println(sizeof_C_MStats, unsafe.Sizeof(MemStats))
|
||||||
|
panic("MStats vs MemStatsType size mismatch")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MemStats holds statistics about the memory system.
|
// MemStats holds statistics about the memory system.
|
||||||
// The statistics are only approximate, as they are not interlocked on update.
|
// The statistics are only approximate, as they are not interlocked on update.
|
||||||
var MemStats MemStatsType
|
var MemStats MemStatsType
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define malloc runtime·mal
|
#define malloc runtime·mal
|
||||||
#define offsetof(s,m) (uint32)(&(((s*)0)->m))
|
|
||||||
#define memset(a,b,c) runtime·memclr((byte*)(a), (uint32)(c))
|
#define memset(a,b,c) runtime·memclr((byte*)(a), (uint32)(c))
|
||||||
#define memcpy(a,b,c) runtime·mcpy((byte*)(a),(byte*)(b),(uint32)(c))
|
#define memcpy(a,b,c) runtime·mcpy((byte*)(a),(byte*)(b),(uint32)(c))
|
||||||
#define assert(a) if(!(a)) runtime·throw("assert")
|
#define assert(a) if(!(a)) runtime·throw("assert")
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,8 @@ runtime·allocmcache(void)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 runtime·sizeof_C_MStats = sizeof(MStats);
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·mallocinit(void)
|
runtime·mallocinit(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,13 @@ runtime·check(void)
|
||||||
float64 j;
|
float64 j;
|
||||||
void* k;
|
void* k;
|
||||||
uint16* l;
|
uint16* l;
|
||||||
|
struct x1 {
|
||||||
|
byte x;
|
||||||
|
};
|
||||||
|
struct y1 {
|
||||||
|
struct x1 x1;
|
||||||
|
byte y;
|
||||||
|
};
|
||||||
|
|
||||||
if(sizeof(a) != 1) runtime·throw("bad a");
|
if(sizeof(a) != 1) runtime·throw("bad a");
|
||||||
if(sizeof(b) != 1) runtime·throw("bad b");
|
if(sizeof(b) != 1) runtime·throw("bad b");
|
||||||
|
|
@ -271,7 +278,9 @@ runtime·check(void)
|
||||||
if(sizeof(j) != 8) runtime·throw("bad j");
|
if(sizeof(j) != 8) runtime·throw("bad j");
|
||||||
if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k");
|
if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k");
|
||||||
if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l");
|
if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l");
|
||||||
// prints(1"check ok\n");
|
if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1");
|
||||||
|
if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y");
|
||||||
|
if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1");
|
||||||
|
|
||||||
uint32 z;
|
uint32 z;
|
||||||
z = 1;
|
z = 1;
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,7 @@ enum {
|
||||||
*/
|
*/
|
||||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
#define nil ((void*)0)
|
#define nil ((void*)0)
|
||||||
|
#define offsetof(s,m) (uint32)(&(((s*)0)->m))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* known to compiler
|
* known to compiler
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,15 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type T1 struct { x uint8 }
|
type T1 struct {
|
||||||
type T2 struct { x uint16 }
|
x uint8
|
||||||
type T4 struct { x uint32 }
|
}
|
||||||
|
type T2 struct {
|
||||||
|
x uint16
|
||||||
|
}
|
||||||
|
type T4 struct {
|
||||||
|
x uint32
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
report := len(os.Args) > 1
|
report := len(os.Args) > 1
|
||||||
|
|
@ -20,7 +26,7 @@ func main() {
|
||||||
var b1 [10]T1
|
var b1 [10]T1
|
||||||
a0, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[0])[2:], 16)
|
a0, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[0])[2:], 16)
|
||||||
a1, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[1])[2:], 16)
|
a1, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[1])[2:], 16)
|
||||||
if a1 != a0 + 1 {
|
if a1 != a0+1 {
|
||||||
fmt.Println("FAIL")
|
fmt.Println("FAIL")
|
||||||
if report {
|
if report {
|
||||||
fmt.Println("alignment should be 1, is", a1-a0)
|
fmt.Println("alignment should be 1, is", a1-a0)
|
||||||
|
|
@ -30,7 +36,7 @@ func main() {
|
||||||
var b2 [10]T2
|
var b2 [10]T2
|
||||||
a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[0])[2:], 16)
|
a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[0])[2:], 16)
|
||||||
a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[1])[2:], 16)
|
a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[1])[2:], 16)
|
||||||
if a1 != a0 + 2 {
|
if a1 != a0+2 {
|
||||||
if status == 0 {
|
if status == 0 {
|
||||||
fmt.Println("FAIL")
|
fmt.Println("FAIL")
|
||||||
status = 1
|
status = 1
|
||||||
|
|
@ -42,7 +48,7 @@ func main() {
|
||||||
var b4 [10]T4
|
var b4 [10]T4
|
||||||
a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[0])[2:], 16)
|
a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[0])[2:], 16)
|
||||||
a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[1])[2:], 16)
|
a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[1])[2:], 16)
|
||||||
if a1 != a0 + 4 {
|
if a1 != a0+4 {
|
||||||
if status == 0 {
|
if status == 0 {
|
||||||
fmt.Println("FAIL")
|
fmt.Println("FAIL")
|
||||||
status = 1
|
status = 1
|
||||||
|
|
@ -173,7 +173,3 @@ panic: interface conversion: interface is main.T, not main.T
|
||||||
panic PC=xxx
|
panic PC=xxx
|
||||||
|
|
||||||
== bugs/
|
== bugs/
|
||||||
|
|
||||||
=========== bugs/bug260.go
|
|
||||||
FAIL
|
|
||||||
BUG: bug260 failed
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue