Mercurial > hg > CbC > old > device
changeset 206:4170cefb48f6
*** empty log message ***
author | kono |
---|---|
date | Thu, 15 Apr 2004 07:25:38 +0900 |
parents | a50f90d0b63a |
children | 8a3516f6eb66 |
files | Changes mc-code-powerpc.c mc-codegen.c mc-parse.c mc.h |
diffstat | 5 files changed, 181 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Thu Apr 15 01:01:51 2004 +0900 +++ b/Changes Thu Apr 15 07:25:38 2004 +0900 @@ -3927,3 +3927,5 @@ みたいな場合では、途中で解放して欲しいよね? use_int とかで lreg は解放して良いんじゃない? + +creg =0 で free_register(creg) が呼ばれているね。困ったな。
--- a/mc-code-powerpc.c Thu Apr 15 01:01:51 2004 +0900 +++ b/mc-code-powerpc.c Thu Apr 15 07:25:38 2004 +0900 @@ -50,6 +50,9 @@ static int freg_sp; /* floating point REGister Stack-Pointer */ static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +static int lreg_sp; /* longlong REGister Stack-Pointer */ +static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ + #define REG_fp 1 #define REG_sp 30 #define REG_VAR_BASE 29 @@ -64,10 +67,12 @@ #define MIN_TMP_FREG 1 #define MAX_TMP_FREG 14 -#define RET_REGISTER 3 -#define RET_FREGISTER (1+FREG_OFFSET) +#define RET_REGISTER regv[3] +#define RET_FREGISTER regv[(1+FREG_OFFSET)] #define RET_LREGISTER_L 4 /* low word */ #define RET_LREGISTER_H 3 /* high word */ +static int lreg_ret; +#define RET_LREGISTER lreg_ret int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ int MAX_FREGISTER=31; @@ -83,13 +88,15 @@ int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; -#define CREG_REGISTER MAX_TMP_REG -#define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) - static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER]; +static int regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER]; static int *regs = powerpc_regs; +#define CREG_REGISTER regv[MAX_TMP_REG] +#define FREG_FREGISTER regv[MAX_TMP_FREG+FREG_OFFSET] + + static int max_reg_var, max_freg_var; static char *reg_name[] = { @@ -122,20 +129,20 @@ } if (!is_int_reg(i)) { if (!ireg) ireg = get_register(); - i = lreg; + i = ireg; } return i; } int use_float(int i) { if (!is_float_reg(i)) i = freg; - if (!regs[i]) regs[i]=1; + if (!regs[cadr(i)]) regs[cadr(i)]=1; return i; } int use_double(int i) { if (!is_float_reg(i)) i = freg; - if (!regs[i]) regs[i]=1; + if (!regs[cadr(i)]) regs[cadr(i)]=1; return i; } @@ -162,6 +169,10 @@ static int code_d1(double d); static int code_d2(double d); #endif +#if LONGLONG_CODE +static int code_l1(long long ll); +static int code_l2(long long ll); +#endif static void code_save_stacks(); static void code_save_input_registers(); @@ -325,11 +336,15 @@ void code_init(void) { + int i; macro_define("__ppc__ 1\n"); macro_define("__BIG_ENDIAN__ 1\n"); // macro_define("_BSD_CT_RUNE_T_ int\n"); macro_define("__STDC__ 1\n"); init_ptr_cache(); + lreg_ret = glist3(LREGISTER, RET_LREGISTER_L,RET_LREGISTER_H); + for(i=0;i<MAX_REGISTER;i++) { regv[i]=glist2(REGISTER,i); } + for(i=0;i<MAX_FREGISTER;i++) { regv[i+FREG_OFFSET]=glist2(DREGISTER,i+FREG_OFFSET); } } void @@ -423,7 +438,7 @@ for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { if (regs[i]) continue; /* 使われている */ regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ - return glist2(REGISTER,i); /* その場所を表す番号を返す */ + return regv[i]; /* その場所を表す番号を返す */ } /* PTR_CACHE をつぶす */ for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { @@ -432,7 +447,7 @@ } else continue; regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ - return glist2(REGISTER,i); /* その場所を表す番号を返す */ + return regv[i]; /* その場所を表す番号を返す */ } /* search register stack */ for(i=0;i<reg_sp;i++) { @@ -443,12 +458,24 @@ return reg; } } +#if LONGLONG_CODE + /* search register stack */ + for(i=0;i<lreg_sp;i++) { + if ((reg=lreg_stack[i])>=0) { + code_assign_lvar( + (lreg_stack[i]=new_lvar(size_of_longlong)),reg,0); + lreg_stack[i]= lreg_stack[i]-REG_LVAR_OFFSET; + free_register(reg); + return get_register(); + } + } +#endif for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { reg =REG_VAR_BASE-i; if (! regs[reg]) { /* 使われていないなら */ regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ if (i>max_reg_var) max_reg_var=i; - return glist2(REGISTER,reg); /* その場所を表す番号を返す */ + return regv[reg]; /* その場所を表す番号を返す */ } } /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ @@ -469,7 +496,7 @@ for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { if (regs[i]) continue; /* 使われている */ regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ - return glist2(DREGISTER,i); /* その場所を表す番号を返す */ + return regv[i]; /* その場所を表す番号を返す */ } /* search register stack */ for(i=0;i<freg_sp;i++) { @@ -485,7 +512,7 @@ if (! regs[reg]) { /* 使われていないなら */ regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ if (i>max_freg_var) max_freg_var=i; - return glist2(DREGISTER,reg); /* その場所を表す番号を返す */ + return regv[reg]; /* その場所を表す番号を返す */ } } /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ @@ -499,23 +526,43 @@ } #endif -#if LONGLONG_CODE int get_lregister() { int h,l,h0,l0; h = get_register(); h0 = cadr(h); l = get_register(); l0 = cadr(l); - free_glist2(h); free_glist2(l); return glist3(LREGISTER,l0,h0); } int get_lregister_var(NMTBL *n) { + int i,j; + int max_reg_var_save=max_reg_var; + for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { + if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ + /* そのレジスタを使うことを宣言し */ + regs[REG_VAR_BASE-i]=USING_REG; + if (i>max_reg_var) max_reg_var=i; + for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) { + if (! regs[REG_VAR_BASE-j]) { /* 使われていないなら */ + /* そのレジスタを使うことを宣言し */ + regs[REG_VAR_BASE-j]=USING_REG; + if (j>max_reg_var) max_reg_var=j; + /* その場所を表す番号を返す */ + return list3(LREGISTER, + glist3(LREGISTER,REG_VAR_BASE-j,REG_VAR_BASE-i), + (int)n); + } + } + /* ひとつしかなかった */ + regs[REG_VAR_BASE-i]=0; + max_reg_var=max_reg_var_save; + } + } return list2(LVAR,new_lvar(size_of_longlong)); } -#endif void emit_pop_free(int xreg) @@ -526,8 +573,13 @@ void free_register(int i) { /* いらなくなったレジスタを開放 */ - if (i<0||MAX_FREGISTER+FREG_OFFSET<i) error(-1); - regs[i]=0; + int j; + if (i==0) return; + j = cadr(i); regs[j]=0; + if (car(i)==LREGISTER) { + j = caddr(i); regs[j]=0; + free_glist3(i); + } } int @@ -540,20 +592,20 @@ if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; i = i+MIN_TMP_FREG+FREG_OFFSET; } - return list3(DREGISTER,glist2(DREGISTER,i),(int)n); + return list3(DREGISTER,regv[i],(int)n); } int get_input_lregister_var(int i,NMTBL *n,int is_code) { if (is_code) { - if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; + if(!(i+1<REG_VAR_BASE-REG_VAR_MIN)) return 0; i = REG_VAR_BASE-i; } else { - if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; + if (i<0||i+1>=MAX_INPUT_REGISTER_VAR) return 0; i = i+MIN_TMP_REG; } - return list3(LREGISTER,glist3(LREGISTER,i+1,i),(int)n); + return list3(LREGISTER,list3(LREGISTER,i+1,i),(int)n); } int @@ -566,7 +618,7 @@ if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; i = i+MIN_TMP_REG; } - return list3(REGISTER,glist2(REGISTER,i),(int)n); + return list3(REGISTER,regv[i],(int)n); } /* double register case? */ @@ -581,7 +633,7 @@ if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; i = i+MIN_TMP_REG; } - return list3(REGISTER,glist2(REGISTER,i),(int)n); + return list3(REGISTER,regv[i],(int)n); } int @@ -617,6 +669,10 @@ free_all_register(void) { int i; +#if LONGLONG_CODE + if (lreg) free_register(lreg); + lreg = 0; +#endif for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; } for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; } #if FLOAT_CODE @@ -637,7 +693,10 @@ if (chk) return; if (!lsrc) return; printf("# %d: %s:",lineno,s); - printf(" creg=%s fgreg=%s",register_name(creg),fregister_name(freg)); + if (ireg) printf(" creg=%s",register_name(ireg)); + if (freg) printf(" freg=%s",fregister_name(freg)); + if (lreg) printf(" lreg=%s,%s",lregister_name_high(lreg), + lregister_name_low(lreg)); #if 0 printf("\n# regs:"); for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } @@ -660,6 +719,9 @@ while(freg_sp > 0) { free_register(freg_stack[--freg_sp]); } + while(lreg_sp > 0) { + free_register(lreg_stack[--lreg_sp]); + } text_mode(); gexpr_code_init(); register_usage("gexpr_init"); @@ -687,18 +749,13 @@ regs[REG_VAR_BASE-i]=USING_REG; if (i>max_reg_var) max_reg_var=i; /* その場所を表す番号を返す */ - return list3(REGISTER,REG_VAR_BASE-i,(int)n); + return list3(REGISTER,glist2(REGISTER,REG_VAR_BASE-i),(int)n); } } return list2(LVAR,new_lvar(size_of_int)); } int -fregister_var(int r) { - return r; -} - -int get_dregister_var(NMTBL *n,int d) { int i; @@ -707,7 +764,8 @@ regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ if (i>max_freg_var) max_freg_var=i; /* その場所を表す番号を返す */ - return list3(DREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); + return list3(DREGISTER, + glist2(DREGISTER,FREG_VAR_BASE-i+FREG_OFFSET),(int)n); } } return list2(LVAR,new_lvar(size_of_double)); @@ -746,14 +804,14 @@ if (xreg<= -REG_LVAR_OFFSET) { return list2(LVAR,REG_LVAR_OFFSET+xreg); } else { - return list2(REGISTER,xreg); + return xreg; } } else { xreg = freg_stack[freg_sp]; if (xreg<= -REG_LVAR_OFFSET) { return list2(LVAR,REG_LVAR_OFFSET+xreg); } else { - return list2(DREGISTER,xreg); + return xreg; } } return xreg; @@ -823,7 +881,7 @@ ptr_cache = p; /* now the last one is the top */ if (!caddr(p)) { if((r=get_register())) { - caddr(p)=r; regs[r]=PTRC_REG; + caddr(p)=r; regs[cadr(r)]=PTRC_REG; } else { error(-1); r=creg; /* this can't happen */ @@ -1269,14 +1327,13 @@ { if (reg!=creg) { clear_ptr_cache_reg(reg); - if (reg!=ireg && mode) + if (ireg && reg!=ireg && mode) { printf("\tmr %s,%s\n",register_name(reg),register_name(ireg)); + } free_register(creg); - creg = ireg = reg; - regs[creg]=1; + regs[cadr(creg)]=USING_REG; } - if (ireg!=creg) error(-1); - ireg = reg; + creg = ireg = reg; } void @@ -1287,16 +1344,26 @@ printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg)); } free_register(creg); - creg = freg = reg; - regs[freg]=1; + regs[cadr(freg)]=USING_REG; } - if (freg!=creg) error(-1); - freg = reg; + creg = freg = reg; } void set_lreg(int reg,int mode) { + if (reg!=creg) { + if (reg!=lreg && 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)); + } + regs[cadr(lreg)]=USING_REG; + regs[caddr(lreg)]=USING_REG; + free_register(creg); + } + creg = lreg = reg; } void @@ -1306,6 +1373,10 @@ regs[cadr(arg)]=USING_REG; else if (car(arg)==DREGISTER) regs[cadr(arg)]=USING_REG; + else if (car(arg)==LREGISTER) { + regs[cadr(arg)]=USING_REG; + regs[caddr(arg)]=USING_REG; + } } void @@ -1339,6 +1410,11 @@ if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } else error(-1); + } else if (tag==LREGISTER) { + /* regs[reg]==INPUT_REG case should be considered */ + n->dsp = offset; + t = n->ty; + offset+=size_of_longlong; reg_offset+=2; } else { offset += size(n->ty); continue; @@ -1346,7 +1422,7 @@ n->sc = LVAR; lvar = list2(LVAR,n->dsp); g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t)); - if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) { + if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) { free_register(reg); } } @@ -1434,6 +1510,22 @@ nargs ++ ; reg_arg++; continue; } else if (t==LONGLONG||t==ULONGLONG) { + if (reg_arg>=MAX_INPUT_REGISTER_VAR) { + arg = list2(LVAR,caller_arg_offset_v(nargs)); + } else if (!simple_args(e3) && cadr(e3)) { + arg = get_register_var(0); + arg_assign = list2( + assign_expr0(get_input_lregister_var(reg_arg,0,0), + arg,t,t), + arg_assign); + } else { + arg = get_input_lregister_var(reg_arg,0,0); + } + use_var(arg); /* protect from input register free */ + reg_arg_list = list2(arg,reg_arg_list); + g_expr_u(assign_expr0(arg,e4,t,t)); + nargs ++ ; reg_arg++; + nargs ++ ; reg_arg++; continue; } else if (t==DOUBLE||t==FLOAT) { if (reg_arg<MAX_INPUT_REGISTER_VAR) { @@ -1454,7 +1546,8 @@ } r0=get_input_register_var(reg_arg,0,0); r1 = reg_arg+1+MIN_TMP_REG; - if (regs[r1]==PTRC_REG) clear_ptr_cache_reg(r1); + if (regs[r1]==PTRC_REG) + clear_ptr_cache_reg(list2(REGISTER,r1)); /* else if (regs[r1]) error(-1); */ r1=get_input_register_var_1(reg_arg+1,0,0); @@ -1519,12 +1612,15 @@ } 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) + if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER + ||car(arg)==LREGISTER) free_register(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); + } else if (ret_type==ULONGLONG||ret_type==LONGLONG) { + set_lreg(RET_LREGISTER,0); } else if (ret_type==VOID) { } else { set_creg(RET_REGISTER,0); @@ -1572,7 +1668,7 @@ g_expr(e1); crn=register_name(creg); printf("\tlwz %s,%d(%s)\n",crn,offset,crn); - return INT; + return us?UNSIGNED:INT; } int @@ -1617,7 +1713,7 @@ printf("\t%s %s,%d(%s)\n",fload(d), fregister_name(freg),offset,crn); creg = freg; - return DOUBLE; + return d?DOUBLE:FLOAT; } #endif @@ -1628,7 +1724,11 @@ char *crn; g_expr(e1); crn=register_name(creg); - return LONGLONG; + if (!lreg) lreg = get_lregister(); + printf("\tlwz %s,%d(%s)\n",crn,offset,lregister_name_low(lreg)); + printf("\tlwz %s,%d(%s)\n",crn,offset+size_of_int,lregister_name_high(lreg)); + creg = lreg; + return us?ULONGLONG:LONGLONG; } #endif @@ -2092,6 +2192,8 @@ code_set_return_register(int mode) { if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) { set_freg(RET_FREGISTER,mode); + } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) { + set_lreg(RET_LREGISTER,mode); } else if (cadr(fnptr->ty)==VOID) { } else { set_creg(RET_REGISTER,mode); @@ -2107,7 +2209,7 @@ code_set_fixed_creg(int reg,int mode,int type) { if (type==FLOAT||type==DOUBLE) { set_freg(reg,mode); - } else if (type==LONGLONG) { + } else if (type==LONGLONG||type==ULONGLONG) { set_lreg(reg,mode); } else { set_creg(reg,mode); @@ -2141,6 +2243,9 @@ double d; float f; #endif +#if LONGLONG_CODE + long long ll; +#endif char *name; name = n->nm; if(mode!=GDECL && mode!=STADECL) { @@ -2171,6 +2276,9 @@ gpc += size_of_int; } #if LONGLONG_CODE + } else if(t==LONGLONG||t==ULONGLONG) { + ll = lcadr(e); + printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll)); #endif #if FLOAT_CODE } else if(t==DOUBLE) { @@ -2922,6 +3030,22 @@ } +static long long ll = 1LL; + +static int +code_l1(long long d) +{ + int *i = (int *)≪ int *j = (int *)&d; + return (i[1] == 1)?j[1]:j[0]; +} + +static int +code_l2(long long d) +{ + int *i = (int *)≪ int *j = (int *)&d; + return (i[1] == 1)?j[0]:j[1]; +} + void code_lconst(int e1,int e2) {
--- a/mc-codegen.c Thu Apr 15 01:01:51 2004 +0900 +++ b/mc-codegen.c Thu Apr 15 07:25:38 2004 +0900 @@ -217,7 +217,7 @@ code_dconst(e1,creg,0); return FLOAT; #endif -#if FLOAT_CODE +#if LONGLONG_CODE case LCONST: creg=use_longlong(creg); code_lconst(e1,creg);
--- a/mc-parse.c Thu Apr 15 01:01:51 2004 +0900 +++ b/mc-parse.c Thu Apr 15 07:25:38 2004 +0900 @@ -4801,6 +4801,7 @@ void free_glist2(int e1) { + if (e1>gfree) return; /* freeing local heap */ if (e1==gfree) { gfree-=2; } else { @@ -4829,6 +4830,7 @@ void free_glist3(int e1) { + if (e1>gfree) return; /* freeing local heap */ if (e1==gfree) { gfree-=3; } else {