changeset 13:a8a812dace23

struct local initialization
author kono
date Mon, 17 Jan 2000 00:43:06 +0900
parents f928bd330351
children 77c0710a8729
files mc-nop-386.c mc-parse.c test/tmp7.c
diffstat 3 files changed, 171 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/mc-nop-386.c	Sat Jan 15 00:01:14 2000 +0900
+++ b/mc-nop-386.c	Mon Jan 17 00:43:06 2000 +0900
@@ -122,6 +122,7 @@
 #define POINTER_REG 3    
 static char *reg_name[8]; 
 static char *reg_name_l[4];
+static char *reg_name_w[4];
 
 /*
     creg   currrent virtual register
@@ -178,6 +179,10 @@
     reg_name_l[REG_EBX] = "%bl";
     reg_name_l[REG_ECX] = "%cl";
     reg_name_l[REG_EDX] = "%dl";
+    reg_name_w[REG_EAX] = "%ax";
+    reg_name_w[REG_EBX] = "%bx";
+    reg_name_w[REG_ECX] = "%cx";
+    reg_name_w[REG_EDX] = "%dx";
 
 }
 
@@ -730,15 +735,85 @@
     }
 }
 
+#define MAX_COPY_LEN 20
+
+void 
+emit_copy(char *from,char *to,int length,int offset)
+{
+    if (length<0) return;
+    switch (length) {
+    case 0:	break;
+    case 1:
+	printf("\tmovb %d(%s),%s\n",offset,from, reg_name_l[rname[dreg]] );
+	printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,to);
+	break;
+    case 2:
+	printf("\tmovw %d(%s),%s\n",offset,from, reg_name_w[rname[dreg]] );
+	printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,to);
+	break;
+    case 4:
+	printf("\tmovl %d(%s),%s\n",offset,from, drn);
+	printf("\tmovl %s,%d(%s)\n",drn, offset,to);
+	break;
+    default:
+	if (length <=MAX_COPY_LEN) {
+	    for(;length>4;length-=4,offset+=4);
+		emit_copy(from,to,4,offset);
+	    for(;length>2;length-=2,offset+=2);
+		emit_copy(from,to,2,offset);
+	    if(length>0)
+		emit_copy(from,to,length,offset);
+	    return;
+	}
+	printf("\texch %%edi,%s\n",from);
+	printf("\texch %%esi,%s\n",to);
+	printf("\texch %%ecx,%s\n",drn);
+	printf("\tmovl $%d,%%ecx\n",length);
+	printf("\tcld\n\trep\n\tmovsl\n");
+	printf("\texch %%ecx,%s\n",drn);
+	printf("\texch %%esi,%s\n",to);
+	printf("\texch %%edi,%s\n",from);
+    }
+}
+
+int
+struct_push(int e4,int t) 
+{
+    int e5;
+    g_expr(e4);
+    e5=size(t); 
+    if(e5%size_of_int) {
+	e5 += size_of_int - (e5%size_of_int);
+    }
+    printf("\tsubl $%d,%%esp\n",e5);
+    if (e5<=MAX_COPY_LEN)
+	emit_copy(crn,"%esp",e5,0);
+    else {
+	printf("\tpushl %%edi\n");
+	printf("\tpushl %%esi\n");
+	printf("\tpushl %%ecx\n");
+	printf("\tleal 12(%%esp),%%di\n");
+	if (rname[creg]!=REG_ESI)
+		printf("\tmovl %s,%%esi\n",crn);
+	printf("\tmovl $%d,%%ecx\n",e5);
+	printf("\tcld\n\trep\n\tmovsl\n");
+	printf("\tpopl %%ecx\n");
+	printf("\tpopl %%esi\n");
+	printf("\tpopl %%edi\n");
+    }
+    return e5/size_of_int;
+}
+
 void
 function(int e1)
 {
-    int e2,e3,e4,e5,nargs;
+    int e2,e3,e4,e5,nargs,t;
     NMTBL *n;
 
     e2 = cadr(e1);
     nargs = 0;
     for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
+	t=caddr(e3);
 	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
 	switch(car(e4)) {
 	case FNAME:
@@ -749,8 +824,16 @@
 	    g_expr(e5);
 	    printf("\tpushl %s\n",crn);
 	    break;
-	default:g_expr(e4);
-	    printf("\tpushl %s\n",crn);
+	default:
+	    if(scalar(t)) {
+		g_expr(e4);
+		printf("\tpushl %s\n",crn);
+	    } else if (car(t)==STRUCT||car(t)==UNION) {
+		nargs += struct_push(e4,t);
+		continue;
+	    } else {
+		error(TYERR);
+	    }
 	}
 	++nargs;
     }
@@ -954,6 +1037,7 @@
     emit_push();
     g_expr(e2);
     xrn = emit_pop(0);
+    emit_copy(crn,xrn,sz,0);
     return;
 }
 
@@ -1406,58 +1490,44 @@
     int l;
     char *name;
     name = n->nm; 
-    if(mode==GDECL)  { /* global */
-	if (n->dsp != -1) {
-	    n->dsp = -1;   /* initiallized flag */
-	    printf(".globl\t%s\n",name);
-	    data_mode(name);
-	    align(t);
-	    printf("%s:\n",name); 
+    if(mode!=GDECL)  { 
+	error(-1); return;
+    }
+    if (n->dsp != -1) {
+	n->dsp = -1;   /* initiallized flag */
+	printf(".globl\t%s\n",name);
+	data_mode(name);
+	align(t);
+	printf("%s:\n",name); 
+    } else {
+	data_mode(0);
+    }
+    if(car(e)==CONST) {       
+	if (t==CHAR) {
+	    printf("\t.byte %d\n",cadr(e));
+	    if (data_alignment>0)
+		data_alignment++;
+	    gpc += 1;
 	} else {
-	    data_mode(0);
-	}
-        if(car(e)==CONST) {       
-	    if (t==CHAR) {
-		printf("\t.byte %d\n",cadr(e));
-		if (data_alignment>0)
-		    data_alignment++;
-		gpc += 1;
-	    } else {
-		printf("\t.long %d\n",cadr(e));
-		gpc += size_of_int;
-	    }
-        } else if(t!=CHAR) {       
+	    printf("\t.long %d\n",cadr(e));
 	    gpc += size_of_int;
-	    if(car(e)==ADDRESS&&car(cadr(e))==GVAR) {
-		printf("\t.long %s\n",caddr(cadr(e)));
-	    } else if(car(e)==FNAME) {
-		printf("\t.long %s\n",((NMTBL *)cadr(e))->nm);
-            } else if(car(e)==STRING) {       
-		if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
-		    l = fwdlabel();
-		    printf("\t.long _%d\n",l);
-		    printf(".section\t.rodata\n");
-		    printf("_%d:\n",l);
-		    output_mode = RODATA_EMIT_MODE;
-		}
-		ascii((char *)cadr(e));
-	    } else error(TYERR);
-        }
-    } else {
-	/* if (n->sc!=LVAR) { error(TYERR); return; } */
-        if(car(e)==CONST) {       
-		printf("\tmovl $%d,%s\n",cadr(e),crn);
-		printf("\t%s %s,%d(%%ebp)\n",t==CHAR?"movsbl":"movl",crn,n->dsp);
-        } else if(t!=CHAR) {       
-		if(car(e)==ADDRESS&&car(cadr(e))==GVAR)
-		    printf("\tlea %s,%s\n",caddr(e),crn);
-                else if(car(e)==FNAME)
-		    printf("\tlea %s,%s\n",((NMTBL *)cadr(e))->nm,crn);
-		else if(car(e)==STRING) {       
-		    string(e);
-                } else error(TYERR);
-		printf("\tmovl %s,%d(%%ebp)\n",crn,n->dsp);
-        }
+	}
+    } else if(t!=CHAR) {       
+	gpc += size_of_int;
+	if(car(e)==ADDRESS&&car(cadr(e))==GVAR) {
+	    printf("\t.long %s\n",caddr(cadr(e)));
+	} else if(car(e)==FNAME) {
+	    printf("\t.long %s\n",((NMTBL *)cadr(e))->nm);
+	} else if(car(e)==STRING) {       
+	    if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
+		l = fwdlabel();
+		printf("\t.long _%d\n",l);
+		printf(".section\t.rodata\n");
+		printf("_%d:\n",l);
+		output_mode = RODATA_EMIT_MODE;
+	    }
+	    ascii((char *)cadr(e));
+	} else error(TYERR);
     }
 }
 
--- a/mc-parse.c	Sat Jan 15 00:01:14 2000 +0900
+++ b/mc-parse.c	Mon Jan 17 00:43:06 2000 +0900
@@ -6,7 +6,7 @@
 
 void ntable_consistency();
 static void adecl(NMTBL *n);
-static void decl_data(int t, NMTBL *n);
+static int decl_data(int t, NMTBL *n,int offset);
 static int alpha(char c);
 static int binop(int op, int e1, int e2, int t1, int t2);
 int caddr(int e);
@@ -656,7 +656,7 @@
 	    *cheapp++ = 0;
 	}
 	if(sym==ASS) {	
-	    decl_data(type,n);
+	    decl_data(type,n,0);
 	    emit_data_closing(n);
 	    /* gpc is incremented by emit_data */
 	} else 
@@ -723,9 +723,11 @@
 	    ndsp = (disp -= sz);
 	}
 	if(sym==ASS) {	
-	    decl_data(type,n);
+	    n->sc = nsc;
+	    n->dsp = ndsp;
+	    decl_data(type,n,0);
 	}
-	break;
+	return;
     case LSDECL:
 	nsc = FIELD;
 	ndsp = disp;
@@ -752,52 +754,54 @@
 void
 emit_init_vars(void)
 {
+    if (!init_vars) return;
+    init_vars = reverse0(init_vars);
     while(init_vars) {
 	g_expr(car(init_vars));
 	init_vars = cadr(init_vars);
     }
 }
 
-void
-assign_data(int e, int t, int n)
+int
+assign_data(int e, int t, NMTBL *n,int offset)
 {
     int ass;
 
     if(mode==GDECL) {
- 	emit_data(e,t,(NMTBL *)n);
+ 	emit_data(e,t,n);
+	return offset+size(t);
     } else if(mode==LDECL) {
-	if (t==STRUCT || t==UNION) {
-	    ass = list3(SASS,list2(LVAR,nptr->dsp),e);
+	if(t==CHAR) {
+	    ass =list3(CASS,list2(LVAR,n->dsp+offset),e);
+	} else if (scalar(t)) {
+	    ass = list3(ASS,list2(LVAR,n->dsp+offset),e);
+	} else if (car(t)==STRUCT || car(t)==UNION || car(t)==STRING) {
+	    ass = list3(SASS,list2(LVAR,n->dsp+offset),e);
 	} else {
-	    if(t==CHAR) {
-		ass =list3(CASS,list2(LVAR,nptr->dsp),e);
-	    } else {
-		ass = list3(ASS,list2(LVAR,nptr->dsp),e);
-	    }
+	    error(DCERR);
 	}
 	init_vars = list2(ass,init_vars);
+	return offset+size(t);
     } else {
 	error(DCERR);
     }
 }
 
-void
-decl_data(int t, NMTBL *n)
+int
+decl_data(int t, NMTBL *n,int offset)
            /* type */
              
 {
-    int t1,slfree,e,i;
+    int t1,e,i;
 
     getsym();
     if (scalar(t)) {
- 	slfree=lfree;
  	e=expr1();
  	if(car(e)!=CONST && t==CHAR)
  	    error(TYERR);
- 	emit_data(e,t,n);
- 	lfree=slfree;
+ 	offset = assign_data(e,t,n,offset);
  	type=t;
-	return;
+	return offset;
     }
     t1 = car(t);
     if (t1==ARRAY) {
@@ -805,35 +809,37 @@
 	    t1 = cadr(t);
 	    for(i=0;;i++) {
 		if (sym!=RC)
-		    decl_data(t1,n);
+		    offset=decl_data(t1,n,offset);
 		if (sym==COMMA) { continue;
 		} else if (sym==RC) {
-		    if (caddr(t)==0) {
-			heap[t+2]=i;
-		    } else if (caddr(t)!=i+1) {
+		    if (caddr(t)==0) {           /* size not defined      */
+			heap[t+2]=i+1;           /* define array size     */
+		    } else if (caddr(t)!=i+1) {  /* size match?           */
 			error(TYERR);
 		    }
 		    getsym();
-		    return;
+		    return offset;
 		} else {
 		    error(TYERR);
 		}
 	    }
 	} else if (cadr(t)==CHAR) {
-	    slfree=lfree;
 	    e=expr1();
 	    if(car(e)!=STRING)
 		error(TYERR);
-	    emit_data(e,STRING,n);
-	    heap[t+2]= size(type);
-	    lfree=slfree;
+	    offset=assign_data(e,list3(ARRAY,CHAR,size(type)),n,offset);
+	    if (caddr(t)==0) {                  /* size not defined      */
+		heap[t+2]=size(type);           /* define array size     */
+	    } else if (caddr(t)!=size(type)) {  /* size match?           */
+		error(TYERR);
+	    }
 	} else 
 	    error(DCERR);
     } else if (t1==STRUCT) {
 	if(cadr(t)==-1) error(DCERR);
 	t1 = caddr(t);  /* list of fields */
 	while(t1) {
-	    decl_data(car(t1),n);  /* alignment? */
+	    offset = decl_data(car(t1),n,offset);  /* alignment? */
 	    t1 = cadr(t1);
 	    if ( t1 && sym==COMMA) continue;
 	    if (!t1 && sym!=RC) error(DCERR);
@@ -876,11 +882,14 @@
 	    heap[nptr0->ty+2]=tags;
 	    rplacad(type0 = nptr0->ty,disp);
 	} else {	
+	    /* struct tag name */
 	    if(nptr0->sc == EMPTY) nptr0=gnptr0;
 	    if(nptr0->sc == EMPTY) error(UDERR);
 	    if(nptr0->sc != TAG) error(TYERR);
-	    type0 = nptr0->ty;
+	    tags = caddr(nptr0->ty);
+	    disp = cadr(nptr0->ty);
 	}
+	type0 = list3(s,disp,tags);
     } else if(sym==LC) {	
 	tags = 0;
 	while(getsym() != RC) {
--- a/test/tmp7.c	Sat Jan 15 00:01:14 2000 +0900
+++ b/test/tmp7.c	Mon Jan 17 00:43:06 2000 +0900
@@ -1,19 +1,19 @@
 
 
+int k=3;
+
+struct aa { int a[100]; } aaa,bbb;
+
 void tmp(void);
 
 int
 main0(int,char *[]);
 
-main0(ac,av)
+main0(int ac,char *av[])
 {
     return ac;
 }
 
-int k=3;
-
-struct aa { int a[100]; } aaa,bbb;
-
 void
 main2(struct aa a1)
 {
@@ -30,6 +30,7 @@
     return a1;
 } 
 
+
 main(ac,av)
 int ac;
 char *av[];
@@ -51,6 +52,7 @@
     printf("%d %s\n",i,p-i);
 }
 
+void
 tmp()
 {
 }