changeset 48:8575ec496cd4

jump with overrupped struct (first code)
author kono
date Sun, 16 Feb 2003 01:01:06 +0900
parents f6b5e4f1a962
children 884c74e6a2f7
files mc-nop-386.c mc-parse.c
diffstat 2 files changed, 199 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/mc-nop-386.c	Sat Feb 15 18:19:27 2003 +0900
+++ b/mc-nop-386.c	Sun Feb 16 01:01:06 2003 +0900
@@ -1012,6 +1012,180 @@
     regv[creg]=1;
 }
 
+/* goto arguments list */
+/* target list3(list2(tag,disp),cdr,ty) */
+/* source list4(tag,cdr,expr,ty) */
+
+void
+disp_source(int e3) {
+    printf("# jump arg list\n");
+    for (e3 = target; e3; e3 = cadr(e3)) {	
+	printf("#    %d, expr %d, size %d\n",car(e3),caddr(e3),cadddr(e3));
+    }
+}
+
+int
+overrap(int t,int source)
+{
+    int s0,s1;
+    int t0=cadr(car(t));
+    int t1=size(caddr(t));
+    for(;source;source=cadr(source)) {
+	s0=cadr(caddr(source));
+	if(car(source)==REGISTER && car(car(t))==REGISTER) {
+	    if(s0==t0) return 1;
+	} else if(car(source)==car(car(t))) {
+	    s1=s0+size(cadddr(source));
+	    if((t0<=s0&&s0<=t1)||(t0<=s1&&s1<=t1)) return 1;
+	}
+    }
+    return 0;
+}
+
+int
+target_frame(int *source,int *target,int *processing)
+{
+    int t,s,e1;
+    while(*target) {
+	t=car(*target);
+	s=caddr(*source);
+	for(p=*processing;p;p=cadr(p)) {
+	    if(car(p)==t) { /*ターゲットが処理リスト中にある*/
+		remove(target,t); remove(source,s); remove(processing,p);
+		/*新しいレジスタ(or スタック)を取得する*/
+		sz=size(ty=caddr(t)); 
+		if (sz==size_of_int && (e1=get_register())!=-1)) {
+		    e1=list2(REGISTER,e1);
+		    g_expr(assign_expr(e1,car(s),ty,ty));
+		    return assign_expr(car(t),e1,ty,ty);
+		} else {
+		    disp+=sz;
+		    gen_jump_assign(car(s),disp,ty);
+		    return assign_expr(car(t),list2(LVAR,disp),ty,ty);
+		}
+	    }
+	}
+	if(car(t)==car(s) && cadr(t)==cadr(s)) {
+            /*書き込み先が自分自身*/
+	    remove(target,t); remove(source,s);
+	} else if (overrap(t,source,caddr(t))) {
+            /*書き込み先がソースと重なっている*/
+	    *prcoessing=list2(t,*processing);
+	    remove(target,t); remove(source,s);
+            /*他のを先にする*/
+	    e1=target(source,target,processing);
+	    /* これで空いたはず*/
+	    g_expr(assign_expr(car(t),car(s),ty,ty));
+	    /* 横によけたものがあれば、後始末をする*/
+	    if(e1) 
+		g_expr(e1);
+	} else {
+	    g_expr(assign_expr(car(t),car(s),ty,ty));
+	    remove(target,t); remove(source,s);
+	}
+    }
+    return 0;
+}
+
+void
+gen_jump_assign(int e3,int disp,int ty)
+{
+    int stype,e2,e4;
+    e2=caddr(e3);
+    stype = type;
+    g_expr(assgin_expr((e4=list2(LVAR,disp)),e2,ty,ty));
+    type = stype;
+    heap[e3]=LVAR; heap[e3+2]=e4;
+}
+
+void 
+remove(int *parent,int e) {
+    int list;
+    while (list=*parent) {
+	if (car(list)==e) {
+	    *parent= cadr(list);
+	} else {
+	     parent=&cadr(list);
+	}
+    }
+}
+
+void
+jump(int e1, int env)
+{
+    int e2,e3,sz,arg_size,ejmp,ty;
+    NMTBL *code0;
+    int target = 0;
+    int source = 0;
+    int processing = 0;
+
+    /* まず、サイズを計算しながら、決まった形に落す。 */
+    arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR;
+    for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
+	e2 = car(e3); sz = size(ty=caddr(e3)); arg_size += sz;
+	if (regs <= max_regs&&integral(ty)) {
+	    target=list3(list2(REGISTER,(regs++)+REG_ESI),target,ty);
+	} else {
+	    target=list3(list2(LVAR,arg_size-MAX_RGISTER_VAR),target,ty);
+	}
+	switch (car(e2)) {
+	case CONST:     source = list4(CONST,source,e2,ty); break;
+	case LVAR:      source = list4(LVAR,source,e2,ty); break;
+	case REGISTER:  source = list4(REGISTER,source,e2,ty); break;
+	case GVAR:      source = list4(GVAR,source,e2,ty); break;
+	default:        source = list4(0,source,e2,ty); break;
+    }
+    disp_source(source);
+
+    arg_size = arg_size-MAX_RGISTER_VAR*size_of_int;
+    /* disp を飛び先似合わせて修正 */
+    if (arg_size>disp) disp = arg_size;
+
+    /*  複雑な式を前もって計算しておく     */
+    /*  必要なら局所変数を用いる。         */
+    /*  局所変数へのオフセットを覚えておく */
+    /*  ついでに、同じものがあれば、除く */
+
+    for (e3 = source,e2 = target; e3; e3 = cadr(e3),e2 = cadr(e2)) {	
+	if (car(e3)==0) {
+	    disp+=size(ty=cadddr(e3));
+	    gen_jump_assign(e3,disp,ty);
+	} else if (car(e3)==car(e2)&&cadr(e3)==cadr(e2)) {
+	    remove(&source,e3);remove(&target,e2);
+	}
+    }
+
+    /* compute jump address */
+    e2 = cadr(e1);
+    if (car(e2) == FNAME) {	
+	code0=(NMTBL *)cadr(e2);
+	if (code0->sc!=CODE) {
+	    error(TYERR); return;
+	}
+    } else {	/* indirect */
+	g_expr(e2);
+	emit_push();
+    }
+
+    /* 並列代入を実行 */
+
+    target_frame(&source,&target,&processing);
+
+    if (!env && arg_size>disp) {
+	/* shrink stack if necessary */
+	printf("\tleal %d(%%ebp),%%esp\n",arg_size);
+    } 
+    if (car(e2) == FNAME) {	
+	printf("\tjmp %s\n",code0->nm);
+    } else {
+	e2 = emit_pop(0);
+	printf("\tjmp *%s\n",register_name(e2,0));
+	emit_pop_free(e2);
+    }
+    free_all_register();
+}
+
+#if 0
 int
 arg_size(int e3,int *nargs0)
 {
@@ -1038,50 +1212,11 @@
 {
     int e2 = car(e1);
     return (
-	e2==FNAME || e2==LVAR || e2==CRLVAR || e2==REGISTER
+	e2==CONST || e2==FNAME || e2==LVAR || e2==CRLVAR || e2==REGISTER
     );
 }
 
 void
-jump_new(int e1, int env)
-{
-    int e2;
-    NMTBL *code0;
-/*
-      jump アドレスを計算する
- */
-    /* compute jump address */
-    e2 = cadr(e1);
-    if (car(e2) == FNAME) {	
-	code0=(NMTBL *)cadr(e2);
-	if (code0->sc!=CODE) {
-	    error(STERR); return;
-	}
-    } else {	/* indirect */
-	g_expr(e2);
-	emit_push();
-    }
-/*
-      まず、複雑な式を前もって単純な式に落す。
-      必要なら局所変数を用いる。
-      局所変数へのオフセットを覚えておく
- */
-/*
-      スタックの位置を修正する
- */
-/*
-      オフセットを用いて、
-      並べ変えを行う
- */
-/*
-      スタックの位置を修正する
- */
-/*
-      jump code を生成する
- */
-}
-
-void
 jump(int e1, int env)
 {
     int i,args,e2,e3,e4,e5,nargs,regs;
@@ -1208,7 +1343,7 @@
     }
     fnptr->sc = scode;
 }
-
+#endif
 
 void
 machinop(int e1)
--- a/mc-parse.c	Sat Feb 15 18:19:27 2003 +0900
+++ b/mc-parse.c	Sun Feb 16 01:01:06 2003 +0900
@@ -127,6 +127,7 @@
 extern void code_leave(char *name,int disp) ;
 extern void code_enter1(int disp0,int args);
 extern int csvalue();
+extern int assign_expr(int e1,int e2,int t,int type);
 
 extern void emit_data_closing(NMTBL *n);
 extern void emit_data(int e, int t, NMTBL *n);
@@ -1512,6 +1513,27 @@
 }
 
 int
+assign_expr(int e1,int e2,int t,int type) {
+    if(t==VOID)
+	error(TYERR);
+    if(t==CHAR) {
+	type= INT;return(list3(CASS,e1,e2));
+    } else if(!scalar(t)&&(car(t)==STRUCT||car(t)==UNION)) {
+	if (size(t)!=size(type)) error(TYERR);
+	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)));
+	}
+    } else {
+	type=t;
+	return(list3(ASS,e1,e2));
+    }
+}
+
+int
 expr(void)
 {
     return(rvalue(expr0()));
@@ -1540,22 +1562,7 @@
 	t=type;
 	getsym();
 	e2=rvalue(expr1());
-	if(t==VOID)
-	    error(TYERR);
-	if(t==CHAR) {
-	    type= INT;return(list3(CASS,e1,e2));
-	} else if(!scalar(t)&&(car(t)==STRUCT||car(t)==UNION)) {
-	    if (size(t)!=size(type)) error(TYERR);
-	    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));
+	return assign_expr(e1,e2,t,type);
     case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS:
     case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS:
 	op = sym-AS;