Mercurial > hg > CbC > old > device
changeset 453:1e5ca85d3f97
inline on going...
author | kono |
---|---|
date | Tue, 30 Nov 2004 02:20:42 +0900 |
parents | 8e3284b0a8c9 |
children | 214272c8f2da |
files | .gdbinit Changes Makefile mc-code-powerpc.c mc-codegen.c mc-codegen.h mc-h-renum.pl mc-parse.c mc-parse.h mc.h |
diffstat | 10 files changed, 954 insertions(+), 178 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Mon Nov 29 04:15:38 2004 +0900 +++ b/.gdbinit Tue Nov 30 02:20:42 2004 +0900 @@ -9,7 +9,7 @@ # run -s test/basic.c # run -s test/code-gen-all.c # run -s test/tmp7.c -run -s test/tmp1.c +run -s test/inline.c define regs printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4 printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
--- a/Changes Mon Nov 29 04:15:38 2004 +0900 +++ b/Changes Tue Nov 30 02:20:42 2004 +0900 @@ -6618,23 +6618,27 @@ よし、inline やるか。 inline function (or parsed tree) - list4(INLINE,name,type) + // list4(INLINE,name,type) + sc = INLINE + attr = parse declaration (argument, local, static) - list4(DECL,next,init,NMTBL *nptr) done by def (?) + list4(ST_DECL,next,NMTBL *nptr,stmode) done by def (?) statement - list3(IF,next,list3(cond,then,else)) - list3(DO,next,list2(cond,while)) - list3(FOR,next,list4(A,B,C,body)) - list4(SWITCH,next,expr,body) - list3(COMP,next,body) - list2(BREAK,next) - list2(CONTINUE,next) - list3(CASE,next,label) + list3(ST_IF,next,list3(cond,then,else)) + list4(ST_DO,next,cond,while) + list4(ST_WHILE,next,cond,while) + list3(ST_FOR,next,list4(A,B,C,body)) + list4(ST_SWITCH,next,expr,body) + list3(ST_COMP,next,body) + list2(ST_BREAK,next) + list2(ST_CONTINUE,next) + list3(ST_CASE,next,label) + list3(ST_DEFAULT,next) list3(ST_RETURN,next,expr) - list3(GOTO,next,expr,env) - list3(ST_ASM,next,list4(A,B,C,D)) + list3(ST_GOTO,next,expr,env) + list3(ST_ASM,next,list4(A,B,C,D),e1) list3(ST_LABEL,next,label) - list3(COMMENT,next,comment) (?) + list3(ST_COMMENT,next,comment) (?) いくつかはexprと重なるけど... (まずい?) RETURN, ASM @@ -6933,3 +6937,29 @@ int arg0,...argn; } } + +Mon Nov 29 11:55:14 JST 2004 + +attr は、連想リストにするべきか。 + +partial evaluation を、どの段階で行うかっていう問題があるのか。 + +expr15 (function call) + +inline 木作成の最中に展開すると繰り返し展開することになる。 +しなくても良いが... しかも、ST_* が expr の中に残ってしまう +ので、g_expr で、ST_* を扱うことが必須。ってことは変更が結構 +大きい。ここで展開すると binop の最適化にひっかかるので簡単。 +docomp と同じ扱いが必要? + +function (codegen) + +ここで展開すると、代入とかが変数扱いしかしなくなる。手遅れ。 + +ってことは、expr15 で、partial evalucation はやる。inline +中は展開しないとして、残った ST_* は、g_expr で処理する +ってことですね。 + +static でもポインタを取られたりすると関数を生成する必要がある。 +extern なら、なおさら。それは、自分でやらないとダメ。まぁ、 +inline の関数リストを作るのが良いんだろうけど。
--- a/Makefile Mon Nov 29 04:15:38 2004 +0900 +++ b/Makefile Tue Nov 30 02:20:42 2004 +0900 @@ -15,7 +15,7 @@ PRINTF= # printf.c CONVERTER=conv/c.o conv/null.o # conv/c2cbc.o conv/cbc2c.o -COMPLIB = mc-parse.o mc-codegen.o mc-switch.o mc-macro.o mc-tree.o +COMPLIB = mc-parse.o mc-codegen.o mc-switch.o mc-macro.o mc-tree.o mc-inline.o # CODE=mc-code-ia32.c CODE=mc-code-$(ARCH).c # @@ -31,6 +31,7 @@ mc-macro.c \ mc-parse.c mc-tree.c mc-switch.c mc-switch.h \ mc.h conv/c.c conv/c.h \ + mc-inline.h mc-inline.c \ conv/conv.h conv/convdef.h conv/null.c mc-powerpc : mc-code-powerpc.o $(COMPLIB) $(CONVERTER) @@ -93,6 +94,7 @@ make check TARGET=test/cext make check TARGET=test/const make check TARGET=test/void_code + make check TARGET=test/inline # make check TARGET=test/scope STDFLAG="-std=gnu99" #MK =-make MK= @@ -163,11 +165,11 @@ clean : -rm -f mc mc-ia32 mc-powerpc mc-mips mc-arm *.bak *.s *.o *.cc mc mc1 mc2 a.out *~ core* */*.o *.bak test/*.s test/*.cc test/*.o test/*.bak test/*~ conv/*.s conv/*.cc conv/*.o conv/*.bak conv/*~ *.out */*.out *.i */*.i -mc1 : b00.s b01.s mc-codegen.o mc-tree.o mc-switch.o mc-macro.o $(CONVERTER) - $(CC) -g -o $@ $(PRINTF) b00.s b01.s mc-codegen.o mc-tree.o mc-switch.o mc-macro.o $(CONVERTER) +mc1 : b00.s b01.s mc-codegen.o mc-tree.o mc-switch.o mc-macro.o mc-inline.o $(CONVERTER) + $(CC) -g -o $@ $(PRINTF) b00.s b01.s mc-codegen.o mc-tree.o mc-switch.o mc-macro.o mc-inline.o $(CONVERTER) -mc2 : b00.s b01.s b02.s b03.s mc-macro.o $(CONVERTER) - $(CC) -g -o $@ $(PRINTF) b00.s b01.s b02.s b03.s b04.s mc-macro.o $(CONVERTER) +mc2 : b00.s b01.s b02.s b03.s mc-macro.o mc-inline.o $(CONVERTER) + $(CC) -g -o $@ $(PRINTF) b00.s b01.s b02.s b03.s b04.s mc-macro.o mc-inline.o $(CONVERTER) b00.s : mc-parse.c $(MC) ./$(MC) -s -ob00.s mc-parse.c
--- a/mc-code-powerpc.c Mon Nov 29 04:15:38 2004 +0900 +++ b/mc-code-powerpc.c Tue Nov 30 02:20:42 2004 +0900 @@ -3165,7 +3165,9 @@ } init = 0; for(n = global_list;n!=&null_nptr;n = n->next) { -// if (is_code(n)||is_function(n)) continue; + if ((is_code(n)||is_function(n))&& + !has_attr(n,FNAME)) // not used as value + continue; if (n->sc==EXTRN1) { if(init==0) { printf(".data\n");
--- a/mc-codegen.c Mon Nov 29 04:15:38 2004 +0900 +++ b/mc-codegen.c Tue Nov 30 02:20:42 2004 +0900 @@ -6,6 +6,7 @@ #include "mc-parse.h" #include "mc-codegen.h" #include "mc-code.h" +#include "mc-inline.h" int use; /* generated value will be used */ char *init_src; @@ -56,6 +57,22 @@ static int bassop(int e1,int e2,int op,int t,int post); #endif +static void st_decl(int e1); +static void st_if(int e1); +static void st_do(int e1); +static void st_while(int e1); +static void st_for(int e1); +static void st_switch(int e1); +static void st_compj(int e1); +static void st_break(int e1); +static void st_continue(int e1); +static void st_case(int e1); +static void st_default(int e1); +static void st_return(int e1); +static void st_goto(int e1); +static void st_asm(int e1); +static void st_label(int e1); +static void st_comment(int e1); extern void codegen_init() @@ -127,14 +144,15 @@ extern int g_expr0(int e1) { - int e2,e3,t,d,t1; - NMTBL *n; - - if (mode==INLINE) { - return (parse = list2(e1,parse)); - } - if (!control) return VOID; - + int e2,e3,t,d,t1; + NMTBL *n; + + if (mode==INLINE) { + return (parse = list3(ST_COMP,parse,e1)); + } + if (!control) return VOID; + + for(;e1;e1=e2) { code_gexpr(e1); e2 = cadr(e1); @@ -505,10 +523,28 @@ /* asm in (str) out (str) opt(str) expr */ return VOID; #endif + case ST_DECL: st_decl(e1); break; + case ST_IF: st_if(e1); break; + case ST_DO: st_do(e1); break; + case ST_WHILE: st_while(e1); break; + case ST_FOR: st_for(e1); break; + case ST_SWITCH: st_switch(e1); break; + case ST_COMP: st_comp(e1); break; + case ST_BREAK: st_break(e1); break; + case ST_CONTINUE: st_continue(e1); break; + case ST_CASE: st_case(e1); break; + case ST_DEFAULT: st_default(e1); break; + case ST_RETURN: st_return(e1); break; + case ST_GOTO: st_goto(e1); break; + case ST_ASM: st_asm(e1); break; + case ST_LABEL: st_label(e1); break; + case ST_COMMENT: st_comment(e1); break; default: code_bool(e1,USE_CREG); /* type? */ return INT; } + } + return VOID; } static int @@ -744,6 +780,12 @@ } extern int +is_inline(NMTBL *f) +{ + return (f && attr_value(f,INLINE)); +} + +extern int function_type(int e1,int *dots) { int ret_type,t; @@ -2370,6 +2412,13 @@ extern void closing() { + int e; + NMTBL *n; + for(e=inline_funcs;e;e=cadr(e)) { + n = (NMTBL*)car(e); + if (1 || n->sc==EXTRN || has_attr(n,FNAME)) // global or used as pointer + pfdecl(n); + } if (!chk) code_closing(); } @@ -2601,7 +2650,7 @@ if(type>0&&(car(type)==FUNCTION || car(type)==CODE)) { if ((mode==GDECL)) { fcheck(n); - n->attr = ctmode; + if (ctmode) set_attr(n,KONST,0); return n; /* function and code segment are defined using fdecl/code_decl */ /* in decl() */ @@ -2671,7 +2720,7 @@ } } gpc +=sz; - n->attr = list2(ctmode,0); + if (ctmode) set_attr(n,KONST,0); return n; case GSDECL: case LSDECL: disp += sz; @@ -2688,7 +2737,8 @@ break; case LLDECL: nsc = FLABEL; - ndsp = fwdlabel(); + if (!inmode) + ndsp = fwdlabel(); break; case ADECL: if(!integral(type)&&(car(type)==FUNCTION||car(type)==CODE)) { @@ -2724,11 +2774,11 @@ } else { n->ty = type; } - n->attr = ctmode; + if (ctmode) set_attr(n,KONST,0); return n; case STAT: /* return (struct hoge)f() case? */ case LDECL: - if (stmode==REGISTER) { + if (stmode==REGISTER && !inmode) { if(scalar(type)) { ndsp = get_register_var(n); #if FLOAT_CODE @@ -2750,14 +2800,14 @@ } n->sc = nsc; n->dsp = ndsp; - n->attr = list2(ctmode,0); + if (ctmode) set_attr(n,KONST,0); return n; default: error(DCERR); } n->sc = nsc; n->dsp = ndsp; - n->attr = list2(ctmode,0); + if (ctmode) set_attr(n,KONST,0); if (stmode==EXTRN) n->sc = EXTRN; return n; @@ -2904,8 +2954,8 @@ return offset+sz; } /* constant value field */ - if (offset==0 && n && car(n->attr)==KONST) { - cadr(n->attr) = e; + if (offset==0 && (has_attr(n,KONST))) { + set_attr(n,KONST,e); } return offset+((t==EMPTY)?cadr(e):size(t)); } @@ -3117,7 +3167,7 @@ extern int rvalue(int e) { - int op; + int op,c; NMTBL *n; if (e==0) error(-1); @@ -3166,14 +3216,14 @@ switch(car(e)) { case GVAR: n = (NMTBL*)caddr(e); - if (cadr(e)==0 && n->attr && car(n->attr)==KONST) { - if (cadr(n->attr)) return cadr(n->attr); + if (cadr(e)==0 && (c=attr_value(n,KONST))) { + return c; } return(list3(RGVAR+op,cadr(e),caddr(e))); case LVAR: n = (NMTBL*)caddr(e); - if (n && car(n->attr)==KONST) { - if (cadr(n->attr)) return cadr(n->attr); + if (n && (c=attr_value(n,KONST))) { + return c; } return(list3(RLVAR+op,cadr(e),caddr(e))); case INDIRECT: @@ -4147,4 +4197,370 @@ return 0; } +static void +st_decl(int e1){ + NMTBL *n = (NTMBL *)caddr(e1); + int stmode = cadddr(e1); +} + + +static void +st_if(int e1){ + int l1,l2,slfree; + int e2=caddr(e1),e3; + // conv->if_(); + slfree=lfree; + checkret(); + l1 = bexpr(car(e2),0,fwdlabel()); + // conv->if_then_(); + checkret(); + g_expr_u(cadr(e2)); + if ((e3=caddr(e2))) { // else + // conv->if_else_(); + if ((l2 = control)) + gen_jmp(l2=fwdlabel()); + fwddef(l1); + g_expr_u(e3); + checkret(); + if (l2) fwddef(l2); + } else { + fwddef(l1); + } + // conv->if_endif_(); +} + + +static void +st_do(int e1){ + int sbreak,scontinue,l; + + sbreak=blabel; + scontinue=clabel; + blabel=fwdlabel(); + clabel=fwdlabel(); + control=1; + checkret(); + l=backdef(); + // conv->dowhile_(); + g_expr_u(cadddr(e1)); + checkret(); + // conv->dowhile_cond_(); + bexpr(caddr(e1),1,l); + // conv->dowhile_end_(); + fwddef(blabel); + clabel=scontinue; + blabel=sbreak; +} + + +static void +st_while(int e1){ + int sbreak,scontinue,e; + + sbreak=blabel; + scontinue=clabel; + blabel=fwdlabel(); + control=1; + checkret(); + clabel=backdef(); + // conv->while_(); + // conv->while_body_(); + if(!(e=cadddr(e1))) { + bexpr(caddr(e1),1,clabel); + // conv->sm_(); + } else { + bexpr(caddr(e1),0,blabel); + g_expr_u(e); + checkret(); + if(control) + gen_jmp(clabel); + } + // conv->while_end_(); + fwddef(blabel); + clabel=scontinue; + blabel=sbreak; +} + + +static void +st_for(int e1){ + int p0,p1,p2,body; + int l,e,dflag=0; + int sbreak=blabel; + int slimit = lfree_type_limit; + int scontinue=clabel; + + e = caddr(e1); + p0 = car(e); p1 = cadr(e); p2 = caddr(e); body = cadddr(e); + + blabel=fwdlabel(); + // conv->for_(); + if (p0) { + checkret(); + g_expr_u(p0); + } + // conv->for1_(); + control=1; + checkret(); + l=backdef(); + if (p1) { + bexpr(p1,0,blabel); + } + // conv->for2_(); + // conv->for_body_(); + if (!p2) { + clabel=l; + g_expr_u(body); + checkret(); + } else { + clabel=fwdlabel(); + g_expr_u(body); + checkret(); + fwddef(clabel); + g_expr_u(p2); + } + // conv->for_end_(); + gen_jmp(l); + fwddef(blabel); + clabel=scontinue; + blabel=sbreak; +} + + +static void +st_switch(int e1){ + int sbreak,scase,sdefault,slfree,svalue,slist; + + checkret(); + slist = cslist; + cslist = 0; + sbreak=blabel; /* save parents break label */ + blabel=fwdlabel(); + sdefault=dlabel; /* save parents default label */ + dlabel=0; + scase=cslabel; /* save parents next case label */ + // conv->switch_(); + slfree=lfree; + svalue=csvalue1; /* save parents switch value */ + gexpr(caddr(e1),1); + csvalue1=csvalue() ; + // conv->switch_body_(); + cslabel = control = 0; + g_expr_u(cadddr(e1)); + // conv->switch_end_(); + checkret(); +#if CASE_CODE + if (control) gen_jmp(blabel); + genswitch(cslist,cslabel); +#else + if(dlabel) def_label(cslabel,dlabel); + else fwddef(cslabel); +#endif + csvalue1=svalue; + cslabel=scase; + dlabel=sdefault; + fwddef(blabel); + blabel=sbreak; + cslist = slist; +} + + +static void +st_comp(int e1){ + g_expr_u(e1); +} + + +static void +st_break(int e1){ + checkret(); + // conv->break_(); + if (control) + gen_jmp(blabel); +} + + +static void +st_continue(int e1){ + checkret(); + // conv->continue_(); + if (control) gen_jmp(clabel); +} + + +static void +st_case(int e1){ +#if CASE_CODE + int l,clist=caddr(e1),c; + l = fwdlabel(); + // conv->case_begin_(0,0); + // conv->case_(0,0); + if (retpending) { + ret(); retpending=0; + } + if (!cslabel) { + if (!control) { + cmpdimm(car(clist),csvalue1,cslabel=fwdlabel(),1); + caddr(clist)=0; + } else { + error(-1); + } + } + while(clist) { + clist = cadr(c=clist); cadr(c) = 0; // insert destroy cadr of clist + cslist=insert_ascend(cslist,c,docase_eq); + } + fwddef(l); + control=1; +#else + /* casading branch implementation */ + int c,l; + c = caddr(e1); + if (retpending) { + ret(); retpending=0; + } + // conv->case_begin_(0,0); + // conv->case_(0,0); + l=fwdlabel(); + if (control) { + control=0; + gen_jmp(l); + } + if (cslabel) fwddef(cslabel); + while(cadr(c)) { + cmpdimm(car(c),csvalue1,l,0); + c=cadr(c); + } + cmpdimm(car(c),csvalue1,cslabel=fwdlabel(),1); + if (l) fwddef(l); +#endif +} + + +static void +st_default(int e1){ + control=1; + checkret(); + if (dlabel) error(STERR); // double default: + dlabel = backdef(); + // conv->case_(0,1); +} + + +static void +st_return(int e1){ + int e,e1; + + if (!cslabel) gen_jmp(cslabel = fwdlabel()); + if(!(e=caddr(e1))) { + // conv->return_(); + // conv->return_end_(); + retpending = 1; + return; + } + // conv->return_(); + if (struct_return) { + 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))); + replace_return_struct(cadr(e), + rvalue_t(car(struct_return),caddr(struct_return))); + gexpr(cadr(e),0); + } else { + type = caddr(struct_return); + // e1 = rvalue_t(cadr(struct_return),INT); /* size */ + e1 = cadr(struct_return); /* size */ + gexpr(list4(STASS,rvalue(car(struct_return)),e,e1),0); + } + } else { + error(TYERR); /* should check compatible */ + } + } else { + gexpr(correct_type(e,cadr(fnptr->ty)),1); + } + // conv->return_end_(); + retpending = 1; +} + + +static void +st_goto(int e){ + NMTBL *nptr0; + int t,e1,e2,env; + + checkret(); + // conv->goto_(); + e1 = caddr(e); + if (car(e1)==RINDIRECT) { + gen_indirect_goto(cadr(e1)); + return; + } else if (car(e1)!=CODE) { + nptr0 = (NMTBL *)cadr(e1); + t = nptr0->sc; + if (t==EMPTY||t==EXTRN1||t==EXTRN) { + // error check? + nptr0->sc=EMPTY; + nptr0=l_top_search(nptr0->nm,0); + nptr0->sc = FLABEL; + nptr0->dsp = fwdlabel(); + } else if (!(t==FLABEL||t==BLABEL)) { + error(STERR); + } + gen_jmp(nptr0->dsp); + control=0; + // conv->sm_(); + // conv->goto_label_(nptr0); + return; + } else { + /* CbC continuation */ + // conv->jump_(env); + e2 = cadr(e1); + env = caddr(e1); + if (car(e2) == FNAME) { + nptr0=(NMTBL *)cadr(e2); + if (nptr0->sc==EMPTY) + nptr0->sc = EXTRN1; + else if(nptr0->sc==FUNCTION) + nptr0->sc = CODE; + if (nptr0->ty>0&&car(nptr0->ty)==FUNCTION) + car(nptr0->ty)=CODE; + } + gexpr(list3(CODE,e1,env),0); + control=0; + // conv->sm_(); + return; + } +} + + +#if ASM_CODE +static void +st_asm(int e1){ + checkret(); + gexpr(list3(ASM,caddr(e1),cadddr(e1)),0); +} +#endif + + +static void +st_label(int e1){ + NMTBL *nptr = (NMTBL*)caddr(e1); + control=1; + checkret(); + if(nptr->sc == FLABEL) { + fwddef(nptr->dsp); + } else if(nptr->sc == BLABEL) { + nptr->dsp = backdef(); + } else error(TYERR); + // conv->label_(); +} + +static void +st_comment(int e1){ + gen_comment((char *)car(e1)); +} + /* end */
--- a/mc-codegen.h Mon Nov 29 04:15:38 2004 +0900 +++ b/mc-codegen.h Tue Nov 30 02:20:42 2004 +0900 @@ -89,6 +89,7 @@ extern int g_expr_u(int e1); extern int is_code(NMTBL *fnptr); extern int is_function(NMTBL *fnptr); +extern int is_inline(NMTBL *fnptr); extern int scalar(int t); extern int make_mask(int from,int to);
--- a/mc-h-renum.pl Mon Nov 29 04:15:38 2004 +0900 +++ b/mc-h-renum.pl Tue Nov 30 02:20:42 2004 +0900 @@ -16,6 +16,8 @@ elsif(m+/\* error number end \*/+) { $mode = 0; } elsif(m+/\* mode start \*/+) { $mode = 4; } elsif(m+/\* mode end \*/+) { $mode = 0; } + elsif(m+/\* statement start \*/+) { $mode = 5; } + elsif(m+/\* statement end \*/+) { $mode = 0; } else { if ($mode==0) { ; } elsif ($mode==1) { @@ -26,6 +28,8 @@ s/(\d+)/$error++/e; } elsif ($mode==4) { s/(\d+)/$modenum++/e; + } elsif ($mode==5) { + s/(\d+)/$tags++/e; } } print;
--- a/mc-parse.c Mon Nov 29 04:15:38 2004 +0900 +++ b/mc-parse.c Tue Nov 30 02:20:42 2004 +0900 @@ -6,6 +6,7 @@ #include "mc-codegen.h" #include "mc-switch.h" #include "mc-macro.h" +#include "mc-inline.h" #include "conv/conv.h" #define FILES 10 @@ -36,6 +37,7 @@ static NMTBL *free_nptr_list; static int current_scope; +int inline_funcs; char linebuf[LBUFSIZE]; char *chptr; @@ -313,7 +315,8 @@ (n==RGERR) ? "too many register usage (internal error)" : (n==REG_ERR) ? "illegal register var" : (n==INERR) ? "bad initialization" : - (n==CODE_ERR) ? "goto code is necessary" : + (n==CODE_ERR) ? "goto is necessary" : + (n==ILERR) ? "inline error" : "Bug of compiler"); errmsg(); exit(1); @@ -729,6 +732,9 @@ } else { conv->return_type_(type,n,sd); n = def(n,ctmode); + if (inmode) { + parse = list4(ST_DECL,parse,(int)n,stmode); + } if (sym==ASS && n!=&null_nptr) { decl_data(type,n,0,0); data_closing(n); } @@ -745,6 +751,9 @@ } conv->return_type_(type,n,1); def(n,ctmode); + if (inmode) { + parse = list4(ST_DECL,parse,(int)n,stmode); + } if (sym==ASS && n!=&null_nptr) { decl_data(type,n,0,0);data_closing(n); } @@ -1312,7 +1321,7 @@ /* duplicate initialization */ error(INERR); } else { - if (mode_save==GDECL && n->attr && car(n->attr)==KONST) { + if (mode_save==GDECL && has_attr(n,KONST)) { mode=GDECL; } } @@ -1540,6 +1549,7 @@ int t,arglist; if(!chk) gen_code_enter(n->nm); + if (inmode) error(ILERR); extrn_use(n); local_static_list = &null_nptr; fnptr=n; @@ -1623,14 +1633,18 @@ { int sd = stypedecl; int arglist; - if(!chk) gen_enter(n->nm); - extrn_use(n); + if (!inmode) { + if(!chk) gen_enter(n->nm); + extrn_use(n); + retlabel=fwdlabel(); + } else { + if (parse) error(-1); + } local_static_list = &null_nptr; fnptr=n; - retlabel=fwdlabel(); retcont = 0; - if (tmp_struct) { tmp_struct->sc = 0; tmp_struct->nm = 0; } - tmp_struct = 0; /* a = f().filed */ + // if (tmp_struct) { tmp_struct->sc = 0; tmp_struct->nm = 0; } // why? + tmp_struct = 0; /* a = f().field */ n->ty = type; fcheck(n); @@ -1639,7 +1653,7 @@ if (sym!=LC) { arglist = fnptr->dsp; fnptr->dsp =args=0; - while (sym!=LC) { /* argument declaration !ANSI */ + while (sym!=LC) { /* K&R sytle argument declaration */ stmode=0; decl(); getsym(0); } @@ -1651,7 +1665,8 @@ fnptr->dsp=reverse0(fnptr->dsp); fdecl_struct(fnptr->ty); /* insert extra argument for struct passing */ disp=0; - arg_register(fnptr); + if (!inmode) + arg_register(fnptr); typedefed=0; conv->function_(fnptr,sd); conv->lc_(); init_vars=0; @@ -1660,20 +1675,59 @@ local_decl(); control=1; cslabel = -1; - if(!chk) gen_enter1(); + if (!inmode && !chk) gen_enter1(); emit_init_vars(); lfree_type_limit = lfree; while(sym!=RC) statement(0); leave_scope(); conv->function_end_(); conv->rc_(); - if(!chk) gen_leave(control,n->nm); + if (inmode) { + set_attr(n,INLINE,reverse0(parse)); parse = 0; + inline_funcs = list2((int)n,inline_funcs); + } else { + if(!chk) gen_leave(control,n->nm); + } retpending = 0; control=0; arglist=0; lfree_type_limit = 0; } +/* generate function from parse tree */ + +extern void +pfdecl(NMTBL *n) +{ + int sd = stypedecl; + + if(!chk) gen_enter(n->nm); + extrn_use(n); + local_static_list = &null_nptr; + retlabel=fwdlabel(); + + fnptr=n; + retcont = 0; + tmp_struct = 0; + + arg_register(fnptr); + typedefed=0; + conv->function_(fnptr,sd); conv->lc_(); + init_vars=0; + + if(!chk) gen_enter1(); + + control=1; + cslabel = -1; + + g_expr_u(pexpr(attr_value(n,INLINE))); + conv->function_end_(); conv->rc_(); + if(!chk) gen_leave(control,n->nm); + + retpending = 0; + control=0; +} + /* basic C statement */ @@ -1709,7 +1763,13 @@ case BREAK: checkret(); conv->break_(); - if (control) gen_jmp(blabel); + if (control) { + if (inmode) { + parse = list2(ST_BREAK,parse); + } else { + gen_jmp(blabel); + } + } getsym(0); checksym(SM); return; @@ -1738,21 +1798,25 @@ return; #endif default: - checkret(); + if (!inmode) + checkret(); if(sym==IDENT&&skipspc()==':') { dolabel(); statement(use); } else { - if (use) { - lastexp = expr(0); - return; + if (inmode) { + parse = list3(ST_COMP,parse,expr(0)); } else { - slfree=lfree; - gexpr(expr(0),use); - set_lfree(slfree); - conv->sm_(); - checksym(SM); + if (use) { + lastexp = expr(0); + } else { + slfree=lfree; + gexpr(expr(0),use); + set_lfree(slfree); + } } + conv->sm_(); + checksym(SM); } } } @@ -1760,43 +1824,67 @@ static void doif(void) { - int l1,l2,slfree; + int l1,l2,slfree,pparse; getsym(0); checksym(LPAR); conv->if_(); slfree=lfree; - checkret(); - l1 = bexpr(expr(0),0,fwdlabel()); + if (inmode) { + pparse = parse; parse = 0; + l1 = expr(0); + } else { + checkret(); + l1 = bexpr(expr(0),0,fwdlabel()); + } set_lfree(slfree); conv->if_then_(); checksym(RPAR); statement(0); - checkret(); + if (inmode) { + l2 = reverse0(parse); parse = 0; + } else { + checkret(); + } if(sym==ELSE) { conv->if_else_(); - if ((l2 = control)) - gen_jmp(l2=fwdlabel()); - fwddef(l1); - getsym(0); - statement(0); - checkret(); - if (l2) fwddef(l2); + if (inmode) { + getsym(0); + statement(0); + parse = list3(ST_IF,pparse,list3(l1,l2,reverse0(parse))); + } else { + if ((l2 = control)) + gen_jmp(l2=fwdlabel()); + fwddef(l1); + getsym(0); + statement(0); + checkret(); + if (l2) fwddef(l2); + } + } else { + if (inmode) { + parse = list3(ST_IF,pparse,list3(l1,l2,0)); + } else { + fwddef(l1); + } } - else fwddef(l1); conv->if_endif_(); } static void dowhile(void) { - int sbreak,scontinue,slfree,e; + int sbreak,scontinue,slfree,e,pparse; sbreak=blabel; scontinue=clabel; - blabel=fwdlabel(); - control=1; - checkret(); - clabel=backdef(); + if (inmode) { + pparse = parse; parse=0; + } else { + blabel=fwdlabel(); + control=1; + checkret(); + clabel=backdef(); + } conv->while_(); getsym(0); checksym(LPAR); @@ -1805,20 +1893,31 @@ checksym(RPAR); conv->while_body_(); if(sym==SM) { - bexpr(e,1,clabel); + if (inmode) { + parse = list4(ST_WHILE,pparse,e,0); + } else { + bexpr(e,1,clabel); + } set_lfree(slfree); conv->sm_(); getsym(0); } else { - bexpr(e,0,blabel); + if (!inmode) { + bexpr(e,0,blabel); + } set_lfree(slfree); statement(0); - checkret(); - if(control) - gen_jmp(clabel); + if (inmode) { + parse = list4(ST_WHILE,pparse,e,reverse0(parse)); + } else { + checkret(); + if(control) + gen_jmp(clabel); + } } conv->while_end_(); - fwddef(blabel); + if (!inmode) + fwddef(blabel); clabel=scontinue; blabel=sbreak; } @@ -1826,30 +1925,43 @@ static void dodo(void) { - int sbreak,scontinue,l,slfree; + int sbreak,scontinue,l,slfree,pparse; sbreak=blabel; scontinue=clabel; - blabel=fwdlabel(); - clabel=fwdlabel(); - control=1; - checkret(); - l=backdef(); + if (inmode) { + parse = pparse; parse = 0; + } else { + blabel=fwdlabel(); + clabel=fwdlabel(); + control=1; + checkret(); + l=backdef(); + } conv->dowhile_(); getsym(0); statement(0); - checkret(); - fwddef(clabel); + if (inmode) { + l = reverse0(parse); parse =0; + } else { + checkret(); + fwddef(clabel); + } checksym(WHILE); checksym(LPAR); slfree=lfree; conv->dowhile_cond_(); - bexpr(expr(0),1,l); + if (inmode) { + parse = list4(ST_DO,pparse,expr(0),l); + } else { + bexpr(expr(0),1,l); + } set_lfree(slfree); checksym(RPAR); conv->dowhile_end_(); checksym(SM); - fwddef(blabel); + if (!inmode) + fwddef(blabel); clabel=scontinue; blabel=sbreak; } @@ -1857,6 +1969,7 @@ static void dofor(void) { + int pparse,p0,p1; int l,e,slfree,dflag=0; int sbreak=blabel; int slimit = lfree_type_limit; @@ -1864,7 +1977,11 @@ int scontinue=clabel; init_vars = 0; - blabel=fwdlabel(); + if (inmode) { + pparse = parse; parse=0; + } else { + blabel=fwdlabel(); + } conv->for_(); getsym(0); checksym(LPAR); @@ -1876,28 +1993,44 @@ lfree_type_limit = lfree; decl(); mode=STAT; - checkret(); + if (inmode) { + p0 = reverse0(parse); parse = 0; + } else { + checkret(); + } emit_init_vars(); getsym(0); } else if(sym!=SM) { - checkret(); - gexpr(expr(0),0); + if (inmode) { + p0 = expr(0); + } else { + checkret(); + gexpr(expr(0),0); + } checksym(SM); conv->for1_(); } else { + p0 = 0; conv->for1_(); getsym(0); } set_lfree(slfree); control=1; - checkret(); - l=backdef(); + if (!inmode) { + checkret(); + l=backdef(); + } if(sym!=SM) { - bexpr(expr(0),0,blabel); + if (inmode) { + p1 = expr(0); + } else { + bexpr(expr(0),0,blabel); + } checksym(SM); conv->for2_(); } else { conv->for2_(); + p1 = 0; getsym(0); } set_lfree(slfree); @@ -1906,23 +2039,33 @@ conv->for_body_(); getsym(0); statement(0); - checkret(); + if (inmode) { + e = 0; + } else { + checkret(); + } } else { clabel=fwdlabel(); e=expr(0); conv->for_body_(); checksym(RPAR); statement(0); - checkret(); - fwddef(clabel); - gexpr(e,0); + if (!inmode) { + checkret(); + fwddef(clabel); + gexpr(e,0); + } set_lfree(slfree); } lfree_type_limit = slimit ; if (dflag) leave_scope(); conv->for_end_(); - gen_jmp(l); - fwddef(blabel); + if (inmode) { + parse = list3(ST_FOR,pparse,list4(p0,p1,e,reverse0(parse))); + } else { + gen_jmp(l); + fwddef(blabel); + } clabel=scontinue; blabel=sbreak; init_vars=sinit_vars; @@ -1936,7 +2079,11 @@ { int slimit = lfree_type_limit ; int sinit_vars = init_vars; + int pparse = parse; conv->lc_(); + if (inmode) { + parse = 0; + } local_decl(); emit_init_vars(); lfree_type_limit = lfree; @@ -1945,6 +2092,9 @@ lfree_type_limit = slimit; init_vars = sinit_vars; leave_scope(); + if (inmode) { + parse = list3(ST_COMP,pparse,reverse0(parse)); + } getsym(0); } @@ -1956,12 +2106,18 @@ doswitch(void) { int sbreak,scase,sdefault,slfree,svalue,slist; - - checkret(); + int pparse = parse,v; + + if (inmode) { + parse = 0; + } else { + checkret(); + } slist = cslist; cslist = 0; sbreak=blabel; /* save parents break label */ - blabel=fwdlabel(); + if (!inmode) + blabel=fwdlabel(); sdefault=dlabel; /* save parents default label */ dlabel=0; scase=cslabel; /* save parents next case label */ @@ -1970,9 +2126,14 @@ checksym(LPAR); slfree=lfree; svalue=csvalue1; /* save parents switch value */ - gexpr(expr(0),1); + if (inmode) { + v = expr(0); + } else { + gexpr(expr(0),1); + } if (!scalar(type)) error(EXERR); - csvalue1=csvalue() ; + if (!inmode) + csvalue1=csvalue() ; set_lfree(slfree); checksym(RPAR); conv->switch_body_(); @@ -1992,18 +2153,23 @@ */ statement(0); conv->switch_end_(); - checkret(); + if (inmode) { + parse = list4(ST_SWITCH,pparse,v,reverse0(parse)); + } else { + checkret(); #if CASE_CODE - if (control) gen_jmp(blabel); - genswitch(cslist,cslabel); + if (control) gen_jmp(blabel); + genswitch(cslist,cslabel); #else - if(dlabel) def_label(cslabel,dlabel); - else fwddef(cslabel); + if(dlabel) def_label(cslabel,dlabel); + else fwddef(cslabel); #endif + } csvalue1=svalue; cslabel=scase; dlabel=sdefault; - fwddef(blabel); + if (!inmode) + fwddef(blabel); blabel=sbreak; cslist = slist; } @@ -2023,14 +2189,22 @@ { #if CASE_CODE int l,clist=0,c; - l = fwdlabel(); + if (!inmode) + l = fwdlabel(); while(sym==CASE) { conv->case_begin_(0,0); getsym(0); - clist=glist3(cexpr(expr(1)),clist,l); + if (inmode) + clist=list2(cexpr(expr(1)),clist); + else + clist=glist3(cexpr(expr(1)),clist,l); conv->case_(0,0); checksym(COLON); } + if (inmode) { + parse = list3(ST_CASE,parse,clist); + return; + } if (retpending) { ret(); retpending=0; } @@ -2064,8 +2238,10 @@ /* casading branch implementation */ int c,l,slfree; l = 0; - if (retpending) { - ret(); retpending=0; + if (!inmode) { + if (retpending) { + ret(); retpending=0; + } } slfree=lfree; c=0; @@ -2076,6 +2252,10 @@ conv->case_(c,0); checksym(COLON); } + if (inmode) { + parse = list3(ST_CASE,parse,clist); + return; + } l=fwdlabel(); if (control) { control=0; @@ -2096,11 +2276,16 @@ dodefault(void) { control=1; - checkret(); + if (!inmode) + checkret(); getsym(0); checksym(COLON); if (dlabel) error(STERR); // double default: - dlabel = backdef(); + if (inmode) { + parse = list2(ST_DEFAULT,parse); + } else { + dlabel = backdef(); + } conv->case_(0,1); } @@ -2109,39 +2294,45 @@ { int slfree,e,e1; - if (!cslabel) gen_jmp(cslabel = fwdlabel()); + if (!inmode && !cslabel) gen_jmp(cslabel = fwdlabel()); if(getsym(0)==SM) { // should check fnptr have no return value conv->return_(); conv->return_end_(); getsym(0); + if (inmode) + parse = list3(ST_RETURN,parse,0); retpending = 1; return; } conv->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) { - /* pass the return pointer to the called function */ - replace_return_struct(cadr(e), - rvalue_t(car(struct_return),caddr(struct_return))); - gexpr(cadr(e),0); + 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))); + gexpr(cadr(e),0); + } else { + type = caddr(struct_return); + // e1 = rvalue_t(cadr(struct_return),INT); /* size */ + e1 = cadr(struct_return); /* size */ + gexpr(list4(STASS,rvalue(car(struct_return)),e,e1),0); + } } else { - type = caddr(struct_return); - // e1 = rvalue_t(cadr(struct_return),INT); /* size */ - e1 = cadr(struct_return); /* size */ - gexpr(list4(STASS,rvalue(car(struct_return)),e,e1),0); + error(TYERR); /* should check compatible */ } } else { - error(TYERR); /* should check compatible */ + gexpr(correct_type(expr(0),cadr(fnptr->ty)),1); } + set_lfree(slfree); } else { - gexpr(correct_type(expr(0),cadr(fnptr->ty)),1); + parse = list3(ST_RETURN,parse,expr(0)); } - set_lfree(slfree); conv->return_end_(); checksym(SM); /* control = 0; still control continue until pending return emission */ @@ -2154,14 +2345,19 @@ NMTBL *nptr0; int t,e1,e2,env; - checkret(); + if (!inmode) + checkret(); conv->goto_(); getsym(0); e1 = expr(0); t=car(e1); if (type==VOID) { if (car(e1)==RINDIRECT) { - gen_indirect_goto(cadr(e1)); + if (inmode) { + parse = list3(ST_GOTO,parse,e1); + } else { + gen_indirect_goto(cadr(e1)); + } } else error(TYERR); checksym(SM); return; @@ -2170,11 +2366,17 @@ nptr0 = (NMTBL *)cadr(e1); t = nptr0->sc; if (t==EMPTY||t==EXTRN1||t==EXTRN) { + // error check? nptr0->sc=EMPTY; nptr0=l_top_search(nptr0->nm,0); nptr0->sc = FLABEL; - gen_jmp(nptr0->dsp = fwdlabel()); - } else if (t==FLABEL||t==BLABEL) { + nptr0->dsp = fwdlabel(); + } else if (!(t==FLABEL||t==BLABEL)) { + error(STERR); + } + if (inmode) { + parse = list3(ST_GOTO,parse,e1); + } else { gen_jmp(nptr0->dsp); } control=0; @@ -2203,7 +2405,11 @@ if (nptr0->ty>0&&car(nptr0->ty)==FUNCTION) car(nptr0->ty)=CODE; } - gexpr(list3(CODE,e1,env),0); + if (inmode) { + parse = list3(ST_GOTO,parse,list3(CODE,e1,env)); + } else { + gexpr(list3(CODE,e1,env),0); + } control=0; conv->sm_(); checksym(SM); @@ -2218,15 +2424,25 @@ { NMTBL *nptr1; control=1; - checkret(); - if(nptr->sc == FLABEL) - fwddef(nptr->dsp); - else if(nptr->sc != EMPTY && nptr->sc != EXTRN1) + if (!inmode) + checkret(); + if(nptr->sc == FLABEL) { + if (inmode) + parse = list3(ST_LABEL,parse,(int)nptr); + else + fwddef(nptr->dsp); + } else if(nptr->sc != EMPTY && nptr->sc != EXTRN1) error(TYERR); - nptr->sc=EMPTY; - nptr1=l_top_search(nptr->nm,0); - nptr1->sc = BLABEL; - nptr1->dsp = backdef(); + } else { + nptr->sc=EMPTY; + nptr1=l_top_search(nptr->nm,0); + nptr1->sc = BLABEL; + if (inmode) { + parse = list3(ST_LABEL,parse,(int)nptr1); + } else { + nptr1->dsp = backdef(); + } + } conv->label_(); getsym(0); checksym(COLON); @@ -2243,7 +2459,8 @@ int e1 = 0, asm0 = 0, input = 0, out = 0, opt = 0; int e; - checkret(); + if (!inmode) + checkret(); getsym(0); if (sym==VOLATILE) getsym(0); checksym(LPAR); @@ -2283,7 +2500,11 @@ } while(sym==COMMA); } checksym(RPAR); - gexpr(list3(ASM,list4(asm0,input,out,opt),e1),0); + if (inmode) { + parse = list4(ST_ASM,parse,list4(asm0,input,out,opt),e1); + } else { + gexpr(list3(ASM,list4(asm0,input,out,opt),e1),0); + } checksym(SM); } #endif @@ -2972,18 +3193,25 @@ // l2 is not defined and generates undefined error. // cntl may prevent this. int l,b,l2,cntl=control; - if (cntl) { - gen_jmp(l=fwdlabel()); - } else l = 0; - b = backdef(); - docomp(1); - if (cntl) { - gen_jmp(l2=fwdlabel()); - } else l2 = 0; - e1 = list3(COMMA,list3(LCALL,b,l2),lastexp); - lastexp = 0; - if (l) fwddef(l); - control=cntl; + if (inmode) { + int sparse = parse; parse = 0; + docomp(1); + e1 = list3(ST_COMP,0,parse); + parse = sparse; + } else { + if (cntl) { + gen_jmp(l=fwdlabel()); + } else l = 0; + b = backdef(); + docomp(1); + if (cntl) { + gen_jmp(l2=fwdlabel()); + } else l2 = 0; + e1 = list3(COMMA,list3(LCALL,b,l2),lastexp); + lastexp = 0; + if (l) fwddef(l); + control=cntl; + } } else { e1=expr0(); conv->rpar_(); @@ -3025,7 +3253,10 @@ getsym(0); } else break; } - if(car(e1)==FNAME) type=list2(POINTER,type); + if(car(e1)==FNAME) { + set_attr((NMTBL*)cadr(e1),FNAME,1); + type=list2(POINTER,type); + } return e1; } @@ -3079,7 +3310,8 @@ /* return type */ type = cadr(ftype); - if(type==CHAR) type=INT; + if(type==CHAR||type==SHORT) type=INT; + else if(type==UCHAR||type==USHORT) type=UNSIGNED; else if(car(type)==STRUCT||car(type)==UNION) { /* make temporary struct for return value */ /* but it is better to see we can reuse old one */ @@ -3105,6 +3337,14 @@ arglist = append3(arglist,list2(ADDRESS,e),list2(POINTER,type)); } + if (car(e1)==FNAME) { + if (is_inline((NMTBL *)cadr(e1))) { + if (inmode) + return list4(INLINE,e1,arglist,ftype); + else /* partial evaluation */ + return pexpr(list4(INLINE,e1,arglist,ftype)); + } + } return list4(FUNCTION,e1,arglist,ftype); } @@ -4070,13 +4310,17 @@ switch (mode) { case GDECL: case GSDECL: case GUDECL: case GTDECL: case MDECL: case ADECL: case LSDECL: case LUDECL: case GEDECL: - case INLINE: - e=gfree; - gfree+=n; + e=gfree; + gfree+=n; break; default: - lfree-=n; - e=lfree; + if (inmode) { + e=gfree; + gfree+=n; + } else { + lfree-=n; + e=lfree; + } } if(lfree<gfree) error(HPERR); return e; @@ -4247,6 +4491,53 @@ return p1; } +extern int +has_attr(NMTBL *n,int attr) +{ + int e; + if (!n) return 0; + e = n->attr; + for(;e;e=cadr(e)) { + if (car(e)==attr) return 1; + } + return 0; +} + +extern int +attr_value(NMTBL *n,int attr) +{ + int e; + if (!n) return 0; + e = n->attr; + for(;e;e=cadr(e)) { + if (car(e)==attr) return caddr(e); + } + return 0; +} + +extern void +set_attr(NMTBL *n,int attr,int value) +{ + int e; + if (!n) error(-1); + e = n->attr; + for(;e;e=cadr(e)) { + if (car(e)==attr) { + caddr(e) = value; + return; + } + } + switch (n->sc) { + case LVAR: + n->attr = list3(attr,n->attr,value); + break; + default: + n->attr = glist3(attr,n->attr,value); + break; + } + return; +} + extern void display_ntable(NMTBL *n, char *s) {
--- a/mc-parse.h Mon Nov 29 04:15:38 2004 +0900 +++ b/mc-parse.h Tue Nov 30 02:20:42 2004 +0900 @@ -27,6 +27,7 @@ extern int lastexp; /* last expression in statement expressoin */ extern int debug; /* debug flag */ extern int decl_str_init; /* partial structure initializer */ +extern int inline_funcs; /* inline function list */ extern int parse; /* parse tree */ @@ -110,6 +111,10 @@ extern void extern_define(char *s,int d,int type,int use); extern void set_lfree(int save); +extern int has_attr(NMTBL *n,int attr); +extern int attr_value(NMTBL *n,int attr); +extern void set_attr(NMTBL *n,int attr,int value); + #if LONGLONG_CODE extern int llist2(int e1, long long d1); #endif @@ -144,5 +149,6 @@ extern struct cheap * increment_cheap(struct cheap *cheap,char **save); extern void save_cheap(struct cheap *scheap,struct cheap *cheap); extern struct cheap * reset_cheap(struct cheap *scheap); +extern void pfdecl(NMTBL *nptr); /* end */
--- a/mc.h Mon Nov 29 04:15:38 2004 +0900 +++ b/mc.h Tue Nov 30 02:20:42 2004 +0900 @@ -386,6 +386,29 @@ /* tree node tags end */ +/* statement start */ + +#define ST_DECL 110 +#define ST_IF 111 +#define ST_DO 112 +#define ST_WHILE 113 +#define ST_FOR 114 +#define ST_SWITCH 115 +#define ST_COMP 116 +#define ST_BREAK 117 +#define ST_CONTINUE 118 +#define ST_CASE 119 +#define ST_DEFAULT 120 +#define ST_RETURN 121 +#define ST_GOTO 122 +#define ST_ASM 123 +#define ST_LABEL 124 +#define ST_COMMENT 125 + +#define IS_STATEMENT(i) (ST_DECL<=i&&i<=ST_COMMENT) + +/* statement end */ + /* error number start */ #define FILERR 1 @@ -416,6 +439,7 @@ #define NMERR 26 #define MMERR 27 #define INERR 28 +#define ILERR 29 /* error number end */