Mercurial > hg > CbC > old > device
changeset 530:58aceee8e4b4
get_lregister messed up
author | kono |
---|---|
date | Fri, 30 Dec 2005 12:21:27 +0900 |
parents | ad874ef77dde |
children | 19f5882997f5 |
files | Changes mc-code-powerpc.c mc-inline.c |
diffstat | 3 files changed, 100 insertions(+), 174 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Thu Dec 29 11:05:21 2005 +0900 +++ b/Changes Fri Dec 30 12:21:27 2005 +0900 @@ -7526,146 +7526,4 @@ あぁ、確かに goto のラベルは、inline の中ではlocal なscope にしないといけないのであった。で、どうすれば良いわけ? -うまく直せない。scope 関係を見直せば良いんだけど.... enter_top_scope とか。 -マルチレベルscopeになるわけね。 - -ではなくて、parse してしまえば、single level scpe になるので、 -enter_scope して、st_label では、make_local_scope すれば良いらしい。 - -## 65: } while ( k < j); - la r11,lo16(-20)(r30) - la r10,lo16(-24)(r30) - cmpw cr2,r10,r11 - -なので、rvalue が取れてないみたいね。そう言われてみると、 -IVAR のravalue とかは無視してましたが、RVALUEみたいなのが -いるってこと? - -RINDIRECT で逃げようと思ったが、 - -## 40: if (i>j) return j; - li r11,-3 - lwz r11,lo16(0)(r11) - li r10,5 - lwz r10,lo16(0)(r10) - cmpw cr1,r10,r11 - ble cr1,L_37 - li r10,-3 - lwz r10,lo16(0)(r10) -## 41: else return i; - -const でreplaceする時がまずいな。RIVARみたいなのを作ると、 -ちょっとcaseが増えすぎるが... pindirect でいんちきするか。 - -(で、あとで、やっぱりだめで、const replace を諦めてるし) - -const で置換したIVARのアドレスを取られると気まずいなぁ。 - -このあたりはマルチパスでないとできない。まぁ、parse tree を -持っているので可能ではあるけど。 - -Sun Dec 25 20:24:02 JST 2005 - -さて、return を作らないとだめか。 - -なに、結局、 - - return value がないときは jump - return value がある時には、g_expr でjump - -にする? とりあえず。 - -pfdecl で struct_return は、なんとかしてるの? - -やっぱ、ret() で、 code_set_return_register(1); -は、だめじゃん。if 文の分岐で値を同じレジスタ -に置くためには.... ?: と同じ方法か。 - -code_get_fixed_creg ねぇ。 - t = code_get_fixed_creg(USE_CREG,d); - gen_jmp(e3=fwdlabel()); - fwddef(e2); - t1=g_expr0(cadddr(e1)); - code_set_fixed_creg(t,1,d); -ですか。 - -Mon Dec 26 10:54:29 JST 2005 - - .cstring とかのデータモードとglobalラベルが変。 - -これねぇ。string をconstに置くかどうかは arch によるわけだから、 -mc-code-*.c で解決するのが正しいわけだけど、emit_data に分散して -しまっているね。 - -Mon Dec 26 22:57:49 JST 2005 - -引数中の関数型の定義があまり正確でないらしい。型宣言のない -code segment の呼び出しで、間違った値を送ってしまう。 - -大きな構造体二種類を含む parallel assignment が 無限ループ -する。分割を小さくすると通る。 - -register のtargetがoverrapしている場合に、registerを free -してからsave_targetしているので同じregisterが再利用されて -しまって無限ループしているらしい。save_target で register -overlap を見るようにしたけど、ad-hoc じゃない? (ま、 -もともと今の実装が ad-hoc だし) - -ASSIGN_STRUCT_DIVDE ってDIVDEする大きさのlimitなのか。 -大きいのは逆にdivdeしないのか。 - -Mon Dec 26 23:18:06 JST 2005 - -そもそも、仮引数のユーザに名前と大きさを決めさせているんだ -から、順序はこっちで決めれば良い。その代わり、異なる名前で -仮引数を受けるのは許さないってのがいいかもね。とすると、code -segment の引数のdefault とかを考えるとかなり、不思議な感じ。 -なんか整合性の良い interface ってあるんだろうか? stack を含 -めて? - - goto hoge(i=1,j=3,...) - -みたいな? - -Tue Dec 27 18:17:55 JST 2005 - -inline をstaticとして扱うoptionがあった方がいいかもね。 - -あ、そうか。inline で new_lvar したら、あとでfreeしないと。 -ということは、keep track しないとまずいのね。 - -## 94: i += k; - la r3,lo16(-32)(r30) - lwz r3,lo16(0)(r3) - li r11,3 - -当然、const arg でないとconstantに置き換えてはいけないわけね。 -address を取られた場合も同様。ということは、has_address みたいな -attribute も必要なわけだ。 - -ま、それはあとで。 - -Wed Dec 28 17:29:59 JST 2005 - -skipspc() で、inmode の時に、cheap に書かれてしまうので、 -cheap 上の string をterminate しないうちに、skipspc() -してはいけないわけね。 - -なんだが、"hoge" "ahoge" のcaseに、inmode の ST_COMMENT -が干渉してしまうわけね。それは、まずいか。 - -やっぱり、STRING は、"" で一つにして、複数つながる -っていう構文にした方が良いね。 - - list(STRING,value,continue) - -みたいな感じ。でも、それだと変更が多い(何故か nptr にいれてた...) -ので、やっぱり、append しました。 - -Thu Dec 29 09:59:38 JST 2005 - -PowerPC の get_lregister が失敗するのが、まだ、微妙に残ってる。 -足りないはずないんだけどね。input register も探させちゃうか。 -そういえば、最初は input register は使わない方針だったけど、 -今は使ってもいいんじゃないの? - +うまく直せない。scope 関係を見直せば良 \ No newline at end of file
--- a/mc-code-powerpc.c Thu Dec 29 11:05:21 2005 +0900 +++ b/mc-code-powerpc.c Fri Dec 30 12:21:27 2005 +0900 @@ -167,7 +167,7 @@ int use_int0() { int i = creg; if (!i||!ireg||!is_int_reg(i)) { - if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; } + if (lreg) { free_register(lreg); lreg = 0; } if (!ireg) ireg = get_register(); // else if (ireg!=i) free_register(i); i = ireg; @@ -643,19 +643,53 @@ } #endif + int get_lregister0() { int i; for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { if (regs[i]==0) { -// printf("## get_lregister %d\n",i); return i; } } return -1; } +static int +get_lregister1(int n,int m) +{ + int i; +#if 1 + for(i=LREG_OFFSET;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { + if (regv_l(i)==n && regv_h(i)==m) { + return i; + } + } +#endif + return get_lregister0(); +} + + +static void +cleanup_lregister0() +{ + int i; +#if 1 + for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { + if (regs[i]) { + if(!regv_l(i) && !regv_h(i)) { + regs[i]=0; + // printf("## cleanup lreg 0 %d\n",i); + } else if(!regs[regv_l(i)] && !regs[regv_h(i)]) { + free_register(i); + // printf("## cleanup lreg 1 %d\n",i); + } + } + } +#endif +} + int get_lregister() { @@ -666,9 +700,10 @@ if (h==-1) return -1; regv_h(i) = h; l = get_register(); - if (l==-1) { free_register(h); return -1; } + if (l==-1) { free_register(h); free_register(i); return -1; } regv_l(i) = l; regs[i]=USING_REG; +// printf("## get_lregister %d %s %s\n",i, lregister_name_high(i), lregister_name_low(i)); return i; } @@ -720,13 +755,13 @@ free_register(int i) { /* いらなくなったレジスタを開放 */ // printf("## free_register %d\n",i); - regs[i]=0; if (is_longlong_reg(i)) { regs[regv_l(i)]=0; regs[regv_h(i)]=0; - //regv_l(i)=0; + //regv_l(i)=0; will erase input register... //regv_h(i)=0; } + regs[i]=0; } extern void @@ -752,7 +787,6 @@ get_input_lregister_var(int i,NMTBL *n,int is_code) { int ll; - ll = get_lregister0(); if (i!=-1) { if (is_code) { if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; @@ -761,6 +795,7 @@ if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; i = i+MIN_TMP_REG; } + ll = get_lregister1(i,i+1); #if ENDIAN_L==0 regv_l(ll)=i; regv_h(ll)=i+1; @@ -898,6 +933,8 @@ return 0; } +int lreg_count; + void register_usage(char *s) { @@ -914,7 +951,7 @@ #if 1 for(j=0,i=0;i<MAX_REGISTER;i++) if (regs[i]) j++; if (j>USAGE_MAX) { - printf("\n## regs:"); + printf("\n## regs(%d):",j); for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } } if (reg_sp>0) { @@ -928,7 +965,7 @@ } for(j=0,i=0;i<MAX_FREGISTER;i++) if (regs[i+FREG_OFFSET]) j++; if (j>USAGE_MAX) { - printf("\n## freg:"); + printf("\n## freg(%d):",j); for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } } if (freg_sp>0) { @@ -942,9 +979,18 @@ } for(j=0,i=0;i<REAL_MAX_LREGISTER;i++) if (regs[i+LREG_OFFSET]) j++; + lreg_count = j; if (j>USAGE_MAX) { - printf("\n## lreg:"); + printf("\n## lreg(%d):",j); for(i=0;i<REAL_MAX_LREGISTER;i++) { printf("%d",regs[i+LREG_OFFSET]); } +#if 0 + for(i=0;i<REAL_MAX_LREGISTER;i++) { + if (regs[i+LREG_OFFSET] && regv_l(i+LREG_OFFSET)) + printf(" %s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET)); + else if (regv_l(i+LREG_OFFSET)) + printf(" *%s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET)); + } +#endif } if (lreg_sp>0) { printf(" lstack "); @@ -1649,23 +1695,26 @@ } if (!is_longlong_reg(reg)) error(-1); if (reg!=creg) { - if (lreg && reg!=lreg) { - if (mode) { - printf("\tmr %s,%s\n", - lregister_name_low(reg),lregister_name_low(lreg)); - printf("\tmr %s,%s\n", - lregister_name_high(reg),lregister_name_high(lreg)); + if (lreg) { + if (reg!=lreg) { + if (mode) { + printf("\tmr %s,%s\n", + lregister_name_low(reg),lregister_name_low(lreg)); + printf("\tmr %s,%s\n", + lregister_name_high(reg),lregister_name_high(lreg)); + } + free_register(lreg); } - free_register(lreg); + if (lreg==creg) creg=0; } - free_register(creg); + if (creg) free_register(creg); regs[reg]=USING_REG; clear_ptr_cache_reg(regv_l(reg)); regs[regv_l(reg)]=USING_REG; clear_ptr_cache_reg(regv_h(reg)); regs[regv_h(reg)]=USING_REG; + creg = lreg = reg; } - creg = lreg = reg; } void @@ -2083,9 +2132,11 @@ arg,INT,INT), arg_assign); use_input_reg(cadr(r0),1); + reg_arg_list = list2(r0,reg_arg_list); } else { - if (car(arg)==LREGISTER) + if (car(arg)==LREGISTER) { use_input_reg(cadr(arg),1); + } } reg_arg_list = list2(arg,reg_arg_list); g_expr_u(assign_expr0(arg,e4,t,t)); @@ -2154,9 +2205,11 @@ for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { arg = car(reg_arg_list); if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER - ||car(arg)==LREGISTER) + ||car(arg)==LREGISTER) { +// if (car(arg)==LREGISTER) +// printf("## lreg freeing %d %s %s\n",cadr(arg), lregister_name_high(cadr(arg)), lregister_name_low(cadr(arg))); free_register(cadr(arg)); - else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); + } else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); } if (ret_type==DOUBLE||ret_type==FLOAT) { set_freg(RET_FREGISTER,0); @@ -2167,6 +2220,7 @@ } else { set_ireg(RET_REGISTER,0); } + cleanup_lregister0(); return ret_type; } @@ -3891,7 +3945,7 @@ /* 64bit int part */ static void -lmove(int to,int from) // to = from +lmove(int to,int from) // to <= from { int tmp; if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) { @@ -4431,7 +4485,9 @@ extern_conv("__umoddi3"); } -#define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); } +#define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); /* reg<=lreg */ } + +// reg = reg op oreg void ltosop(int op,int reg,int oreg) @@ -4502,7 +4558,7 @@ case LUMUL: // code_save_stacks(); // clear_ptr_cache(); - dx=get_lregister(); + dx=get_lregister(); if (dx<0) error(-1); use_reg(dx); drn_l = lregister_name_low(dx); drn_h = lregister_name_high(dx); @@ -4542,7 +4598,7 @@ default: error(-1); } - if(ox!=-1) free_register(dx); + if(ox!=-1) free_register(ox); if(dx!=-1) free_register(dx); }
--- a/mc-inline.c Thu Dec 29 11:05:21 2005 +0900 +++ b/mc-inline.c Fri Dec 30 12:21:27 2005 +0900 @@ -451,14 +451,19 @@ prindirect(int e) { int lvar; - if (car(lvar=cadr(e))==IVAR) + if (car(lvar=cadr(e))==IVAR) { lvar=p_lvar(cadr(e)); // can be anything.... - switch(car(lvar)) { - case LVAR: - return rvalue_t(lvar,cadddr(e)); - default: - return list3(car(e),pexpr(cadr(e)),caddr(e)); + switch(car(lvar)) { + case LVAR: + return rvalue_t(lvar,cadddr(e)); + case REGISTER: case DREGISTER: + case FREGISTER: case LREGISTER: + case CONST: case FCONST: case DCONST: case LCONST: + // should do type check + return lvar; + } } + return list3(car(e),pexpr(cadr(e)),caddr(e)); } static int @@ -1005,6 +1010,8 @@ #define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) +extern int lreg_count; + extern int gen_inline(int e) { @@ -1019,6 +1026,7 @@ int sret_reg_mode = ret_reg_mode; int sinline_lvars = inline_lvars; int slfree=lfree; + int slreg_count=lreg_count; int narg,arg; NMTBL *n = (NMTBL*)cadr(cadr(e)); @@ -1107,6 +1115,10 @@ inline_lvars = sinline_lvars; lfree=slfree; + if (slreg_count!=lreg_count && lreg_count>0) { + printf("## lreg_count %d != %d\n", slreg_count,lreg_count); + } + return ret_type; }