changeset 650:fe0a971a6666 struct-alignment

fix alignment in struct
author kono
date Tue, 21 Nov 2006 05:52:02 +0900
parents f1d71563a46a
children c9a489ac3fc7
files Changes mc-codegen.c mc-parse.c mc-parse.h test/ps2.c
diffstat 5 files changed, 76 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sat Nov 18 15:37:37 2006 +0900
+++ b/Changes	Tue Nov 21 05:52:02 2006 +0900
@@ -9131,5 +9131,32 @@
 typedef されたsymbol に付いているattribute を引き継ぐ必要が
 ある。それは、どこで...
 
-
-
+Sun Nov 19 14:10:54 JST 2006
+
+なんか、ia32/gcc 2.9 の時のvarargs が壊れているらしい。
+
+ARMのスタックalignmentは、ずれているようだ... stack top
+自体がalignされているべきだと思うので、直すんだろうな。
+
+Tue Nov 21 05:06:37 JST 2006
+
+struct のaligned(16) (引数無しもあるらしい...) だけど、
+nptr に set_attribute してしまってはだめらしい。関数の
+arugment もそう。
+
+typedef された attribute は、どうする? もともと、タイプ
+の方に attribute してやれば、こんな問題は出ないのだが...
+hoge *p; では、hoge のattribute を引き継いではだめ。
+
+ってことは、set_attr は要らないってこと? (かもね...)
+
+
+
+
+
+
+
+
+
+
+
--- a/mc-codegen.c	Sat Nov 18 15:37:37 2006 +0900
+++ b/mc-codegen.c	Tue Nov 21 05:52:02 2006 +0900
@@ -3125,6 +3125,9 @@
     int sz,nsc,ndsp,align;
     int sbit_f = bit_field_disp;
     int type0 = type_value(type);
+    int attr = attribute;
+    attribute = 0;
+
     bit_field_disp = 0;  // default is 0, recover only in bit-field
 
     if (n==0) {
@@ -3138,6 +3141,7 @@
 	if ((mode==GDECL)) {
 	    fcheck(n);
 	    set_ctmode(n,ctmode);
+	    set_attributes(n,attr);
 	    return n;
 	    /* function and code segment are defined using fdecl/code_decl */
             /* in decl() */
@@ -3172,14 +3176,19 @@
                 disp = ((disp+(size_of_int-1))&~(size_of_int-1));
             }
 #endif
-	    if ((align=attr_value(n,ALIGNED))) {
+	    if ((align=attr_value_in_list(attr,ALIGNED))) {
+int hoge = disp;
 		if (car(align)!=CONST) error(-1);
 		// align have to be 2^n
+		align = caddr(align);
                 disp = ((disp+(align-1))&~(align-1));
+printf("# field %s %d->%d (align %d)\n",n->nm,hoge,disp,align);
+
 	    }
 	}
 	if (n!=&null_nptr)
 	    fields = list4(type,fields,(int)(n->nm),disp);
+	// don't set attribute to n
     } else if (mode==GUDECL||mode==LUDECL) { // union
 	/* disp is pushded and reset in sdecl */
 	if (type0>0 && car(type0)==BIT_FIELD) {
@@ -3232,6 +3241,7 @@
 	}
 	gpc +=sz;
 	set_ctmode(n,ctmode);
+	set_attributes(n,attr);
 	return n;
     case GSDECL: case LSDECL:   // struct
 	disp += sz;
@@ -3243,9 +3253,11 @@
     case GTDECL:                // typedef
 	nsc = TYPE;
 	gtypedefed=glist2((int)gnptr,gtypedefed);
+	set_attributes(n,attr);
 	break;
     case LTDECL:                // local typedef
 	nsc = TYPE;
+	set_attributes(n,attr);
 	break;
     case LLDECL:                // label def (gcc extension)
 	nsc = FLABEL;
@@ -3290,6 +3302,8 @@
 #if  1
 	} else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
 	    /* alignment in struct in argument */
+	    /* should be GCD of member alignment */
+	    /* __attribute(alignment(16)) is ignored in argments */
 	    n->dsp = args;
 	    args += ((sz+(size_of_int-1))&~(size_of_int-1));
 #endif
@@ -3304,10 +3318,12 @@
 	} else {
 	    n->ty = type;
 	}
+	// don't set attribute
 	set_ctmode(n,ctmode);
 	return n;
     case STAT: /* return (struct hoge)f() case? */
     case LDECL:    // local variable
+	set_attributes(n,attr);
 	if (stmode==REGISTER && !(inmode==INLINE)) {
 	    if(scalar(type0)) {
 		ndsp = get_register_var(n);
@@ -3345,6 +3361,7 @@
     default:
 	error(DCERR);
     }
+    // should be an error?
     n->sc = nsc;
     n->dsp = ndsp;
     set_ctmode(n,ctmode);
--- a/mc-parse.c	Sat Nov 18 15:37:37 2006 +0900
+++ b/mc-parse.c	Tue Nov 21 05:52:02 2006 +0900
@@ -191,7 +191,6 @@
 static void top_init();
 static void qualifiers();
 static void attributes();
-static void set_attributes(NMTBL *n);
 static void macro_convert();
 extern void sym_print(int,FILE *);
 static void copy_attributes(NMTBL *n) ;
@@ -902,7 +901,6 @@
     }
     while (sym==ATTRIBUTE||sym==ASM) { 
 	int sym0 = sym; getsym(0); attributes(sym0); 
-	set_attributes(n); attribute = 0;
     }
     if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS)) {
 	/* function body */
@@ -914,16 +912,13 @@
 	if (type<0) error(DCERR);
 	else if (car(type)==CODE) {
 	    if (is_function(n)) error(UFERR);
-	    set_attributes(n); attribute = 0;
 	    code_decl(n); return;
 	} else if (car(type)==FUNCTION) {
 	    if (is_code(n)) error(UCERR);
-	    set_attributes(n); attribute = 0;
 	    fdecl(n); return;
 	} else error(DCERR);
     } else {
 	conv->return_type_(type,n,sd);
-	set_attributes(n); attribute = 0;
 	n = def(n,ctmode);
 	if (inmode && (mode==LDECL||mode==LLDECL)) { 
 	    parse = list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode));
@@ -944,7 +939,6 @@
 		    error(DCERR);
 	    }
 	    conv->return_type_(type,n,1);
-	    set_attributes(n); attribute = 0;
 	    def(n,ctmode);
 	    if (inmode && mode==LDECL) {
 		parse = list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode));
@@ -1151,6 +1145,7 @@
 	    if (nptr->sc==TYPE) {
 		t=nptr->ty;
 		typedefed=glist2((int)nptr,typedefed);
+		// have to be type attribute
 		copy_attributes(nptr);
 		getsym(0);
 		break;
@@ -1179,6 +1174,7 @@
 {
     NMTBL *n;
     if(sym==MUL) {
+	attribute = 0; // do not inherite type attributes
 	getsym(0);
 	qualifiers();
 	n=decl0();
@@ -1328,10 +1324,12 @@
 	} else {
 	    if(sym==DOTS) {
 		argtypes=list2(DOTS,argtypes);
+		attribute = 0;
 		getsym(0);
 		break;
 	    }
 	    if((t=typespec())==0) {
+		attribute = 0;
 		error(DCERR);
 		break;
 	    }
@@ -1342,10 +1340,12 @@
 		args = sargs;
 		reverse(t); // this sets type also
 		if (arg != &null_nptr) {
-		    if (smode==GDECL)
+		    if (smode==GDECL) {
 			def(arg,ctmode);
+		    }
 		}
 	    }
+	    attribute = 0;
 	    argtypes=list2(type,argtypes);
 	    if(sym==RPAR) break;
 	}
@@ -4182,6 +4182,7 @@
 ndecl0(void)
 {
     if(sym==MUL) {
+	attribute = 0; // do not inherite type attributes
 	getsym(0);
 	return type=list2(POINTER,ndecl0());
     }
@@ -5461,14 +5462,25 @@
     transfer attribtes() value to nptr;
  */
 
-static void
-set_attributes(NMTBL *n) {
+extern void
+set_attributes(NMTBL *n,int attr) {
     int e;
-    for(e = attribute; e ; e = cadr(e)) {
+    for(e = attr; e ; e = cadr(e)) {
 	set_attr(n,car(e),caddr(e));
     }
 }
 
+extern int
+attr_value_in_list(int list,int attr)
+{
+    int e;
+    e = list;
+    for(;e;e=cadr(e)) {
+	if (car(e)==attr) return caddr(e);
+    }
+    return 0;
+}
+
 static void
 copy_attributes(NMTBL *n) {
     int attr;
--- a/mc-parse.h	Sat Nov 18 15:37:37 2006 +0900
+++ b/mc-parse.h	Tue Nov 21 05:52:02 2006 +0900
@@ -55,6 +55,7 @@
 extern int inline_funcs;    /* inline function list */
 
 extern int parse;   /* parse tree */
+extern int attribute;   /* attribute list (in __attribute())  */
 
 /*
           STRING         nptr
@@ -157,6 +158,10 @@
 extern NMTBL *new_static_name(char *name,int delimit);
 extern int reverse0(int t1);
 extern int size(int t);
+extern void set_attributes(NMTBL *n, int attr);
+
+extern int attr_value_in_list(int list,int attr);
+
 
 /* used in mc-macro.c */
 
--- a/test/ps2.c	Sat Nov 18 15:37:37 2006 +0900
+++ b/test/ps2.c	Tue Nov 21 05:52:02 2006 +0900
@@ -76,6 +76,8 @@
     if(!this) return;
     if(this->mtd)  this->mtd( this );
     if(this->draw) this->draw( this, work, base );
+    printf("offset draw %d\n",((char*)(&this->draw) - ((char*)&this->object)));
+    printf("offset next %d\n",((char*)(&this->next) - ((char*)&this->object)));
 
     if(this->child) graphic_ObjNode_draw( this->child, work );
     if(this->next)  graphic_ObjNode_draw( this->next,  base );