Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 530:58aceee8e4b4
get_lregister messed up
author | kono |
---|---|
date | Fri, 30 Dec 2005 12:21:27 +0900 |
parents | ad874ef77dde |
children | 19f5882997f5 |
line wrap: on
line diff
--- 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); }