Mercurial > hg > CbC > old > device
changeset 46:b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
calling sequence.
author | kono |
---|---|
date | Sat, 15 Feb 2003 17:54:30 +0900 |
parents | b9266c88495c |
children | f6b5e4f1a962 |
files | Idea mc-nop-386.c mc-parse.c test/tmp11.c test/tmp7.c |
diffstat | 5 files changed, 158 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/Idea Thu Feb 13 22:14:21 2003 +0900 +++ b/Idea Sat Feb 15 17:54:30 2003 +0900 @@ -1506,3 +1506,22 @@ int number; } virtual/real は、どうする。 + +Sat Feb 15 14:00:03 JST 2003 + +fdecl_struct を構文的に引数が出現するときに行うと、int *f(int +a) などで、* の評価が終る前に、int aが評価されしまう。*obj +のobj を評価し終らないとfのタイプが確定しない。int*f()[] み +たいな場合があるから。(?) なので、gcc と、そろえるためには、 +arg の先頭で fdecl_struct を行う方法ではだめで、fdecl 中であ +とから修正する方が良い。 + +fix しようにも引数リストなんて、存在しないじゃん! + +varargs を実装するのはめんどくさかろう... + +rvalue(expr(),type) では、expr() のtypeをrvalueに引き渡せな +い。でも、type を大域変数にすると、rvalueを異なるタイプで呼 +び出すときにtypeを変更する必要がある。このrvalueのtype の扱 +いは、かなりはまったことがあるので、rvalue(int e,int type)の +方が良いことは確かなんだが...
--- a/mc-nop-386.c Thu Feb 13 22:14:21 2003 +0900 +++ b/mc-nop-386.c Sat Feb 15 17:54:30 2003 +0900 @@ -913,22 +913,30 @@ if (register_full()) { /* this is wrong assumption */ save = 1; - for(lreg=0;lreg!=creg&&lreg!=dreg;lreg++); + for(lreg=0;lreg==creg||lreg==dreg;lreg++); printf("\tpushl %s\n",register_name(lreg,0)); - xreg = lreg; + xreg = lreg; regv[xreg]=0; } else { save=0; xreg = get_register(); } - printf("\tmovl %%esp,%s\n",register_name(xreg,0)); + if (save) + printf("\tlea %d(%%esp),%s\n",size_of_int,register_name(xreg,0)); + else + printf("\tmovl %%esp,%s\n",register_name(xreg,0)); regv[xreg]=1; emit_copy(creg,xreg,length,0); - /* we have value in creg */ + /* we have value in creg, it may be changed */ if (save) { - printf("\tpopl %s\n",register_name(lreg,0)); + if(creg==xreg) { + creg = get_register(); /* creg is freed in emit_copy */ + printf("\tmovl %s,%s\n",register_name(xreg,0),register_name(creg,0)); + regv[creg]=1; + } + printf("\tpopl %s\n",register_name(xreg,0)); + regv[xreg]=1; } else free_register(xreg); - regv[xreg]=0; return length/size_of_int; }
--- a/mc-parse.c Thu Feb 13 22:14:21 2003 +0900 +++ b/mc-parse.c Sat Feb 15 17:54:30 2003 +0900 @@ -75,6 +75,7 @@ static void reverse(int t1); int reverse0(int t1); static int rvalue(int e); +static int rvalue_t(int e,int type); int scalar(int t); static int sdecl(int s); static int skipspc(void); @@ -90,9 +91,11 @@ static void local_define(); static void local_undef(); static int macro_eval(int macrop,char *body,int history); -static char * append(int lists); +static char * mappend(int lists); static NMTBL *free_nptr(); static void replace_return_struct(int func,int left); +static void fdecl_struct(int type); +static int append3(int p,int a1,int a2); extern void display_ntable(NMTBL *n, char *s); extern void closing(void); @@ -131,6 +134,7 @@ extern void exit(int l); static int struct_return = 0; +static int arglist = 0; int main(int argc, char **argv) @@ -572,26 +576,13 @@ reg_var=0; n->dsp=0; smode = mode; - /* if(mode!=GDECL && mode!=ADECL) - error(DCERR); */ mode=ADECL; - args= 0; + args = 0; + arglist = 0; for(;;) { if(sym==IDENT && nptr->sc!=TYPE) { rplacad(n->ty,glist2(INT,cadr(n->ty))); - if (stmode==REGISTER && reg_var < MAX_REGISTER_VAR) { - nptr->ty = INT; - nptr->sc = REGISTER; - if ((nptr->dsp = get_register_var())<0) - error(-1); - use_register_var(nptr->dsp); /* it has now value in it */ - reg_var++; - } else { - nptr->ty = INT; - nptr->sc = LVAR; - nptr->dsp = args ; - args += size_of_int; - } + def(nptr); getsym(); if(sym==RPAR) break; } else { @@ -739,6 +730,7 @@ nsc = TYPE; break; case ADECL: + arglist = list2((int)n,arglist); if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR) { if (type!=CHAR && !scalar(type)) error(TYERR); @@ -748,7 +740,7 @@ if ((n->dsp = get_register_var())<0) { error(-1); } - use_register_var(nptr->dsp); /* it has now value in it */ + use_register_var(n->dsp); /* it has now value in it */ } return n; } @@ -988,9 +980,9 @@ code_enter(n->nm); fnptr=n; disp = -args; - args = 0; reg_var=0; mode=ADECL; + args = 0; stmode=REGISTER; while (sym!=LC) { /* argument declaration !ANSI */ decl(); getsym(); @@ -1023,9 +1015,6 @@ void fdecl(NMTBL *n) { - NMTBL str_ret; - int t; - enter(n->nm); fnptr=n; retlabel=fwdlabel(); @@ -1035,28 +1024,12 @@ reg_var=0; fcheck(n); mode=ADECL; - if (sym!=LC) args=0; + if (sym!=LC) { args=0; arglist = 0; } while (sym!=LC) { /* argument declaration !ANSI */ stmode=0; decl(); getsym(); } - t=car(fnptr->ty); - if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) { - /* extra argument for struct return */ - /* this extra dummy arguments are set at calling sequence */ - 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; - } - args=0; + fdecl_struct(fnptr->ty); disp=0; init_vars=0; /* local variable declaration */ @@ -1078,6 +1051,44 @@ control=0; } +static NMTBL str_ret; + +void +fdecl_struct(int fntype) +{ + int type_save,mode_save,t,sz; + NMTBL *n; + + t = car(fntype); + if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) { + mode_save = mode; + mode=ADECL; + type_save = type; + /* extra argument for struct return */ + /* this extra dummy arguments are set at calling sequence */ + str_ret.nm = "str_ret"; str_ret.sc = EMPTY; + str_ret.dsp = 0; str_ret.ty = 0; + type=list2(POINTER,t); + /* fix all arguments's offset */ + sz = size(type); + for(t=arglist;t;t=cadr(t)) { + n=(NMTBL *)car(t); + n->dsp += sz; + } + arglist = reverse0(arglist); + if ((t=size(car(fntype)))==-1) error(TYERR); + else { + args = 0; + def(&str_ret); + struct_return = list3(list2(LVAR,str_ret.dsp),t,type); + } + type = type_save; + mode = mode_save; + } else { + struct_return = 0; + } +} + void fcheck(NMTBL *n) { @@ -1413,10 +1424,16 @@ e = expr(); if ((car(type)==STRUCT || car(type)==UNION)&& size(type)==cadr(struct_return)) { - e = rvalue(e); - type = caddr(struct_return); - e1 = rvalue(cadr(struct_return)); - gexpr(list4(SASS,rvalue(car(struct_return)),e,e1)); + if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) { + replace_return_struct(cadr(e), + rvalue_t(car(struct_return),caddr(struct_return))); + gexpr(cadr(e)); + } else { + e = rvalue(e); + type = caddr(struct_return); + e1 = rvalue_t(cadr(struct_return),INT); /* size */ + gexpr(list4(SASS,rvalue(car(struct_return)),e,e1)); + } } else { error(TYERR); /* should check compatible */ } @@ -1431,8 +1448,9 @@ void replace_return_struct(int func,int left) { - int e = caddr(func); /* arg lists */ - e = car(e); /* return_struct arg */ + int e = caddr(func); /* arg lists */ + while(cadr(e)) e=cadr(e); /* find first arg */ + e = car(e); /* return_struct arg */ rplacad(e,left); } @@ -1527,6 +1545,7 @@ 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); @@ -2003,6 +2022,16 @@ } } +int +rvalue_t(int e,int t) +{ + int stype = type; + type = t; + e = rvalue(e); + type = stype; + return e; +} + void lcheck(int e) { @@ -2213,7 +2242,7 @@ /* this is recognized by called function declaration */ /* but I don't know this sequece is compatible with gcc */ - arglist=list3(list2(ADDRESS,e),arglist,list2(POINTER,type)); + append3(arglist,list2(ADDRESS,e),list2(POINTER,type)); } return list3(FUNCTION,e1,arglist); } @@ -2334,7 +2363,7 @@ macrop=macro_eval(macrop,(char *)car(nptrm->dsp),0); } macropp = macro_buf; - append(reverse0(macrop)); + mappend(reverse0(macrop)); macropp[-1] ='\n'; *macropp =0; lfree = slfree; @@ -3002,7 +3031,7 @@ } evalues = reverse0(evalues); while(args) { - local_define((char *)car(args),append(reverse0(car(evalues)))); + local_define((char *)car(args),mappend(reverse0(car(evalues)))); /* fprintf(stderr,"%s: %s => %s\n",nptr->nm,(char *)car(args),(char *)car(msearch0((char *)car(args))->dsp)); */ args = cadr(args); evalues = cadr(evalues); @@ -3175,8 +3204,19 @@ return e; } +int +append3(int p,int a1,int a2) +{ + int p1; + if(!p) return list3(a1,0,a2); + p1=p; + while(cadr(p)) p = cadr(p); + rplacad(p,list3(a1,0,a2)); + return p1; +} + char * -append(int lists) +mappend(int lists) { char *p; char *result = macropp;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tmp11.c Sat Feb 15 17:54:30 2003 +0900 @@ -0,0 +1,34 @@ +typedef struct nametable { + char *nm; + int sc,ty,dsp; } NMTBL; +NMTBL *a; + +NMTBL * +test2(char *n) { + printf("s %s\n",n); + return a; +} + +int +test0(int a,int b,int c) { + printf("a %d b %d c %d\n",a,b,c); + return 4; +} + +int +test1(a,b,c) +int a,b;int c; +{ + return test0(a,b,c); +} + +int +main() +{ + int d; + NMTBL *b; + b = test2("test"); + d = test1(1,2,3); + printf("return %d\n",d); + return d; +}
--- a/test/tmp7.c Thu Feb 13 22:14:21 2003 +0900 +++ b/test/tmp7.c Sat Feb 15 17:54:30 2003 +0900 @@ -79,7 +79,7 @@ j = main3(bbb).a[55]; printf("main3 bbb.a[55] in temporal copy %d==2 %d\n",j,bbb.a[53]); j = main3(bbb).a[53]; - printf("main3 bbb.a[55] in temporal copy %d==2 %d\n",j,bbb.a[53]); + printf("main3 bbb.a[55] in temporal copy %d==53 %d\n",j,bbb.a[53]); printf("%d==3\n",q.b); /* 3==3 */