changeset 551:73ebe9d82a9c

inline (scope.c/GNU extension) continue...
author kono
date Wed, 04 Jan 2006 14:55:46 +0900
parents df60b120675d
children 74bbea56b8e5
files .gdbinit Changes Makefile mc-codegen.c mc-inline.c mc-parse.c
diffstat 6 files changed, 194 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Tue Jan 03 22:23:26 2006 +0900
+++ b/.gdbinit	Wed Jan 04 14:55:46 2006 +0900
@@ -46,5 +46,6 @@
 # run -s -DINLINE=inline test/basic.c
 # run -s test/too-long-argument.c
 # run -s test/strinit.c
-run -s test/linux_kernel.c.--- 
-# run -s -DINLINE=inline test/scope.c
+# run -s test/linux_kernel.c.--- 
+run -DINLINE=inline test/scope.c
+# run -DINLINE=inline test/code-gen-all.c
--- a/Changes	Tue Jan 03 22:23:26 2006 +0900
+++ b/Changes	Wed Jan 04 14:55:46 2006 +0900
@@ -7793,7 +7793,46 @@
 statement expression ({int x; x+1})  だけど、inline でも、
 call してregister save した方が良いのだが....
 
-
-
-
-
+    parse = list3(ST_COMP,parse,expr(0));
+
+とすると、expr(0)で生成されたparseは失われてしまう。(何故かわかる?)
+
+Wed Jan  4 09:41:39 JST 2006
+
+そろそろ mc-tree を作り直す時か...
+
+ST_COMPがネストしすぎ。ST_COMPじゃんなくてlistをデフォルトに
+すればいいんだよな。append, reverse0 がたくさんでるけど。
+
+やっぱり、statement expression が後ろに廻されてるね。
+        if ({hoge,i}) ....
+を、
+        hoge;
+	if (i) ...
+とcompileしていいのか? LCALL の代わりに「SAVE_REGISTER」みたいな
+ことはできないの?
+
+素直に list3(STATEMENT,statement,value)とすれば? one path では出来ないか。
+
+                    goto exit0;
+                printf("#0051:2nd inner %d %d %0x\n",i,k,&&exit1==exit);
+            exit0:
+            i;
+        ....
+        printf("#0061:inner %d %d %0x\n",i,k,&&exit1==exit);
+    }
+    k++;
+exit0:
+
+やっぱり、label のネストはあるのか... enter_scope しないで
+なんとかする方法ないの? pvartable にkeepすればいいんじゃない?
+だから、new_lvar すればいいんじゃないか? (いいんだけど、
+変更が大きい...)
+
+p_goto が、なんか二重に呼ばれている。まぁ、害はないんだが...
+
+硬いなぁ。scope.c が全然通らない。このコンパイラも複雑すぎる。
+また、simple に戻すのをやらないといじれなくなってしまう。
+
+
+
--- a/Makefile	Tue Jan 03 22:23:26 2006 +0900
+++ b/Makefile	Wed Jan 04 14:55:46 2006 +0900
@@ -126,7 +126,7 @@
 
 #	-./$(MC) -Itest/ -s $(TARGET).c
 
-check: $(MC) $(TARGET).c
+check: mc $(MC) $(TARGET).c
 	-$(CC) $(CFLAGS1) $(STDFLAG) $(TARGET).c -o b.out $(MLIB)
 	-./b.out > $(TARGET).gcc.out
 	-./$(MC) -s $(TARGET).c
@@ -134,7 +134,7 @@
 	-./a.out > $(TARGET).$(MC).out
 	-diff $(TARGET).gcc.out $(TARGET).$(MC).out
 
-check-inline: $(MC) $(TARGET).c
+check-inline: mc $(MC) $(TARGET).c
 	-$(CC) $(CFLAGS1) $(STDFLAG) $(TARGET).c -o b.out $(MLIB)
 	-./b.out > $(TARGET).gcc.out
 	-./$(MC) -s -DINLINE=inline $(TARGET).c
@@ -142,12 +142,12 @@
 	-./a.out > $(TARGET).$(MC).out
 	-diff $(TARGET).gcc.out $(TARGET).$(MC).out
 
-check-code: $(MC)
+check-code: mc $(MC)
 	-./$(MC) -s $(TARGET).c
 	-$(CC) $(TARGET).s $(MLIB)
 	-./a.out > $(TARGET).$(MC).out
 	-diff  $(TARGET).code-out $(TARGET).$(MC).out
-check-code-make: $(MC)
+check-code-make: mc $(MC)
 	-./$(MC) -s $(TARGET).c
 	-$(CC) $(TARGET).s $(MLIB)
 	-./a.out > $(TARGET).code-out
--- a/mc-codegen.c	Tue Jan 03 22:23:26 2006 +0900
+++ b/mc-codegen.c	Wed Jan 04 14:55:46 2006 +0900
@@ -226,7 +226,8 @@
 	code_fname((NMTBL *)(e2),USE_CREG);
 	return ADDRESS;
     case LABEL:
-	code_label_value(e2,USE_CREG);
+	if (car(e2)!=LVAR) error(-1);
+	code_label_value(cadr(e2),USE_CREG);
 	return ADDRESS;
     case CONST:  /* 代入する値が0でも特別な処理はしない */
 	code_const(e2,USE_CREG);
@@ -2487,6 +2488,8 @@
     return labelno++;
 }
 
+// define case label with default label for switch statement
+
 extern void
 def_label(int cslabel, int dlabel)
 {
@@ -2879,9 +2882,12 @@
 	nsc = FLABEL;
 	if (!inmode)
 	    ndsp = fwdlabel();
-	// で、inmode の時は?
-	// 名前のまま、nptr で取っておいて、その場で解決する
-	// scope は関数ローカルになる
+	else
+	    ndsp = --disp;
+	// inmode の時は pvartable のoffset を確保する。st_label で
+	// nptr が 0 ならば backdef、st_label よりも先に使われたら
+	// fwdlabel すれば良い。
+	// scope は parse 時に解決される。
 	break;
     case ADECL:                 // funcion arguments
 	if(!integral(type0)&&type0>0&&(car(type0)==FUNCTION||car(type0)==CODE)) {
@@ -3252,6 +3258,7 @@
 {
     int type_save,mode_save,t,sz;
     NMTBL *n;
+    int sargs = args;
 
     t = cadr(fntype);
     if (t>0 && (car(t)==STRUCT||car(t)==UNION)) {
@@ -3267,13 +3274,14 @@
 	sz = inmode?1:size(type);
 	for(t=fnptr->dsp;t;t=cadr(t)) {
 	    n=(NMTBL *)caddr(t);
-	    n->dsp += sz;
+	    n->dsp += inmode?1:sz;
 	}
 	fnptr->dsp = reverse0(fnptr->dsp);
 	if ((sz=size(cadr(fntype)))==-1) error(TYERR);
 	else {
-	    args = 0;
-	    def(&str_ret,0);
+	    args=0;  // set struct var dsp = 0
+	    def(&str_ret,0); 
+	    args = sargs + (inmode?1:size_of_int);
 	    struct_return = inmode
 		?list3(list3(IVAR,str_ret.dsp,0),sz,type)
 		:list3(list3(LVAR,str_ret.dsp,0),sz,type);
@@ -3371,7 +3379,7 @@
 	    lastexp = 0;   // checkret can be nest?
 	    gexpr(lastexp0,0);
 	}
-    } else {
+    } else if (lastexp) {
 	parse = list3(ST_COMP,parse,lastexp);
 	lastexp = 0;
     }
--- a/mc-inline.c	Tue Jan 03 22:23:26 2006 +0900
+++ b/mc-inline.c	Wed Jan 04 14:55:46 2006 +0900
@@ -279,41 +279,18 @@
         retpending = 1;
         return;
     }
-    // conv->return_();
-    if (struct_return) {
-	// certainly this is wrong for inline 
-	if ((car(type)==STRUCT || car(type)==UNION)&&
-		size(type)==cadr(struct_return)) {
-	    if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) {
-		/* pass the return pointer to the called function */
-		replace_return_struct(cadr(e),
-		    rvalue_t(car(struct_return),caddr(struct_return)));
-		g_expr_u(cadr(e));
-	    } else {
-		type = caddr(struct_return);
-		// e1 = rvalue_t(cadr(struct_return),INT); /* size */
-		e1 = cadr(struct_return); /* size */
-		g_expr_u(list4(STASS,rvalue(car(struct_return)),e,e1));
-	    }
-	    if (ret_reg_mode==0) {
-		ret_reg_mode=1;
-		ret_register = code_get_fixed_creg(USE_CREG,INT);
-	    } else {
-		code_set_fixed_creg(ret_register,1,INT);
-	    }
-	} else {
-	    error(TYERR); /* should check compatible */
-	}
+    t = type_value(cadr(fnptr->ty));
+    if (t>0 && (car(t)==STRUCT || car(t)==UNION)) {
+	// copy is included in e, pass the pointer
+	t = list2(POINTER,type_value(cadr(fnptr->ty)));
+    } 
+    g_expr(e);
+    if (ret_reg_mode==0) {
+	// return value register is not fixed
+	ret_reg_mode=1;
+	ret_register = code_get_fixed_creg(USE_CREG,t);
     } else {
-	g_expr(e);
-	t = type_value(cadr(fnptr->ty));
-	if (ret_reg_mode==0) {
-	    // return value register is not fixed
-	    ret_reg_mode=1;
-	    ret_register = code_get_fixed_creg(USE_CREG,t);
-	} else {
-	    code_set_fixed_creg(ret_register,1,t);
-	}
+	code_set_fixed_creg(ret_register,1,t);
     }
     // conv->return_end_();
     retpending = 1;
@@ -321,34 +298,25 @@
 
 extern void
 st_goto(int e){
-    NMTBL *nlist,*nptr0;
-    int t,e1,e2,env;
+    NMTBL *nptr0;
+    int e1,e2,env;
 
     checkret();
-    // conv->goto_();
     e1 = caddr(e);
     if (car(e1)==RINDIRECT) {
 	gen_indirect_goto(cadr(e1));
 	return ;
+    } else if (car(e1)==RLVAR||car(e1)==LVAR) {
+	gen_indirect_goto(e1);
+	return ;
     } else if (car(e1)==FLABEL) {
-	nlist = (NMTBL *)cadr(e1);
-	nptr0 = name_space_search(nlist,0);
-        t = nptr0->sc;
-        if (t==EMPTY||t==EXTRN1||t==EXTRN) {
-	    nptr0 = make_local_scope(nlist,nptr0,0);
-            nptr0->sc = FLABEL;
-            nptr0->dsp = fwdlabel();
-        } else if (!(t==FLABEL||t==BLABEL)) {
-            error(STERR);
-        }
-	gen_jmp(nptr0->dsp);
+	gen_jmp(cadr(e1));
         control=0;
-        // conv->sm_();
-        // conv->goto_label_(nptr0);
         return ;
-    } else {
+    } else if (car(e1)==CODE) {
 	/*   CbC continuation */
 	// conv->jump_(env);
+	// should be separate function
 	e2 = cadr(e1);
 	env = caddr(e1);
 	if (car(e2) == FNAME) {
@@ -364,6 +332,8 @@
 	control=0;
 	// conv->sm_();
 	return ;
+    } else {
+	error(-1);
     }
 }
 
@@ -379,22 +349,12 @@
  
 extern void
 st_label(int e1){
-    NMTBL *nptr,*nlist;
-    nlist = (NMTBL *)caddr(e1);
-    nptr = name_space_search(nlist,0);
+    int lb = caddr(e1);
     control=1;
     checkret();
-    if(nptr->sc == FLABEL) {
-	fwddef(nptr->dsp);
-    } else if(nptr->sc != EMPTY && nptr->sc != EXTRN1 && nptr->sc !=BLABEL) {
-	error(TYERR);
-    } else {
-	nptr->sc=EMPTY;
-	nptr = make_local_scope(nlist,nptr,0);
-	nptr->sc = BLABEL;
-	nptr->dsp = backdef();
-    }
-    // conv->label_();
+    if (car(lb)==LVAR) {  // label variable case
+    } else if (car(lb)!=FLABEL) error(-1);
+    fwddef(cadr(lb));
 }
 
 extern void
@@ -601,7 +561,10 @@
     // is used or not.
     switch(stmode) {
     case EXTRN: case EXTRN1: case STATIC:
+	    // def(n,0); // ctmode?
 	    return pexpr(cadr(e));
+    case LLDECL:
+	v = list2(FLABEL,fwdlabel()); break;
 #if 1
     case REGISTER:
 	switch(n->ty) {
@@ -724,12 +687,17 @@
 static int
 p_goto(int e)
 {
-    int e1;
+    int e1,lb;
     if ((e1=caddr(e))) {
 	switch(car(e1)) {
 	case RINDIRECT: e1=pexpr(e1); break;
 	case CODE: e1=list3(CODE,pexpr(cadr(e1)),pexpr(caddr(e1))); break;
-	case FLABEL: break;
+	case FLABEL: /* error(-1); */ break;
+	case IVAR: 
+	    lb = cadr(e1);
+	    if (!(e1=heap[pdisp+lb])) {
+		e1 = heap[pdisp+lb]=list2(FLABEL,fwdlabel());
+	    }
 	}
     }
     return list3(ST_GOTO,pexpr(cadr(e)),e1);
@@ -756,7 +724,34 @@
 static int
 p_label(int e)
 {
-    return list3(ST_LABEL,pexpr(cadr(e)),caddr(e));
+    int e1,lb;
+    if ((e1=caddr(e))) {
+	switch(car(e1)) {
+	case FLABEL: /* error(-1); */ break;
+	case IVAR: 
+	    lb = cadr(e1);
+	    if (!(e1=heap[pdisp+lb])) {
+		e1 = heap[pdisp+lb]=list2(FLABEL,fwdlabel());
+	    }
+	}
+    }
+    return list3(ST_LABEL,pexpr(cadr(e)),e1);
+}
+
+static int
+p_label_var(int e)
+{
+    int d,e1;
+    switch(car(e1=e)) {
+    case LVAR: /* error(-1) */ break;
+    case IVAR: 
+	// should this done in p_decl? (in __label__?)
+	d = cadr(e);
+	if (!(e1=(heap[pdisp+d])))  {
+	    e1 = heap[pdisp+d]=list3(LVAR,fwdlabel(),caddr(e));
+	}
+    }
+    return list2(LABEL,e1);
 }
 
 static int
@@ -801,14 +796,18 @@
     case FRGVAR: case  DRGVAR:
     case LREGISTER:
     case LRGVAR: case LURGVAR:
-    case LABEL: case CONST: 
+    case CONST: 
     case DCONST: case FCONST:
     case LCONST:
     case STRING:
     case FNAME:
     case FLABEL:
-    case RSTRUCT:
 	return e1;
+    case RSTRUCT: 
+	// list3(RSTRUCT,e,size)
+	return pexpr(e2);
+    case LABEL: 
+	return p_label_var(e2);
     case LVAR:
     case RLVAR: case CRLVAR: case CURLVAR: case SRLVAR: case SURLVAR:
     case FRLVAR: case DRLVAR: 
@@ -1011,6 +1010,7 @@
     case ST_LABEL:        return p_label(e1);
     case ST_COMMENT:      return p_comment(e1);
     default:
+	error(-1);
 	return p_bool(e1);
   }
   return VOID;
--- a/mc-parse.c	Tue Jan 03 22:23:26 2006 +0900
+++ b/mc-parse.c	Wed Jan 04 14:55:46 2006 +0900
@@ -1810,9 +1810,10 @@
 	// arglist is set by adecl() and is reversed.
 	fnptr->dsp = arg_reorder(arglist,fnptr->dsp);
     }
-    arg_disp = args;
     fnptr->dsp=reverse0(fnptr->dsp);
     fdecl_struct(fnptr->ty); /* insert extra argument for struct passing */
+    arg_disp = args;
+    args = 0;
     disp=0;
     if (!inmode)
 	arg_register(fnptr);
@@ -1929,7 +1930,7 @@
 static void
 statement(int use)
 {
-    int slfree;
+    int slfree,e;
 
     if(sym==SM) {
 	conv->sm_();
@@ -2007,7 +2008,8 @@
 		if (use) {
 		    lastexp = expr(0);
 		} else {
-		    parse = list3(ST_COMP,parse,expr(0));
+		    e = expr(0);
+		    parse = list3(ST_COMP,parse,e);
 		}
 	    } else {
 		if (use) {
@@ -2128,7 +2130,7 @@
 static void
 dodo(void)
 {
-    int sbreak,scontinue,l,slfree,pparse;
+    int sbreak,scontinue,l,slfree,pparse,e;
 
     sbreak=blabel;
     scontinue=clabel;
@@ -2155,7 +2157,8 @@
     slfree=lfree;
     conv->dowhile_cond_();
     if (inmode) {
-	parse = list4(ST_DO,pparse,expr(0),l);
+	e = expr(0);
+	parse = list4(ST_DO,pparse,e,l);
     } else {
 	bexpr(expr(0),1,l);
     }
@@ -2520,33 +2523,43 @@
 	return;
     }
     conv->return_();
-    if (!inmode) {
-	slfree=lfree;
-	if (struct_return) {
-	    e = expr(0);
-	    if ((car(type)==STRUCT || car(type)==UNION)&&
-		    size(type)==cadr(struct_return)) {
-		if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) {
-		    /* pass the return pointer to the called function */
-		    replace_return_struct(cadr(e),
-			rvalue_t(car(struct_return),caddr(struct_return)));
+    slfree=lfree;
+    if (struct_return) {
+	e = expr(0);
+	if ((car(type)==STRUCT || car(type)==UNION)&&
+		size(type)==cadr(struct_return)) {
+	    if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) {
+		/* return struct_return_f(); case */
+		/* pass the return pointer to the called function */
+		replace_return_struct(cadr(e),
+		    rvalue_t(car(struct_return),caddr(struct_return)));
+		if (inmode) {
+		    parse = list3(ST_RETURN,parse,cadr(e));
+		} else
 		    gexpr(cadr(e),0);
-		} else {
-		    type = caddr(struct_return);
-		    // e1 = rvalue_t(cadr(struct_return),INT); /* size */
-		    e1 = cadr(struct_return); /* size */
+	    } else {
+		type = caddr(struct_return);
+		// e1 = rvalue_t(cadr(struct_return),INT); /* size */
+		e1 = cadr(struct_return); /* size */
+		if (inmode) {
+		    parse = list3(ST_RETURN,parse,
+			    list4(STASS,rvalue(car(struct_return)),e,e1));
+		} else
 		    gexpr(list4(STASS,rvalue(car(struct_return)),e,e1),0);
-		}
-	    } else {
-		error(TYERR); /* should check compatible */
 	    }
 	} else {
+	    error(TYERR); /* should check compatible */
+	}
+    } else {
+	if (inmode) {
+	    e = correct_type(expr(0),cadr(fnptr->ty));
+	    parse = list3(ST_RETURN,parse,e);
+	} else {
 	    gexpr(correct_type(expr(0),cadr(fnptr->ty)),1);
 	}
-	set_lfree(slfree);
-    } else {
-	parse = list3(ST_RETURN,parse,correct_type(expr(0),cadr(fnptr->ty)));
     }
+    set_lfree(slfree);
+
     conv->return_end_();
     checksym(SM);
     /* control = 0; still control continue until pending return emission */
@@ -2577,10 +2590,6 @@
     }
     if (t==FNAME) {
 	nptr0 = (NMTBL *)cadr(e1);
-	if (inmode) {
-	    parse = list3(ST_GOTO,parse,
-		list2(FLABEL,(int)get_name(nptr0->nm,0,0)));
-	}
 	t = nptr0->sc;
 	if (t==EMPTY||t==EXTRN1||t==EXTRN) {
 	    // error check?
@@ -2588,10 +2597,12 @@
 	    nptr0=l_top_search(nptr0->nm,0);
 	    nptr0->sc = FLABEL;
 	    if (!inmode) nptr0->dsp = fwdlabel();
+	    else nptr0->dsp = --disp;
 	} else if (!(t==FLABEL||t==BLABEL)) {
 	    error(STERR);
 	}
 	if (!inmode) gen_jmp(nptr0->dsp);
+	else parse = list3(ST_GOTO,parse,list3(IVAR,nptr0->dsp,(int)nptr0));
 	control=0;
 	conv->sm_();
 	checksym(SM);
@@ -2638,11 +2649,11 @@
     NMTBL *nptr1;
     control=1;
     checkret();
-    if (inmode)
-	parse = list3(ST_LABEL,parse,(int)get_name(nptr->nm,0,0));
     if(nptr->sc == FLABEL) {
 	// already used by goto with fwdlabel
+	// or this is a local label defined by __label__
 	if (!inmode) fwddef(nptr->dsp);
+	else parse = list3(ST_LABEL,parse,list3(IVAR,nptr->dsp,(int)nptr));
     } else if(nptr->sc != EMPTY && nptr->sc != EXTRN1) {
 	error(TYERR); // duplicate label
     } else {
@@ -2651,6 +2662,10 @@
 	nptr1=l_top_search(nptr->nm,0);
 	nptr1->sc = BLABEL;
 	if (!inmode) nptr1->dsp = backdef();
+	else {
+	    nptr1->dsp = --disp;
+	    parse = list3(ST_LABEL,parse,list3(IVAR,nptr1->dsp,(int)nptr1));
+	}
     }
     conv->label_();
     getsym(0);
@@ -3198,10 +3213,15 @@
             nptr1->sc=EMPTY;
             nptr1=l_top_search(nptr->nm,0);
             nptr1->sc = FLABEL;
-            nptr1->dsp = fwdlabel();
+	    if (!inmode)
+		nptr1->dsp = fwdlabel();
+	    else
+		nptr1->dsp = --disp;
         }
 	type = list2(POINTER,VOID);
-	return list2(LABEL,nptr1->dsp);
+	// can be global?!
+	return list2(LABEL,
+	    list3(inmode?IVAR:LVAR,nptr1->dsp,(int)nptr1));
     }
     e=expr14();
 
@@ -3457,8 +3477,10 @@
 	    // cntl prevents this. 
 	    int l,b,l2,cntl=control;
 	    if (inmode) {
+		int sparse = parse; parse=0;
 		docomp(1);
-		e1 = lastexp;
+		e1 = list3(COMMA,parse,lastexp);
+		parse = sparse;
 		lastexp = 0;
 	    } else {
 		if (cntl) {
@@ -3641,7 +3663,8 @@
 	arglist = append3(arglist,list2(ADDRESS,e),list2(POINTER,type));
     }
     if (car(e1)==FNAME) {
-	if (is_inline((NMTBL *)cadr(e1))) {
+	// recursive inline is not allowed
+	if ((NMTBL *)(cadr(e1))!=fnptr && is_inline((NMTBL *)cadr(e1))) {
 	    return list4(INLINE,e1,arglist,ftype);
 	}
     }