summaryrefslogtreecommitdiff
path: root/src/cmd/6c/swt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6c/swt.c')
-rw-r--r--src/cmd/6c/swt.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c
index 668a1fdbc..47975a0c8 100644
--- a/src/cmd/6c/swt.c
+++ b/src/cmd/6c/swt.c
@@ -503,7 +503,7 @@ zaddr(Biobuf *b, Adr *a, int s)
}
int32
-align(int32 i, Type *t, int op)
+align(int32 i, Type *t, int op, int32 *maxalign)
{
int32 o;
Type *v;
@@ -517,7 +517,9 @@ align(int32 i, Type *t, int op)
break;
case Asu2: /* padding at end of a struct */
- w = SZ_VLONG;
+ w = *maxalign;
+ if(w < 1)
+ w = 1;
if(packflg)
w = packflg;
break;
@@ -525,10 +527,13 @@ align(int32 i, Type *t, int op)
case Ael1: /* initial align of struct element */
for(v=t; v->etype==TARRAY; v=v->link)
;
- w = ewidth[v->etype];
- if(w <= 0 || w >= SZ_VLONG)
- w = SZ_VLONG;
- if(packflg)
+ if(v->etype == TSTRUCT || v->etype == TUNION)
+ w = v->align;
+ else
+ w = ewidth[v->etype];
+ if(w < 1 || w > SZ_VLONG)
+ fatal(Z, "align");
+ if(packflg)
w = packflg;
break;
@@ -538,8 +543,8 @@ align(int32 i, Type *t, int op)
case Aarg0: /* initial passbyptr argument in arg list */
if(typesu[t->etype]) {
- o = align(o, types[TIND], Aarg1);
- o = align(o, types[TIND], Aarg2);
+ o = align(o, types[TIND], Aarg1, nil);
+ o = align(o, types[TIND], Aarg2, nil);
}
break;
@@ -560,13 +565,15 @@ align(int32 i, Type *t, int op)
break;
case Aaut3: /* total align of automatic */
- o = align(o, t, Ael1);
- o = align(o, t, Ael2);
+ o = align(o, t, Ael1, nil);
+ o = align(o, t, Ael2, nil);
break;
}
o = xround(o, w);
+ if(maxalign && *maxalign < w)
+ *maxalign = w;
if(debug['A'])
- print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
+ print("align %s %d %T = %d\n", bnames[op], i, t, o);
return o;
}