changeset 39:c63c4fdeb9a7

struct done.
author kono
date Tue, 11 Feb 2003 22:36:51 +0900
parents d48d952da354
children 060d1e549fec
files .gdbinit Idea mc-nop-386.c mc-parse.c test/tmp7.c
diffstat 5 files changed, 100 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Tue Feb 11 11:26:51 2003 +0900
+++ b/.gdbinit	Tue Feb 11 22:36:51 2003 +0900
@@ -1,6 +1,4 @@
 tb main
-# b error
-# b errmsg
 define regs 
 call fprintf(stderr,"eax=%08x ebx=%08x ecx=%08x edx=%08x\nesi=%08x edi=%08x ebp=%08x esp=%08x eip=%08x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp,$eip)
 end
@@ -13,4 +11,6 @@
 nexti
 x/1i $eip
 end
+b error
+b errmsg
 r -s test/tmp7.c
--- a/Idea	Tue Feb 11 11:26:51 2003 +0900
+++ b/Idea	Tue Feb 11 22:36:51 2003 +0900
@@ -1458,3 +1458,20 @@
 結局、list base のinterpreter を実装しました。きちゃないが。
 前の方法でも、頑張ればできるんでしょうけどね。
 
+Tue Feb 11 13:50:03 JST 2003
+
+struct copy だけど... 関数がstructを返すときに、引数に前もって
+積んでおくのでは、そこに値がコピーされてしまうし、あとで、
+スタックをたたんで置くときにきまずい。
+
+function call の時に、引数の型のチェックをしてない
+
+type に -1 とheapの引数が混在しているやつだけど..
+やっぱまずいんじゃないか?
+
+temproal struct は再利用できるんだけど、dispの変更ができないので
+新しく作るしかない。大きいときだけ新しく作るなんていうセコイ
+技はあるけど。
+
+register  を使用しているかだけじゃなくて、実際にcreg/dregに
+値があるかどうかを記憶する必要がある。
--- a/mc-nop-386.c	Tue Feb 11 11:26:51 2003 +0900
+++ b/mc-nop-386.c	Tue Feb 11 22:36:51 2003 +0900
@@ -746,7 +746,8 @@
 void 
 emit_copy(int from,int  to,int length,int offset)
 {
-    if (length<0) return;
+    int fix = 0;
+    if (length<=0) return;
     switch (length) {
     case 0:	break;
     case 1:
@@ -769,17 +770,24 @@
 		emit_copy(from,to,2,offset);
 	    if(length>0)
 		emit_copy(from,to,length,offset);
-	    return;
+	    break;
 	}
-	use_register(from,REG_EDI,1);
-	use_register(to,  REG_ESI,1);
-	use_register(dreg,REG_ECX,1);
+	use_register(from,REG_ESI,1);
+	use_register(to,  REG_EDI,1);
+	use_register(dreg,REG_ECX,0);
 	printf("\tmovl $%d,%%ecx\n",length/4);
+	fix = (length/4)*4;
 	printf("\tcld\n\trep\n\tmovsl\n");
 	if(length%4) {
 	    emit_copy(from,to,length,offset+length/4);
 	}
     }
+    /* this code is necessary for the value of assignment or function call */
+    /* otherwise we don't need this */
+    if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0));
+    if(creg!=to) {
+	free_register(creg); creg=to;
+    }
 }
 
 int
@@ -1114,7 +1122,7 @@
     /* structure assignment */
     e2 = cadr(e1);  /* pointer variable to the struct */
     e3 = cadr(e2);  /* offset of the variable (distination) */
-    e4 = caddr(e1); /* rright value (source) */
+    e4 = caddr(e1); /* right value (source) */
     sz = cadddr(e1);  /* size of struct or union */
     g_expr(e4);
     emit_push();
--- a/mc-parse.c	Tue Feb 11 11:26:51 2003 +0900
+++ b/mc-parse.c	Tue Feb 11 22:36:51 2003 +0900
@@ -92,6 +92,7 @@
 static int macro_eval(int macrop,char *body,int history);
 static char * append(int lists);
 static NMTBL *free_nptr();
+static void replace_return_struct(int func,int left);
 
 extern void display_ntable(NMTBL *n, char *s);
 extern void closing(void);
@@ -738,33 +739,33 @@
 	if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR) {
 	    if (type!=CHAR && !scalar(type)) 
 		error(TYERR);
-	    nptr->sc = REGISTER;
+	    n->sc = REGISTER;
 	    reg_var++;
-	    if (nptr->dsp==0) {
-		if ((nptr->dsp = get_register_var())<0) {
+	    if (n->dsp==0) {
+		if ((n->dsp = get_register_var())<0) {
 		    error(-1);
 		} 
 	    } 
 	    return n;
 	}
-	nptr->sc = LVAR;
+	n->sc = LVAR;
 	if(type==CHAR) {
-	    /* nptr->ty=INT; */
-	    if (nptr->dsp==0) {
-		nptr->dsp = args;
+	    /* n->ty=INT; */
+	    if (n->dsp==0) {
+		n->dsp = args;
 		if (endian) 
 		    n->dsp += size_of_int-1;
 	    }
 	    args += size_of_int;
 	} else {
-	    if (nptr->dsp==0)
-		nptr->dsp = args;
+	    if (n->dsp==0)
+		n->dsp = args;
 	    args += sz;
 	}
 	if(type==VOID) {
 	} else if (!scalar(type)) {
 	    if((t=car(type))==STRUCT || t==UNION) {
-		nptr->ty = type;
+		n->ty = type;
 	    } else
 		error(TYERR);
 	}
@@ -1032,13 +1033,18 @@
 	stmode=0;
 	decl(); getsym();
     }
-    if (((t=car(fnptr->ty))==STRUCT||t==UNION)) {
+    t=car(fnptr->ty);
+    if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) {
 	/* this extra dummy arguments are set at calling sequence */
-	str_ret.nm = "str_ret";
-	type = t;
-	def(&str_ret);
-	if ((t=size(type))==-1) error(TYERR);
-	else struct_return = list2(list2(LVAR,str_ret.dsp),size(type));
+	str_ret.nm = "str_ret"; str_ret.sc = EMPTY;
+	str_ret.dsp = 0; str_ret.ty = 0;
+	type=list2(POINTER,t);
+	if ((t=size(t))==-1) error(TYERR);
+	else {
+	    def(&str_ret);
+	    struct_return = list3(list2(LVAR,str_ret.dsp),t,type);
+	}
+	/* type is no longer valid */
     } else {
 	struct_return = 0;
     }
@@ -1073,7 +1079,7 @@
 	    error(DCERR);
 	else {
 	    n->sc=FUNCTION;
-	    n->ty=glist2(cadr(type),0);
+	    n->ty=glist2(cadr(type),0); /* arglist? */
 	}
     }
 }
@@ -1386,7 +1392,7 @@
 void
 doreturn(void)
 {
-    int slfree,e;
+    int slfree,e,e1;
 
     if(getsym()==SM) {	
 	getsym();
@@ -1398,19 +1404,28 @@
 	e = expr();
 	if ((car(type)==STRUCT || car(type)==UNION)&&
 		size(type)==cadr(struct_return)) {
-	    e = list4(SASS,car(struct_return),rvalue(e),size(type));
-	    gexpr(e);
+	    e = rvalue(e);
+	    type = caddr(struct_return);
+	    e1 = rvalue(cadr(struct_return));
+	    gexpr(list4(SASS,rvalue(car(struct_return)),e,e1));
 	} else {
-	    error(TYERR);
+	    error(TYERR); /* should check compatible */
 	}
     } else {
 	gexpr(expr());
     }
     lfree=slfree;
     checksym(SM);
+    /* control = 0; still control continue until pending return emittion */
     retpending = 1;
 }
 
+void
+replace_return_struct(int func,int left) {
+    int e = caddr(func); /* arg lists */
+    e = car(e);          /* return_struct arg */
+    rplacad(e,left);
+}
 
 void
 dogoto(void)
@@ -1503,7 +1518,13 @@
 	if(t==CHAR) {
 	    type= INT;return(list3(CASS,e1,e2));
 	} else if(!scalar(t)&&(car(t)==STRUCT||car(t)==UNION)) {
-	    type= t;return(list4(SASS,e1,e2,size(t)));
+	    type= t;
+	    if(car(e2)==RSTRUCT && car(cadr(e2))==FUNCTION) {
+		replace_return_struct(cadr(e2),e1);
+		return cadr(e2);
+	    } else {
+		return(list4(SASS,e1,e2,size(t)));
+	    }
 	}
 	type=t;
 	return(list3(ASS,e1,e2));
@@ -2132,6 +2153,8 @@
 {
     int t,arglist,e;
 
+    /* function call */
+
     t=type;
     if(integral(t)|| (car(t)!=FUNCTION && car(t)!=CODE))
 	error(TYERR);
@@ -2144,15 +2167,17 @@
 	getsym();
     }
     checksym(RPAR);
-    if(car(t)!=CODE) {
-	t=cadr(t);
-	if(t==CHAR) type= INT;
-	else if(car(t)==STRUCT||car(t)==UNION) {
-	    type = t;
-	    e = list2(LVAR,def(0)->dsp);
-	    arglist=list3(e,arglist,type);
-	    return list3(COMMA,list3(FUNCTION,e1,arglist),rvalue(e));
-	} else type=t;
+    if(car(t)==CODE) 
+	return list3(FUNCTION,e1,arglist);
+    type=cadr(t);
+    if(type==CHAR) type=INT;
+    else if(car(type)==STRUCT||car(type)==UNION) {
+	/* make temporaly struct for return value */
+	e = list2(LVAR,def(0)->dsp);
+	/* pass the pointer as an argument */
+	/* this is recognized by called function declaration */
+	arglist=list3(list2(ADDRESS,e),arglist,list2(POINTER,type));
+	/* return list3(COMMA,list3(FUNCTION,e1,arglist),rvalue(e)); */
     }
     return list3(FUNCTION,e1,arglist);
 }
--- a/test/tmp7.c	Tue Feb 11 11:26:51 2003 +0900
+++ b/test/tmp7.c	Tue Feb 11 22:36:51 2003 +0900
@@ -12,7 +12,10 @@
 struct aa
 main0()
 {
+    int i;
     struct aa ccc;
+
+    for(i=0;i<100;i++) ccc.a[i]=i;
     ccc.a[55]=123;
     return ccc;
 }
@@ -50,11 +53,19 @@
     register char *p;
     int j = 3;
     struct { int b; void (*c)(struct aa); } q = {3,main1},r;
+    struct aa *aap[3];
 
     j = 3;
 
     bbb = main0();
+    printf("copied main0 ccc.a[55] %d==123\n",bbb.a[55]); 
+    aap[2] = &bbb;
+    *aap[2] = main0();
+    printf("complex copied main0 ccc.a[55] %d==123\n",bbb.a[55]); 
+    bbb.a[55]=0;
     j = main0().a[55];
+    printf("new main0 ccc.a[55] in temporal copy %d==123\n",j); 
+
     printf("%d==3\n",q.b);
 /* 3==3 */
     r = q;