Mercurial > hg > CbC > old > device
changeset 345:2b3946ee4fc9 nametbl-before
*** empty log message ***
author | kono |
---|---|
date | Sun, 27 Jun 2004 20:31:46 +0900 |
parents | b7f07df0c0f8 |
children | 969089695850 |
files | Changes mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c |
diffstat | 6 files changed, 174 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Jun 27 14:56:21 2004 +0900 +++ b/Changes Sun Jun 27 20:31:46 2004 +0900 @@ -5229,3 +5229,46 @@ そういえば、double register pair のparallel assignmentって やってる? + +うーん、やっぱり、codegen が register pair を知ることが出来 +るように、list2(LREGISTER,high,low) みたいな形にしたいよね。 +なんで、だめなんだったっけ? + list2(DREGISTER,list2(REGISTER2,high,low)) + list2(LREGISTER,list2(REGISTER2,high,low)) + list2(FREGISTER,list2(REGISTER,high)) +とか? + list3(REGISTER,1,reg); + list3(DREGISTER,2,reg,reg); + list3(FREGISTER,1,reg); +かな。 + +いいんだけど、変更多くない? でも、use_reg とかの複雑さを考えると、 +そうした方がいいんじゃないかなぁ。 + +でも、変更多いよね。利点としては、regs[] を lregster 分取らなくて +すむことかな。でも、本当に簡単になるのかな? + +code_*() でレジスタを使っている部分を修正する必要があるから、 +かなり大きな変更になるのか。でも、code_*() に引き渡す変数と +構文木中の要素が同じになるのは重要だよね。 + +構文木でのレジスタ変数のユニークさを維持しないと、 + if(r!=reg) + printf("\tmr %s,%s\n",register_name(reg),register_name(r)); + return; +みたいなのが困るね。ということは reverse poiner がいるってこ +とか。 + +overlap を見るときに、自分自身が overlap していても問題ない。 +ただし、重ならないようにコピーしないとだめ。そうしないと、 +巨大な構造体を二回コピーするはめになる。 + + |---||--------------| + + |--------------||---| + + |--------------| |---| + + |--------------||---| + +みたいな感じだね。
--- a/mc-code-ia32.c Sun Jun 27 14:56:21 2004 +0900 +++ b/mc-code-ia32.c Sun Jun 27 20:31:46 2004 +0900 @@ -373,6 +373,21 @@ } int +get_input_lregister_var(int i,NMTBL *nptr,int is_code) +{ + int h,l; + if (is_code) { + if (i+1>=MAX_CODE_INPUT_REGISTER_VAR) return 0; + h = virtual(REG_ESI); + l = virtual(REG_EDI); + regs[h]=regs[l]=INPUT_REG; + regv[h]=regv[l]=INPUT_REG; + return list2(LREGISTER,REG_L); + } + return 0; +} + +int get_dregister(int d) { return -1; @@ -437,6 +452,20 @@ return; } +extern int +code_register_overlap(int s,int t) +{ + if (car(s)==REGISTER) { + if (car(t)==REGISTER) return cadr(s)==cadr(t); + if (car(t)==LREGISTER) + return cadr(s)==virtual(REG_ESI)|| cadr(s)==virtual(REG_EDI); + } else if (car(s)==LREGISTER) { + if (car(t)==LREGISTER) return 1; + if (car(t)==REGISTER) + return cadr(t)==virtual(REG_ESI)|| cadr(t)==virtual(REG_EDI); + } + return 0; +} void register_usage(char *s)
--- a/mc-code-mips.c Sun Jun 27 14:56:21 2004 +0900 +++ b/mc-code-mips.c Sun Jun 27 20:31:46 2004 +0900 @@ -917,6 +917,52 @@ return; } + +extern int +code_register_overlap(int s,int t) +{ + switch(car(s)) { + case REGISTER: + switch(car(t)) { + case FREGISTER: break; + case REGISTER: + return cadr(s)==cadr(t); + break; + case LREGISTER: case DREGISTER: + if(cadr(s)==regv_l(cadr(t))) return 1; + if(cadr(s)==regv_h(cadr(t))) return 1; + break; + } + break; + case FREGISTER: + switch(car(t)) { + case REGISTER: case LREGISTER: case DREGISTER: break; + case FREGISTER: + return cadr(s)==cadr(t); + break; + } + break; + case DREGISTER: + case LREGISTER: + switch(car(t)) { + case FREGISTER: break; + case REGISTER: + if(cadr(t)==regv_l(cadr(s))) return 1; + if(cadr(t)==regv_h(cadr(s))) return 1; + break; + case LREGISTER: case DREGISTER: + if(regv_l(cadr(t))==regv_l(cadr(s))) return 1; + if(regv_l(cadr(t))==regv_h(cadr(s))) return 1; + if(regv_h(cadr(t))==regv_l(cadr(s))) return 1; + if(regv_h(cadr(t))==regv_h(cadr(s))) return 1; + break; + } + break; + } + return 0; +} + + void register_usage(char *s) { @@ -1794,7 +1840,7 @@ } else if (regv_h(lreg)==reg) { regs[lreg]=0; if (regv_h(lreg)>reg && ( - (regs[regv_l(lreg)]==USING_DREG) || + (regs[regv_l(lreg)]==USING_REG) || (regs[regv_l(lreg)]==USING_DREG) )) { free_register(regv_l(lreg));
--- a/mc-code-powerpc.c Sun Jun 27 14:56:21 2004 +0900 +++ b/mc-code-powerpc.c Sun Jun 27 20:31:46 2004 +0900 @@ -817,6 +817,50 @@ return; } +extern int +code_register_overlap(int s,int t) +{ + switch(car(s)) { + case REGISTER: + switch(car(t)) { + case DREGISTER: case FREGISTER: break; + case REGISTER: + if(cadr(s)==cadr(t)) return 1; + break; + case LREGISTER: + if(cadr(s)==regv_l(cadr(t))) return 1; + if(cadr(s)==regv_h(cadr(t))) return 1; + break; + } + break; + case DREGISTER: + case FREGISTER: + switch(car(t)) { + case REGISTER: case LREGISTER: break; + case DREGISTER: case FREGISTER: + if(cadr(s)==cadr(t)) return 1; + break; + } + break; + case LREGISTER: + switch(car(t)) { + case DREGISTER: case FREGISTER: break; + case REGISTER: + if(cadr(t)==regv_l(cadr(s))) return 1; + if(cadr(t)==regv_h(cadr(s))) return 1; + break; + case LREGISTER: + if(regv_l(cadr(t))==regv_l(cadr(s))) return 1; + if(regv_l(cadr(t))==regv_h(cadr(s))) return 1; + if(regv_h(cadr(t))==regv_l(cadr(s))) return 1; + if(regv_h(cadr(t))==regv_h(cadr(s))) return 1; + break; + } + break; + } + return 0; +} + void register_usage(char *s) {
--- a/mc-code.h Sun Jun 27 14:56:21 2004 +0900 +++ b/mc-code.h Sun Jun 27 20:31:46 2004 +0900 @@ -54,6 +54,7 @@ extern int get_input_lregister_var(int,NMTBL *,int); extern void code_ptr_cache_def(int r,NMTBL *nptr); extern void use_ptr_cache(int r); +extern int code_register_overlap(int s,int t); extern void emit_push(); extern int emit_pop(int type);
--- a/mc-codegen.c Sun Jun 27 14:56:21 2004 +0900 +++ b/mc-codegen.c Sun Jun 27 20:31:46 2004 +0900 @@ -844,15 +844,8 @@ for(;source;source=cadr(source)) { s=car(source); s0=cadr(s); switch(car(s)) { - // double register pair? - case REGISTER: - if(car(t)==REGISTER && s0==t0) return s; - case DREGISTER: - if(car(t)==DREGISTER && s0==t0) return s; - case FREGISTER: - if(car(t)==FREGISTER && s0==t0) return s; - case LREGISTER: - if(car(t)==LREGISTER && s0==t0) return s; + case REGISTER: case DREGISTER: case FREGISTER: case LREGISTER: + if (code_register_overlap(s,t)) return s; } if (is_same_type(s,t)) { s1=s0+caddr(source); @@ -875,7 +868,7 @@ while(use0) { if (car(use0)==t) { reg = car(caddr(use0)); - if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER) + if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER||reg==LREGISTER) free_register(cadr(caddr(use0))); break; } @@ -889,25 +882,25 @@ { int e1; /*新しいレジスタ(or スタック)を取得する*/ - if (sz==size_of_int && (e1=get_register())!=-1) { + if (scalar(ty) && sz==size_of_int && (e1=get_register())!=-1) { e1=list3(REGISTER,e1,0); *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); #if FLOAT_CODE - } else if (sz==size_of_double && (e1=get_dregister(1))!=-1) { + } else if (ty==DOUBLE && sz==size_of_double && (e1=get_dregister(1))!=-1) { e1=list3(DREGISTER,e1,0); *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); - } else if (sz==size_of_float && (e1=get_dregister(0))!=-1) { + } else if (ty==FLOAT && sz==size_of_float && (e1=get_dregister(0))!=-1) { e1=list3(FREGISTER,e1,0); *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); #endif #if LONGLONG_CODE - } else if (sz==size_of_longlong && (e1=get_lregister())!=-1) { + } else if ((ty==LONGLONG||ty==ULONGLONG)&&(e1=get_lregister())!=-1) { e1=list3(LREGISTER,e1,0); *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); @@ -1097,6 +1090,8 @@ target=list4(r, target,ty,e2); fregs++; } else if (ty==DOUBLE && (r = get_input_dregister_var(fregs,0,1,1))) { target=list4(r, target,ty,e2); fregs++; + } else if ((ty==LONGLONG||ty==ULONGLONG) && (r = get_input_lregister_var(fregs,0,1))) { + target=list4(r, target,ty,e2); regs+=2; } else { target=list4(list2(LVAR,0), target,ty,e2); } @@ -1138,7 +1133,7 @@ #endif /* we should check size also (but currently useless) */ remove0(&target,t0); - /* still we have source to avoid overwrite */ + /* still we keep source to avoid overwrite */ } } if(is_memory(s0)) {