Mercurial > hg > CbC > old > device
changeset 48:8575ec496cd4
jump with overrupped struct (first code)
author | kono |
---|---|
date | Sun, 16 Feb 2003 01:01:06 +0900 |
parents | f6b5e4f1a962 |
children | 884c74e6a2f7 |
files | mc-nop-386.c mc-parse.c |
diffstat | 2 files changed, 199 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-nop-386.c Sat Feb 15 18:19:27 2003 +0900 +++ b/mc-nop-386.c Sun Feb 16 01:01:06 2003 +0900 @@ -1012,6 +1012,180 @@ regv[creg]=1; } +/* goto arguments list */ +/* target list3(list2(tag,disp),cdr,ty) */ +/* source list4(tag,cdr,expr,ty) */ + +void +disp_source(int e3) { + printf("# jump arg list\n"); + for (e3 = target; e3; e3 = cadr(e3)) { + printf("# %d, expr %d, size %d\n",car(e3),caddr(e3),cadddr(e3)); + } +} + +int +overrap(int t,int source) +{ + int s0,s1; + int t0=cadr(car(t)); + int t1=size(caddr(t)); + for(;source;source=cadr(source)) { + s0=cadr(caddr(source)); + if(car(source)==REGISTER && car(car(t))==REGISTER) { + if(s0==t0) return 1; + } else if(car(source)==car(car(t))) { + s1=s0+size(cadddr(source)); + if((t0<=s0&&s0<=t1)||(t0<=s1&&s1<=t1)) return 1; + } + } + return 0; +} + +int +target_frame(int *source,int *target,int *processing) +{ + int t,s,e1; + while(*target) { + t=car(*target); + s=caddr(*source); + for(p=*processing;p;p=cadr(p)) { + if(car(p)==t) { /*ターゲットが処理リスト中にある*/ + remove(target,t); remove(source,s); remove(processing,p); + /*新しいレジスタ(or スタック)を取得する*/ + sz=size(ty=caddr(t)); + if (sz==size_of_int && (e1=get_register())!=-1)) { + e1=list2(REGISTER,e1); + g_expr(assign_expr(e1,car(s),ty,ty)); + return assign_expr(car(t),e1,ty,ty); + } else { + disp+=sz; + gen_jump_assign(car(s),disp,ty); + return assign_expr(car(t),list2(LVAR,disp),ty,ty); + } + } + } + if(car(t)==car(s) && cadr(t)==cadr(s)) { + /*書き込み先が自分自身*/ + remove(target,t); remove(source,s); + } else if (overrap(t,source,caddr(t))) { + /*書き込み先がソースと重なっている*/ + *prcoessing=list2(t,*processing); + remove(target,t); remove(source,s); + /*他のを先にする*/ + e1=target(source,target,processing); + /* これで空いたはず*/ + g_expr(assign_expr(car(t),car(s),ty,ty)); + /* 横によけたものがあれば、後始末をする*/ + if(e1) + g_expr(e1); + } else { + g_expr(assign_expr(car(t),car(s),ty,ty)); + remove(target,t); remove(source,s); + } + } + return 0; +} + +void +gen_jump_assign(int e3,int disp,int ty) +{ + int stype,e2,e4; + e2=caddr(e3); + stype = type; + g_expr(assgin_expr((e4=list2(LVAR,disp)),e2,ty,ty)); + type = stype; + heap[e3]=LVAR; heap[e3+2]=e4; +} + +void +remove(int *parent,int e) { + int list; + while (list=*parent) { + if (car(list)==e) { + *parent= cadr(list); + } else { + parent=&cadr(list); + } + } +} + +void +jump(int e1, int env) +{ + int e2,e3,sz,arg_size,ejmp,ty; + NMTBL *code0; + int target = 0; + int source = 0; + int processing = 0; + + /* まず、サイズを計算しながら、決まった形に落す。 */ + arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR; + for (e3 = caddr(e1); e3; e3 = cadr(e3)) { + e2 = car(e3); sz = size(ty=caddr(e3)); arg_size += sz; + if (regs <= max_regs&&integral(ty)) { + target=list3(list2(REGISTER,(regs++)+REG_ESI),target,ty); + } else { + target=list3(list2(LVAR,arg_size-MAX_RGISTER_VAR),target,ty); + } + switch (car(e2)) { + case CONST: source = list4(CONST,source,e2,ty); break; + case LVAR: source = list4(LVAR,source,e2,ty); break; + case REGISTER: source = list4(REGISTER,source,e2,ty); break; + case GVAR: source = list4(GVAR,source,e2,ty); break; + default: source = list4(0,source,e2,ty); break; + } + disp_source(source); + + arg_size = arg_size-MAX_RGISTER_VAR*size_of_int; + /* disp を飛び先似合わせて修正 */ + if (arg_size>disp) disp = arg_size; + + /* 複雑な式を前もって計算しておく */ + /* 必要なら局所変数を用いる。 */ + /* 局所変数へのオフセットを覚えておく */ + /* ついでに、同じものがあれば、除く */ + + for (e3 = source,e2 = target; e3; e3 = cadr(e3),e2 = cadr(e2)) { + if (car(e3)==0) { + disp+=size(ty=cadddr(e3)); + gen_jump_assign(e3,disp,ty); + } else if (car(e3)==car(e2)&&cadr(e3)==cadr(e2)) { + remove(&source,e3);remove(&target,e2); + } + } + + /* compute jump address */ + e2 = cadr(e1); + if (car(e2) == FNAME) { + code0=(NMTBL *)cadr(e2); + if (code0->sc!=CODE) { + error(TYERR); return; + } + } else { /* indirect */ + g_expr(e2); + emit_push(); + } + + /* 並列代入を実行 */ + + target_frame(&source,&target,&processing); + + if (!env && arg_size>disp) { + /* shrink stack if necessary */ + printf("\tleal %d(%%ebp),%%esp\n",arg_size); + } + if (car(e2) == FNAME) { + printf("\tjmp %s\n",code0->nm); + } else { + e2 = emit_pop(0); + printf("\tjmp *%s\n",register_name(e2,0)); + emit_pop_free(e2); + } + free_all_register(); +} + +#if 0 int arg_size(int e3,int *nargs0) { @@ -1038,50 +1212,11 @@ { int e2 = car(e1); return ( - e2==FNAME || e2==LVAR || e2==CRLVAR || e2==REGISTER + e2==CONST || e2==FNAME || e2==LVAR || e2==CRLVAR || e2==REGISTER ); } void -jump_new(int e1, int env) -{ - int e2; - NMTBL *code0; -/* - jump アドレスを計算する - */ - /* compute jump address */ - e2 = cadr(e1); - if (car(e2) == FNAME) { - code0=(NMTBL *)cadr(e2); - if (code0->sc!=CODE) { - error(STERR); return; - } - } else { /* indirect */ - g_expr(e2); - emit_push(); - } -/* - まず、複雑な式を前もって単純な式に落す。 - 必要なら局所変数を用いる。 - 局所変数へのオフセットを覚えておく - */ -/* - スタックの位置を修正する - */ -/* - オフセットを用いて、 - 並べ変えを行う - */ -/* - スタックの位置を修正する - */ -/* - jump code を生成する - */ -} - -void jump(int e1, int env) { int i,args,e2,e3,e4,e5,nargs,regs; @@ -1208,7 +1343,7 @@ } fnptr->sc = scode; } - +#endif void machinop(int e1)
--- a/mc-parse.c Sat Feb 15 18:19:27 2003 +0900 +++ b/mc-parse.c Sun Feb 16 01:01:06 2003 +0900 @@ -127,6 +127,7 @@ extern void code_leave(char *name,int disp) ; extern void code_enter1(int disp0,int args); extern int csvalue(); +extern int assign_expr(int e1,int e2,int t,int type); extern void emit_data_closing(NMTBL *n); extern void emit_data(int e, int t, NMTBL *n); @@ -1512,6 +1513,27 @@ } int +assign_expr(int e1,int e2,int t,int type) { + if(t==VOID) + error(TYERR); + 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); + return cadr(e2); + } else { + return (list4(SASS,e1,e2,size(t))); + } + } else { + type=t; + return(list3(ASS,e1,e2)); + } +} + +int expr(void) { return(rvalue(expr0())); @@ -1540,22 +1562,7 @@ t=type; getsym(); e2=rvalue(expr1()); - if(t==VOID) - error(TYERR); - 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); - return cadr(e2); - } else { - return(list4(SASS,e1,e2,size(t))); - } - } - type=t; - return(list3(ASS,e1,e2)); + return assign_expr(e1,e2,t,type); case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS: case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS: op = sym-AS;