Mercurial > hg > CbC > old > device
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); } }