Mercurial > hg > CbC > old > device
changeset 39:c63c4fdeb9a7
struct done.
author | kono |
---|---|
date | Tue, 11 Feb 2003 22:36:51 +0900 |
parents | d48d952da354 |
children | 060d1e549fec |
files | .gdbinit Idea mc-nop-386.c mc-parse.c test/tmp7.c |
diffstat | 5 files changed, 100 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Tue Feb 11 11:26:51 2003 +0900 +++ b/.gdbinit Tue Feb 11 22:36:51 2003 +0900 @@ -1,6 +1,4 @@ tb main -# b error -# b errmsg define regs call fprintf(stderr,"eax=%08x ebx=%08x ecx=%08x edx=%08x\nesi=%08x edi=%08x ebp=%08x esp=%08x eip=%08x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp,$eip) end @@ -13,4 +11,6 @@ nexti x/1i $eip end +b error +b errmsg r -s test/tmp7.c
--- a/Idea Tue Feb 11 11:26:51 2003 +0900 +++ b/Idea Tue Feb 11 22:36:51 2003 +0900 @@ -1458,3 +1458,20 @@ 結局、list base のinterpreter を実装しました。きちゃないが。 前の方法でも、頑張ればできるんでしょうけどね。 +Tue Feb 11 13:50:03 JST 2003 + +struct copy だけど... 関数がstructを返すときに、引数に前もって +積んでおくのでは、そこに値がコピーされてしまうし、あとで、 +スタックをたたんで置くときにきまずい。 + +function call の時に、引数の型のチェックをしてない + +type に -1 とheapの引数が混在しているやつだけど.. +やっぱまずいんじゃないか? + +temproal struct は再利用できるんだけど、dispの変更ができないので +新しく作るしかない。大きいときだけ新しく作るなんていうセコイ +技はあるけど。 + +register を使用しているかだけじゃなくて、実際にcreg/dregに +値があるかどうかを記憶する必要がある。
--- a/mc-nop-386.c Tue Feb 11 11:26:51 2003 +0900 +++ b/mc-nop-386.c Tue Feb 11 22:36:51 2003 +0900 @@ -746,7 +746,8 @@ void emit_copy(int from,int to,int length,int offset) { - if (length<0) return; + int fix = 0; + if (length<=0) return; switch (length) { case 0: break; case 1: @@ -769,17 +770,24 @@ emit_copy(from,to,2,offset); if(length>0) emit_copy(from,to,length,offset); - return; + break; } - use_register(from,REG_EDI,1); - use_register(to, REG_ESI,1); - use_register(dreg,REG_ECX,1); + use_register(from,REG_ESI,1); + use_register(to, REG_EDI,1); + use_register(dreg,REG_ECX,0); printf("\tmovl $%d,%%ecx\n",length/4); + fix = (length/4)*4; printf("\tcld\n\trep\n\tmovsl\n"); if(length%4) { emit_copy(from,to,length,offset+length/4); } } + /* this code is necessary for the value of assignment or function call */ + /* otherwise we don't need this */ + if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0)); + if(creg!=to) { + free_register(creg); creg=to; + } } int @@ -1114,7 +1122,7 @@ /* structure assignment */ e2 = cadr(e1); /* pointer variable to the struct */ e3 = cadr(e2); /* offset of the variable (distination) */ - e4 = caddr(e1); /* rright value (source) */ + e4 = caddr(e1); /* right value (source) */ sz = cadddr(e1); /* size of struct or union */ g_expr(e4); emit_push();
--- a/mc-parse.c Tue Feb 11 11:26:51 2003 +0900 +++ b/mc-parse.c Tue Feb 11 22:36:51 2003 +0900 @@ -92,6 +92,7 @@ static int macro_eval(int macrop,char *body,int history); static char * append(int lists); static NMTBL *free_nptr(); +static void replace_return_struct(int func,int left); extern void display_ntable(NMTBL *n, char *s); extern void closing(void); @@ -738,33 +739,33 @@ if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR) { if (type!=CHAR && !scalar(type)) error(TYERR); - nptr->sc = REGISTER; + n->sc = REGISTER; reg_var++; - if (nptr->dsp==0) { - if ((nptr->dsp = get_register_var())<0) { + if (n->dsp==0) { + if ((n->dsp = get_register_var())<0) { error(-1); } } return n; } - nptr->sc = LVAR; + n->sc = LVAR; if(type==CHAR) { - /* nptr->ty=INT; */ - if (nptr->dsp==0) { - nptr->dsp = args; + /* n->ty=INT; */ + if (n->dsp==0) { + n->dsp = args; if (endian) n->dsp += size_of_int-1; } args += size_of_int; } else { - if (nptr->dsp==0) - nptr->dsp = args; + if (n->dsp==0) + n->dsp = args; args += sz; } if(type==VOID) { } else if (!scalar(type)) { if((t=car(type))==STRUCT || t==UNION) { - nptr->ty = type; + n->ty = type; } else error(TYERR); } @@ -1032,13 +1033,18 @@ stmode=0; decl(); getsym(); } - if (((t=car(fnptr->ty))==STRUCT||t==UNION)) { + t=car(fnptr->ty); + if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) { /* this extra dummy arguments are set at calling sequence */ - str_ret.nm = "str_ret"; - type = t; - def(&str_ret); - if ((t=size(type))==-1) error(TYERR); - else struct_return = list2(list2(LVAR,str_ret.dsp),size(type)); + 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; } @@ -1073,7 +1079,7 @@ error(DCERR); else { n->sc=FUNCTION; - n->ty=glist2(cadr(type),0); + n->ty=glist2(cadr(type),0); /* arglist? */ } } } @@ -1386,7 +1392,7 @@ void doreturn(void) { - int slfree,e; + int slfree,e,e1; if(getsym()==SM) { getsym(); @@ -1398,19 +1404,28 @@ e = expr(); if ((car(type)==STRUCT || car(type)==UNION)&& size(type)==cadr(struct_return)) { - e = list4(SASS,car(struct_return),rvalue(e),size(type)); - gexpr(e); + e = rvalue(e); + type = caddr(struct_return); + e1 = rvalue(cadr(struct_return)); + gexpr(list4(SASS,rvalue(car(struct_return)),e,e1)); } else { - error(TYERR); + error(TYERR); /* should check compatible */ } } else { gexpr(expr()); } lfree=slfree; checksym(SM); + /* control = 0; still control continue until pending return emittion */ retpending = 1; } +void +replace_return_struct(int func,int left) { + int e = caddr(func); /* arg lists */ + e = car(e); /* return_struct arg */ + rplacad(e,left); +} void dogoto(void) @@ -1503,7 +1518,13 @@ if(t==CHAR) { type= INT;return(list3(CASS,e1,e2)); } else if(!scalar(t)&&(car(t)==STRUCT||car(t)==UNION)) { - type= t;return(list4(SASS,e1,e2,size(t))); + 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)); @@ -2132,6 +2153,8 @@ { int t,arglist,e; + /* function call */ + t=type; if(integral(t)|| (car(t)!=FUNCTION && car(t)!=CODE)) error(TYERR); @@ -2144,15 +2167,17 @@ getsym(); } checksym(RPAR); - if(car(t)!=CODE) { - t=cadr(t); - if(t==CHAR) type= INT; - else if(car(t)==STRUCT||car(t)==UNION) { - type = t; - e = list2(LVAR,def(0)->dsp); - arglist=list3(e,arglist,type); - return list3(COMMA,list3(FUNCTION,e1,arglist),rvalue(e)); - } else type=t; + if(car(t)==CODE) + return list3(FUNCTION,e1,arglist); + type=cadr(t); + if(type==CHAR) type=INT; + else if(car(type)==STRUCT||car(type)==UNION) { + /* make temporaly struct for return value */ + e = list2(LVAR,def(0)->dsp); + /* pass the pointer as an argument */ + /* this is recognized by called function declaration */ + arglist=list3(list2(ADDRESS,e),arglist,list2(POINTER,type)); + /* return list3(COMMA,list3(FUNCTION,e1,arglist),rvalue(e)); */ } return list3(FUNCTION,e1,arglist); }
--- a/test/tmp7.c Tue Feb 11 11:26:51 2003 +0900 +++ b/test/tmp7.c Tue Feb 11 22:36:51 2003 +0900 @@ -12,7 +12,10 @@ struct aa main0() { + int i; struct aa ccc; + + for(i=0;i<100;i++) ccc.a[i]=i; ccc.a[55]=123; return ccc; } @@ -50,11 +53,19 @@ register char *p; int j = 3; struct { int b; void (*c)(struct aa); } q = {3,main1},r; + struct aa *aap[3]; j = 3; bbb = main0(); + printf("copied main0 ccc.a[55] %d==123\n",bbb.a[55]); + aap[2] = &bbb; + *aap[2] = main0(); + printf("complex copied main0 ccc.a[55] %d==123\n",bbb.a[55]); + bbb.a[55]=0; j = main0().a[55]; + printf("new main0 ccc.a[55] in temporal copy %d==123\n",j); + printf("%d==3\n",q.b); /* 3==3 */ r = q;