Mercurial > hg > CbC > old > device
changeset 583:421be86892b3
ia32 reorganization
author | kono |
---|---|
date | Tue, 17 Jan 2006 23:38:57 +0900 |
parents | 3f60e599cc04 |
children | ef6e0e05137f |
files | .gdbinit Changes mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c |
diffstat | 5 files changed, 487 insertions(+), 470 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Mon Jan 16 00:52:56 2006 +0900 +++ b/.gdbinit Tue Jan 17 23:38:57 2006 +0900 @@ -39,7 +39,7 @@ # run -s l.c # run -s test/const.c # run -s test/basic.c -# run -s test/code-gen-all.c +run -s test/code-gen-all.c # run -s test/tmp7.c # run -s test/inline.c # run -s test/code-gen-inline.c @@ -55,4 +55,4 @@ # run -s test/func_conv_err.c # run -DINLINE=inline test/tmp7.c # run -DINLINE=inline test/code-gen-all.c -run -s throw.c +# run -s throw.c
--- a/Changes Mon Jan 16 00:52:56 2006 +0900 +++ b/Changes Tue Jan 17 23:38:57 2006 +0900 @@ -8414,4 +8414,97 @@ esi/edi をget_regsiter しないと、assop などで、致命的に足り ないことになる。 - +rname しないとすると、use_data_reg したら、必ず後で戻す +みたいな実装か? + +get_register では data_registerが取れて、get_pointer では、 +esi が取れて、それは、use_data_reg/setup_edx では、使われない +みたいな感じかなぁ。 + +Mon Jan 16 08:42:16 JST 2006 + +やっぱり ia32 は、設計が悪い。 + + rname, dreg は廃止 + use_data_reg は、use_int などと同じ形式に + setup_edx などは止め、parallel_rassign を使用する + +とすれば、register を復活できるのではないだろうか? +mc-code-mips とかから再構成する? + +Mon Jan 16 09:03:27 JST 2006 + +というわけで、 + +cbc - 環境/インタフェースの切替え + +やっぱり、そのままでは動きませんでしたが、付けてみました。 +うまく使うと、POSIX Thread 的に使うことも可能。 + +例題は CbC_project/device/test/throw.c にあります。 + +code +throw(interface1 arg,int i,int j) +{ + char *space = (char *)malloc(ENVSIZE)+ENVSIZE; + printf("%d %d %d %d %d\n",arg.last,arg.a,arg.c[99],i,j); + arg.last=97; + goto throw1(arg,i,75),space; +} + +こんな感じで使います。space (切替えるべき環境)は、stack な +のでメモリ領域の一番下を指しているようにしてください。context +とか呼ぶ人もいるだろうな。大きさ的にどれくらいいるかは、 +状況による。64Kbyteはとるべきでしょう。 + +でも、常に interface がコピーされるのでは、あまり意味がない +のか。interface をコピーしないで保存するモードがあれば良い +のかな。 + + goto throw1(),space; + +みたいな感じ? env が最後を指しているのが不便だが。 + + code hoge(interface &hoge) {}; + +みたいな? もともと参照だしね。引数のずれを防ぐのも考えないと。 +struct に64byteのalignment を入れるか。 + +やっぱり、特定の型を作って、 + __env env = new_env(size); + goto throw(env); +みたいな感じの方がいいのかな。 + +int +main1() +{ + interface1 arg; + char *space = (char *)malloc(ENVSIZE)+ENVSIZE; + ret = return; + env = environment; + goto throw1(arg,-6,77),space; +} + +ってな感じで、Cの環境から呼ぶことも可能。 + +space が一番下ってのも変だが、stack だから仕方がない? こういう風に +実装するなら、下向きに延ばすことも可能だが.... C のスタックと干渉 +するから、だめか。 + +Tue Jan 17 10:56:08 JST 2006 + +一応、ia32 から ranme と dreg は落しましたが.... + + get_register が必ず成功するようにする + register_var をセーブするような手法が必要かも? + free_register で戻す + でも、save されたって言う保証がない? + dreg を使っていたところを get_register に直す + use_data_reg0 を書き直し + +というわけで、結構あるなぁ。(こんなのより論文書いたら?) + +なんか creg=0 をemptyだと思っているみたいだけど、-1 だろ? + +酒飲んでないけど、頭が廻らん。 +
--- a/mc-code-ia32.c Mon Jan 16 00:52:56 2006 +0900 +++ b/mc-code-ia32.c Tue Jan 17 23:38:57 2006 +0900 @@ -165,11 +165,15 @@ static int output_mode = TEXT_EMIT_MODE; static int creg; +static int ireg; static int lreg; +#define regv_l(r) (r==REG_L?REG_ESI:REG_EAX) +#define regv_h(r) (r==REG_L?REG_EDI:REG_EDX) + int code_lassop_p = 0; -int MAX_REGISTER=6; /* intel386のレジスタを6つまで使う*/ +#define MAX_REGISTER 6 /* intel386のレジスタを6つまで使う*/ #define REAL_MAX_REGISTER 8 /* intel386のレジスタが8つということ*/ static int MAX_DATA_REG=4; static int MAX_POINTER=3; @@ -195,7 +199,6 @@ static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ static int reg_var; -static int regvar[2]; /* @@ -237,75 +240,64 @@ } /* - creg current virtual register - dreg spare virtual register - - rname[creg] current real register - rname[dreg] spare real register - - regs[] virtual register usage - regv[] value in virtual register flag - - reg_name[rname[creg]] + creg current register + + regs[] register usage + regv[] value in register flag freg current floating point register fregv value in floating point register */ -static int dreg; /* general temporal register */ - #define REAL_MAX_LREGISTER 2 -static int ia32regs[REAL_MAX_REGISTER+REAL_MAX_LREGISTER]; -static int ia32regv[REAL_MAX_REGISTER+REAL_MAX_LREGISTER]; -static int ia32rname[REAL_MAX_REGISTER+REAL_MAX_LREGISTER]; - -static int *regv = ia32regv; +static int ia32regs[1+REAL_MAX_REGISTER+REAL_MAX_LREGISTER]; + + static int *regs = ia32regs; -static int *rname = ia32rname; static int ia32fregs[1]; -static int ia32fregv[1]; - +static int *fregs = ia32fregs; static int freg; -static int *fregv = ia32fregv; -static int *fregs = ia32fregs; - - -#define REG_EAX 0 -#define REG_EBX 1 -#define REG_ECX 2 -#define REG_EDX 3 -#define REG_ESI 4 -#define REG_EDI 5 -#define REG_EBP 6 -#define REG_ESP 7 -#define is_int_reg(reg) (reg<REG_EBP) -#define REG_LCREG 8 -#define REG_L 9 + + +#define REG_EAX 1 +#define REG_EBX 2 +#define REG_ECX 3 +#define REG_EDX 4 +#define REG_ESI 5 +#define REG_EDI 6 +#define REG_EBP 7 +#define REG_ESP 8 +#define is_int_reg(reg) (1<=reg&®<REG_EBP) +#define REG_LCREG 9 +#define REG_L 10 #define REG_fp REG_EBP -#define regv_l(r) (virtual(r==REG_L?REG_ESI:REG_EAX)) -#define regv_h(r) (virtual(r==REG_L?REG_EDI:REG_EDX)) - - #define DATA_REG 0 #define POINTER_REG 3 -static char *reg_name[8]; -static char *reg_name_l[4]; -static char *reg_name_w[4]; + +#define RET_FREGISTER +#define RET_DREGISTER +#define RET_LREGISTER REG_LCREG +#define RET_REGISTER REG_EAX + + +static char *reg_name[8+1]; +static char *reg_name_l[4+1]; +static char *reg_name_w[4+1]; static void ascii(char *s); -static void use_register(int virt, int real, int move); -static int virtual(int real); +static int use_register(int virt, int real, int move); static void shift(char *op, int reg,int creg); static void ld_indexx(int byte, int n, int xreg,int reg,int sign); //static void data_mode(char *name); // static void text_mode(int align); -static int edx_setup(int rreg); -static void edx_cleanup(); +static int get_data_register(void); + static void local_table(void); static int push_struct(int e4,int t) ; +static void code_clear_stack_reg(int reg1); #if FLOAT_CODE static char * fload(int d); static int code_d1(double d); @@ -319,25 +311,110 @@ #endif #define use_int(reg) if (reg==-1) reg=use_int0() -static int use_int0() { lreg = 0; if (!is_int_reg(creg)) { creg = virtual(REG_EBX); regs[creg]=1;} return creg; } - -#define use_longlong(reg) reg=use_longlong0(reg) + +static int +use_int0() { + int i = creg; + if (!i||!ireg||!is_int_reg(i)) { + if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; } + if (!ireg) ireg = get_register(); + i = ireg; + } + if (!regs[i]) regs[i]=USING_REG; + creg = ireg = i; + return i; +} + +#define is_data_reg(reg) (REG_EAX<=reg&®<=REG_EDX) +#define is_pointer_reg(reg) (REG_ESI<=reg&®<=REG_EBP) + +static int +use_register(int reg0, int reg1, int move) +{ + /* + reg0 becomes reg1, if (move) copy the content. + if reg1 is used, reg0 contains old value. + */ + + + char *move_op; + code_clear_stack_reg(reg1); + move_op = regs[reg0]?"\txchg %s,%s\n":"\tmovl %s,%s\n"; + if (move) { + printf(move_op,reg_name[reg0],reg_name[reg1]); + } + return reg0; +} + +#define use_data_reg(reg,keep) \ + if (reg==-1||!is_data_reg(reg)) reg=use_data_reg0(keep) + +int +use_data_reg0(int keep) +{ + int i = creg; + int ptreg =0; + if (is_pointer_reg(creg)) { + free_register(ptreg=creg); creg = 0; + } + if (!i||!ireg||!is_int_reg(i)) { + if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; } + if (!ireg) ireg = get_data_register(); + // else if (ireg!=i) free_register(i); + i = ireg; + } + if (!regs[i]) regs[i]=USING_REG; + creg = i; + if (ptreg && keep) { + printf("\tmovl %s,%s\n",reg_name[ptreg],reg_name[creg]); + } + return i; +} + +static void +set_ireg(int reg,int mode) +{ + if (!is_int_reg(reg)) error(-1); + if (reg!=creg) { + // clear_ptr_cache_reg(reg); + if (ireg && reg!=ireg ) { + free_register(ireg); + if (mode) { + printf("\tmovl %s,%s\n",reg_name[reg],reg_name[ireg]); + } + } + if (regs[creg]!=REG_VAR) free_register(creg); + if (creg==lreg) lreg = 0; + regs[reg]=USING_REG; + } + creg = ireg = reg; +} + +#define is_long_reg(reg) (reg==REG_LCREG||reg==REG_L) +#define use_longlong(reg) \ + if (reg==-1||is_long_reg(reg)) reg=use_longlong0(reg) + static int use_longlong0(int reg) { - int i; - if (reg==USE_CREG) - reg = REG_LCREG; - if (!lreg) { + int i = creg; + if (ireg) { free_register(ireg); ireg=0; } + if (!lreg||!regs[lreg]) { code_save_stacks(); - // make edx,eax free - use_register(creg,REG_EBX,regv[creg]); - use_register(dreg,REG_ECX,regv[dreg]); - for(i=0;i<reg_var;i++) - use_register(regvar[i],REG_ESI+i,1); - } - creg = lreg = reg; - return lreg; + lreg = REG_LCREG; + i = lreg; + } + if (!regs[i]) regs[i]=USING_REG; + if (!regs[regv_l(i)]) regs[regv_l(i)]=USING_REG; + if (!regs[regv_h(i)]) regs[regv_h(i)]=USING_REG; + creg = lreg = i; + return i; +} + +static void +set_lreg(int reg,int mode) +{ + use_longlong(reg); } char * @@ -364,7 +441,7 @@ endian = ENDIAN; arg_offset = 8; - MAX_REGISTER=6; + // MAX_REGISTER=6; MAX_DATA_REG=4; MAX_POINTER=3; MAX_REGISTER_VAR=2; @@ -398,16 +475,16 @@ char * register_name(int i,int byte) { - if (i<0) { + if (i<=0) { error(REG_ERR); return "%eax"; } - if (byte==1 && rname[i] <= REG_EDX) { - return reg_name_l[rname[i]]; - } else if (byte==SIZE_OF_SHORT && rname[i] <= REG_EDX) { - return reg_name_w[rname[i]]; + if (byte==1 && i <= REG_EDX) { + return reg_name_l[i]; + } else if (byte==SIZE_OF_SHORT && i <= REG_EDX) { + return reg_name_w[i]; } else { - return reg_name[rname[i]]; /* 0 or 4 means int */ + return reg_name[i]; /* 0 or 4 means int */ } } @@ -421,9 +498,8 @@ void gexpr_code_init(void){ - use_register(creg,REG_EAX,0); - regv[creg]=0; - regv[dreg]=0; + // use_register(creg,REG_EAX,0); + set_ireg(REG_EAX,0); } void @@ -433,13 +509,46 @@ int get_register(void) { /* 使われていないレジスタを調べる */ - int i; - for(i=0;i<MAX_REGISTER;i++) { + int i,reg,j; + for(i=1;i<MAX_REGISTER+1;i++) { if (! regs[i]) { /* 使われていないなら */ regs[i]=1; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ } } + /* search register stack */ + for(i=0;i<reg_sp;i++) { + if ((reg=reg_stack[i])>=0) { + code_assign_lvar( + (j=new_lvar(SIZE_OF_INT)),reg,0); + reg_stack[i]= j-REG_LVAR_OFFSET; + return reg; + } + } + error(-1); + return -1; /* 空いている場所がないなら、それを表す -1 を返す */ +} + +static int +get_data_register(void) +{ /* 使われていないレジスタを調べる */ + int i,reg,j; + for(i=1;i<=REG_EDX;i++) { + if (! regs[i]) { /* 使われていないなら */ + regs[i]=1; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + } + /* search register stack */ + for(i=0;i<reg_sp;i++) { + if (is_data_reg(i) && (reg=reg_stack[i])>=0) { + code_assign_lvar( + (j=new_lvar(SIZE_OF_INT)),reg,0); + reg_stack[i]= j-REG_LVAR_OFFSET; + return reg; + } + } + error(-1); return -1; /* 空いている場所がないなら、それを表す -1 を返す */ } @@ -447,17 +556,12 @@ free_register(int i) { /* いらなくなったレジスタを開放 */ if (i==REG_L) { reg_var=0; - regv[virtual(REG_ESI)]=regv[virtual(REG_EDI)]=0; + regs[REG_ESI]=regs[REG_EDI]=0; } else if (regs[i]==REG_VAR) { reg_var--; } else if(i==REG_LCREG) { //? REG_L? - regv[virtual(REG_EAX)]=regv[virtual(REG_EDX)]=0; + regs[REG_EAX]=regs[REG_EDX]=0; } - regv[i]=regs[i]=0; -#if 0 - if(i==REAL_MAX_REGISTER) { //? REG_L? - regv[virtual(REG_ESI)]=regv[virtual(REG_EDI)]=0; - } -#endif + regs[i]=0; } extern void @@ -477,8 +581,8 @@ { if (is_code) { if (i>=MAX_CODE_INPUT_REGISTER_VAR) return 0; - i = virtual(i+REG_ESI); - regs[i]=regv[i]=INPUT_REG; + i += REG_ESI; + regs[i]=INPUT_REG; return list3(REGISTER,i,(int)nptr); } else { return 0; @@ -497,10 +601,9 @@ int h,l; if (is_code) { if (i+1>=MAX_CODE_INPUT_REGISTER_VAR) return 0; - h = virtual(REG_ESI); - l = virtual(REG_EDI); + h = REG_ESI; + l = REG_EDI; regs[h]=regs[l]=INPUT_REG; - regv[h]=regv[l]=INPUT_REG; return list2(LREGISTER,REG_L); } return 0; @@ -516,13 +619,11 @@ get_lregister_var(NMTBL *n) { int h,l; - h = virtual(REG_ESI); - l = virtual(REG_EDI); - if (regv[REAL_MAX_REGISTER]==0&®s[h]==0&®s[l]==0) { + h = REG_ESI; + l = REG_EDI; + if (regs[h]==0&®s[l]==0) { regs[h]=regs[l]=REG_VAR; - regv[h]=regv[l]=REG_VAR; - regv[REAL_MAX_REGISTER]=1; - reg_var=2; regvar[0]=h; regvar[1]=l; + reg_var=2; return list2(LREGISTER,REG_L); } return list3(LVAR,new_lvar(SIZE_OF_LONGLONG),0); @@ -539,7 +640,7 @@ register_full(void) { int i; - for(i=0;i<MAX_REGISTER;i++) { + for(i=1;i<MAX_REGISTER+1;i++) { if (! regs[i]) { return 0; } @@ -552,8 +653,8 @@ { int i,count; count = 0; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i] && ! regv[i]) count++; + for(i=1;i<MAX_REGISTER+1;i++) { + if (! regs[i]) count++; } return d?0:count; } @@ -562,11 +663,10 @@ free_all_register(void) { int i; - for(i=0;i<MAX_REGISTER+REAL_MAX_LREGISTER;i++) { - regs[i]=regv[i]=0; + for(i=1;i<MAX_REGISTER+REAL_MAX_LREGISTER+1;i++) { + regs[i]=0; } - creg = get_register(); - dreg = get_register(); + lreg = creg = ireg = 0; reg_var = 0; return; } @@ -577,11 +677,11 @@ 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); + return cadr(s)==REG_ESI|| cadr(s)==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 cadr(t)==REG_ESI|| cadr(t)==REG_EDI; } return 0; } @@ -591,16 +691,12 @@ { int i; printf("## %d: %s:",lineno,s); - printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); - for(i=0;i<MAX_REGISTER;i++) { + if (creg) printf(" creg=%s ",register_name(creg,0)); + for(i=1;i<MAX_REGISTER+1;i++) { printf("%d",regs[i]); } - printf(":"); - for(i=0;i<MAX_REGISTER;i++) { - printf("%d",regv[i]); - } #if 0 - printf(" regs_stack",register_name(creg,0),register_name(dreg,0)); + printf(" regs_stack",register_name(creg,0); for(i=reg_sp;i>=0;i--) { if(reg_stack[i]>=0) printf(" %s",register_name(reg_stack[i],0)); @@ -632,7 +728,6 @@ if ((reg = get_input_register_var(reg_var,n,is_code0))) { n->sc = REGISTER; n->dsp = cadr(reg); - regv[n->dsp]= 1; regs[n->dsp]= INPUT_REG; reg_var++; cadddr(args)=SIZE_OF_INT; /* why we need this? */ @@ -642,7 +737,6 @@ if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { n->sc = DREGISTER; n->dsp = cadr(reg); - fregv[n->dsp]= 1; fregs[n->dsp]= INPUT_REG; freg_var++; cadddr(args)=size(type); /* why we need this? */ @@ -664,7 +758,7 @@ stack_depth = 0; text_mode(0); gexpr_code_init(); - regs[creg]=1; regv[creg]=1; + regs[creg]=1; register_usage("gexpr_init"); } @@ -673,26 +767,12 @@ emit_init(void) { int i; - for(i=0;i<REAL_MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} + for(i=1;i<REAL_MAX_REGISTER+1;i++) regs[i]=0; free_all_register(); reg_sp = 0; freg_sp = 0; } -int -virtual(int real) -{ - int real_v,i; - real_v = -1; - for(i=0;i<REAL_MAX_REGISTER;i++) { - if (rname[i]==real) { - real_v=i; - break; - } - } - return real_v; -} - int pop_register(void) { /* レジスタから値を取り出す */ @@ -702,9 +782,7 @@ void emit_pop_free(int xreg) { - if (xreg==dreg||xreg==creg) { - regv[dreg]=0; - } else if (xreg>=0) { + if (xreg>=0 && xreg!=creg) { free_register(xreg); } } @@ -713,25 +791,13 @@ int get_register_var(NMTBL *nptr) { -#if 0 - int i,j; - どうしても、%esi,%edi がvirtualでずれてループしてしまうのを - 止められないので、とりえあず諦める。 - - edx_setup あたりがまずいらしいが... - - if (reg_var<2) { - for(i=REG_ESI;i<REG_EBP;i++) { - j = virtual(i); - if (! regs[j]) { /* 使われていないなら */ - regs[j]=REG_VAR; /* そのレジスタを使うことを宣言し */ - regv[j]=0; - regvar[reg_var++]=i; - return list3(REGISTER,j,(int)nptr); /* その場所を表す番号を返す */ - } + int i; + for(i=REG_ESI;i<REG_EBP;i++) { + if (! regs[i]) { /* 使われていないなら */ + regs[i]=REG_VAR; /* そのレジスタを使うことを宣言し */ + return list3(REGISTER,i,(int)nptr); /* その場所を表す番号を返す */ } } -#endif return list3(LVAR,new_lvar(SIZE_OF_INT),0); } @@ -741,82 +807,13 @@ return list3(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT),0); } -static void -use_register(int virt, int real, int move) -{ - int real_v; - char *move_op; - if (rname[virt]==real) - return; - real_v = virtual(real); - move_op = regs[real_v]?"\txchg %s,%s\n":"\tmovl %s,%s\n"; - if (move || (regv[real_v])) { - printf(move_op,reg_name[rname[virt]],reg_name[real]); - } - rname[real_v] = rname[virt]; - rname[virt] = real; -} - -#if 0 -static void -check_virtual() -{ - int real; - if (rname[REG_ESI]!=REG_ESI) { - real = rname[REG_ESI]; - printf("\txchg %%esi,%s\n",reg_name[real]); - rname[real] = real; - rname[REG_ESI] = REG_ESI; - } - if (rname[REG_EDI]!=REG_EDI) { - real = rname[REG_EDI]; - printf("\txchg %%edi,%s\n",reg_name[real]); - rname[real] = real; - rname[REG_EDI] = REG_EDI; - } -} -#endif - -#if 0 -static void -use_pointer(int virt, int move) -{ - int i; - if (rname[virt]>=POINTER_REG) - return; - for(i=POINTER_REG;i<MAX_REGISTER;i++) { - if (!regs[virtual(i)]) { - use_register(virt,i,move); - return; - } - } - /* we prefer EBX */ - use_register(virt,REG_EBX,move); -} -#endif - -void -use_data_reg(int virt, int move) -{ - int i; - if (rname[virt]<MAX_DATA_REG) - return; - for(i=0;i<MAX_DATA_REG;i++) { - if (!regs[virtual(i)]) { - use_register(virt,i,move); - return; - } - } - /* we prefer EBX */ - use_register(virt,REG_EBX,move); -} - int emit_push() { int new_reg,old; new_reg = get_register(); + // who free new_reg? if (new_reg==creg) error(-1); old = creg; if(new_reg<0) { /* もうレジスタがない */ @@ -827,8 +824,8 @@ /* creg is used soon, don't regv[creg]=0 */ } else { reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ - creg = new_reg; - regv[creg]=1; + ireg = creg = new_reg; + regs[creg]=1; } return old; } @@ -836,26 +833,19 @@ int emit_pop(int type) { - int xreg; - if ((xreg=pop_register())==-1) { -if (regv[dreg]) { - printf("### emit_pop dreg conflict\n"); - error(-1); -} - printf("\tpopl %s\n",register_name(dreg,0)); - regv[dreg]=1; - stack_depth -= SIZE_OF_INT; - return dreg; - } else if (xreg<= -REG_LVAR_OFFSET) { - code_rlvar(xreg+REG_LVAR_OFFSET,dreg); - free_lvar(xreg+REG_LVAR_OFFSET); - regv[dreg]=1; - return dreg; + int xreg,reg; + xreg=pop_register(); + if (xreg<= -REG_LVAR_OFFSET) { + reg = get_register(); + code_rlvar(REG_LVAR_OFFSET+xreg,reg); + free_lvar(REG_LVAR_OFFSET+xreg); + xreg = reg; } return xreg; } -int +#if 0 +static int stack_top(int type) { int xreg; @@ -876,7 +866,7 @@ } return xreg; } - +#endif void @@ -894,7 +884,7 @@ } else { printf("\tmovl $%s,%s\n",((NMTBL*)caddr(e1))->nm,register_name(creg,0)); } - regv[creg]=1; + } @@ -906,7 +896,7 @@ register_name(creg,0)); } else printf("\tmovl %s,%s\n",((NMTBL*)caddr(e1))->nm,register_name(creg,0)); - regv[creg]=1; + } static char *cload(int sign,int sz) { return sz==1?(sign?"movsbl":"movzbl"):sz==SIZE_OF_SHORT?(sign?"movswl":"movzwl"):"movl"; } @@ -920,7 +910,7 @@ } else printf("\t%s %s,%s\n",cload(sign,sz), ((NMTBL*)caddr(e1))->nm,register_name(creg,0)); - regv[creg]=1; + } @@ -928,7 +918,6 @@ code_lvar(int e2,int creg) { use_int(creg); printf("\tlea %d(%%ebp),%s\n",lvar(e2),register_name(creg,0)); - regv[creg]=1; } @@ -936,7 +925,6 @@ code_register(int e2,int creg) { use_int(creg); printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0)); - regv[creg]=1; } @@ -944,7 +932,6 @@ code_rlvar(int e2,int reg) { use_int(reg); printf("\tmovl %d(%%ebp),%s\n",lvar(e2),register_name(reg,0)); - regv[creg]=1; } extern void @@ -987,7 +974,7 @@ code_crlvar(int e2,int reg,int sign,int sz) { use_int(reg); printf("\t%s %d(%%ebp),%s\n",cload(sign,sz),lvar(e2),register_name(reg,0)); - regv[creg]=1; + } @@ -995,21 +982,18 @@ code_fname(NMTBL *n,int creg) { use_int(creg); printf("\tmovl $%s,%s\n",n->nm,register_name(creg,0)); - regv[creg]=1; } void code_label_value(int label,int reg) { use_int(reg); printf("\tleal _%d,%s\n",label,register_name(reg,0)); - regv[creg]=1; } void code_const(int e2,int creg) { use_int(creg); printf("\tmovl $%d,%s\n",e2,register_name(creg,0)); - regv[creg]=1; } void @@ -1029,7 +1013,7 @@ void code_lnot(int creg) { char *xrn; - use_int(creg); + use_data_reg(creg,1); xrn = register_name(creg,1); printf("\tcmpl $0,%s\n", register_name(creg,0)); @@ -1044,13 +1028,11 @@ use_int(reg); printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),0)); printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0)); - regv[reg]=1; return; } g_expr(e2); xrn = register_name(creg,0); use_int(reg); - // use_data_reg(reg); printf("\t%s $%d,(%s)\n",(sz==1)?"addb":(sz==SIZE_OF_SHORT)?"addw":"addl",dir,xrn); printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,0)); } @@ -1063,14 +1045,13 @@ use_int(reg); printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0)); printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),0)); - regv[reg]=1; + return; } g_expr(e2); emit_push(); xrn = register_name((e2=emit_pop(0)),0); use_int(reg); - // use_data_reg(reg); printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,0)); printf("\t%s $%d,(%s)\n",(sz==1)?"addb":(sz==SIZE_OF_SHORT)?"addw":"addl",dir,xrn); emit_pop_free(e2); @@ -1082,7 +1063,6 @@ code_return(int creg) { use_int(creg); printf("\tleal _%d,%s\n",retcont,register_name(creg,0)); - regv[creg]=1; } @@ -1090,7 +1070,6 @@ code_environment(int creg) { use_int(creg); printf("\tmovl %%ebp,%s\n",register_name(creg,0)); - regv[creg]=1; } static int rexpr_bool(int e1,int reg); @@ -1115,7 +1094,6 @@ fwddef(e2); printf("\tmovl $1,%s\n",xrn); fwddef(e3); - regv[reg]=1; } else { fwddef(e2); } @@ -1231,29 +1209,35 @@ void emit_copy(int from,int to,int length,int offset,int value,int det) { - /* length <0 means upward direction copy */ + int dreg; + char *drn,*frn; + char *trn; use_int(from); use_int(to); + frn = register_name(from,0); + trn = register_name(to,0); + + /* length <0 means upward direction copy */ switch (length) { - case 0: break; + case 0: break; case 1: case -1: - printf("\tmovb %d(%s),%s\n",offset, - register_name(from,0), reg_name_l[rname[dreg]] ); - printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset, - register_name(to,0)); - break; + drn = register_name(dreg = get_data_register(),1); + printf("\tmovb %s,%d(%s)\n",drn,offset,frn); + printf("\tmovb %s,%d(%s)\n",drn,offset,trn); + free_register(dreg); + break; case 2: case -2: - printf("\tmovw %d(%s),%s\n",offset, - register_name(from,0), reg_name_w[rname[dreg]] ); - printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset, - register_name(to,0)); - break; + drn = register_name(dreg = get_data_register(),2); + printf("\tmovw %s,%d(%s)\n",drn,offset,frn); + printf("\tmovw %s,%d(%s)\n",drn,offset,trn); + free_register(dreg); + break; case 4: case -4: - printf("\tmovl %d(%s),%s\n",offset, - register_name(from,0), register_name(dreg,0)); - printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset, - register_name(to,0)); - break; + drn = register_name(dreg = get_register(),0); + printf("\tmovl %s,%d(%s)\n",drn,offset,frn); + printf("\tmovl %s,%d(%s)\n",drn,offset,trn); + free_register(dreg); + break; default: if (length <0) { if (length > -MAX_COPY_LEN) { @@ -1274,12 +1258,13 @@ emit_copy(from,to,length,offset,0,det); break; } + // should be parallel_rassign.... + printf("\tpushl %%esi\n"); printf("\tpushl %%edi\n"); printf("\tpushl %%ecx\n"); printf("\tpushl %s\n",register_name(from,0)); printf("\tpushl %s\n",register_name(to,0)); - printf("\tpushl %s\n",register_name(dreg,0)); printf("\tpopl %%ecx\n"); printf("\tpopl %%edi\n"); printf("\tpopl %%esi\n"); @@ -1314,26 +1299,21 @@ /* this code is necessary for the value of assignment or function call */ /* otherwise we don't need this */ if(creg!=to) { - if (to==dreg) - printf("\tmovl %s,%s\n",register_name(to,0),register_name(creg,0)); - else { - free_register(creg); creg=to; - } + free_register(creg); creg=to; } } - regv[from]=regv[to]=regv[dreg]=0; - regv[creg]=1; } static int push_struct(int e4,int t) { - int length,xreg,save,lreg,count; + int length,count; g_expr(e4); length=size(t); if(length%SIZE_OF_INT) { length += SIZE_OF_INT - (length%SIZE_OF_INT); } + // try small amount copy for(count=0;length<MAX_COPY_LEN;count++,length-=SIZE_OF_INT) { if (length==0) return count; else { @@ -1341,32 +1321,11 @@ length-SIZE_OF_INT,register_name(creg,0)); } } + // alignment may remain printf("\tsubl $%d,%%esp\n",length); - if (register_full()) { - save = 1; - for(lreg=0;lreg==creg||lreg==dreg;lreg++); - printf("\tpushl %s\n",register_name(lreg,0)); - xreg = lreg; regv[xreg]=0; - } else { - save=0; - xreg = get_register(); - } - if (save) - printf("\tlea %d(%%esp),%s\n",SIZE_OF_INT,register_name(xreg,0)); - else - printf("\tmovl %%esp,%s\n",register_name(xreg,0)); - regv[xreg]=1; /* downward direction copy */ - emit_copy(creg,xreg,length,0,0,1); + emit_copy(creg,REG_ESP,length,0,0,1); /* we have value in creg, it may be changed */ - if (save) { - if(creg==xreg) { - creg = get_register(); /* creg is freed in emit_copy */ - } - printf("\tpopl %s\n",register_name(xreg,0)); - regv[xreg]=1; - } else - free_register(xreg); stack_depth += length*SIZE_OF_INT; return length/SIZE_OF_INT; } @@ -1376,7 +1335,6 @@ { int e2,e3,e4,nargs,t,ret_type; NMTBL *n=0; - int save,saved; int stack_depth_save = stack_depth; ret_type = cadr(cadddr(e1)); @@ -1388,15 +1346,6 @@ code_save_fstacks(); #endif - if (free_register_count(0)<1) { - for(save = 0;save==dreg||save==creg;save++); - printf("\tpushl %s\n",register_name(save,0)); - saved = 1; - } else { - save = get_register(); - saved = 0; - } - regv[save]=0; e2 = cadr(e1); nargs = 0; for (e3 = caddr(e1); e3; e3 = cadr(e3)) { @@ -1431,14 +1380,12 @@ g_expr(e4); printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n"); nargs += SIZE_OF_DOUBLE/SIZE_OF_INT; - fregv[freg]=0; stack_depth += SIZE_OF_DOUBLE; continue; } else if (t==FLOAT) { g_expr(e4); printf("\tleal\t-4(%%esp),%%esp\n\tfstps\t(%%esp)\n"); nargs += SIZE_OF_FLOAT/SIZE_OF_INT; - fregv[freg]=0; stack_depth += SIZE_OF_FLOAT; continue; } else if (car(t)==STRUCT||car(t)==UNION) { @@ -1451,45 +1398,27 @@ } if (car(e2) == FNAME) { n=(NMTBL *)cadr(e2); - regv[creg]=0; use_register(creg,REG_EAX,0); /* will be destroyed */ } else { g_expr(e2); - regv[creg]=1; use_register(creg,REG_EAX,1); /* will be destroyed */ } - /* we don't have to save creg nor dreg */ - regs[creg]=0; regs[dreg]=0; - regv[dreg]= regv[save]= 0; - use_register(dreg,REG_EBX,0); /* will be destroyed */ - use_register(save,REG_ECX,0); /* will be destroyed */ - regs[creg]=1; regs[dreg]=1; - if (car(e2) == FNAME) { printf("\tcall\t%s\n",n->nm); } else { printf("\tcall\t*%s\n",register_name(creg,0)); } if (nargs) printf("\taddl $%d,%%esp\n",SIZE_OF_INT*nargs); - if (saved) { - printf("\tpopl %s\n",register_name(save,0)); - } else { - free_register(save); - } - regv[save]=0; if (ret_type==DOUBLE||ret_type==FLOAT) { } else if (ret_type==LONGLONG||ret_type==ULONGLONG) { use_longlong0(USE_CREG); - regv[creg]=1; } else if (ret_type==VOID) { - regv[freg]=0; regv[creg]=0; } else { if (!is_int_reg(creg)) { - lreg=0; creg=virtual(REG_EAX); + lreg=0; creg=REG_EAX; } use_register(creg,REG_EAX,0); - fregv[freg]=0; regv[creg]=1; } stack_depth = stack_depth_save; return ret_type; @@ -1504,7 +1433,7 @@ g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15)),list2(CONST,~15))); use_int(reg); if (stack_depth>0) { - edx = edx_setup(-1); + crn = register_name(reg,0); drn = register_name(edx,0); printf("\tmovl %%esp,%s\n",drn); @@ -1512,7 +1441,7 @@ printf("\tmovl %%esp,%s\n",crn); emit_copy(edx,creg,stack_depth,0,1,1); printf("\taddl $%d,%s\n",stack_depth,register_name(creg,0)); - edx_cleanup(); + } else { crn = register_name(reg,0); printf("\tsubl %s,%%esp\n",crn); @@ -1529,7 +1458,7 @@ int code_frame_pointer_register() { - return list2(REGISTER,virtual(REG_fp)); + return list2(REGISTER,REG_fp); } void @@ -1580,7 +1509,7 @@ { char *crn = register_name(creg,0); use_longlong(reg); - if((reg==REG_L&&rname[creg]==REG_ESI)||(rname[creg]==REG_EAX)) { + if((reg==REG_L&&creg==REG_ESI)||(creg==REG_EAX)) { printf("\tmovl %d(%s),%s\n",offset+SIZE_OF_INT,crn,l_edx(reg)); printf("\tmovl %d(%s),%s\n",offset,crn,l_eax(reg)); } else { @@ -1594,7 +1523,7 @@ { int reg0; g_expr(e1); - regv[reg0=creg]=1; + reg0=creg; use_longlong(reg); lload(reg0,offset,reg); return LONGLONG; @@ -1609,8 +1538,8 @@ void code_assign_gvar(int e2,int creg,int byte) { - use_int(creg); - if (byte) use_data_reg(creg,1); + if (byte) { use_data_reg(creg,1); + } else { use_int(creg); } if (cadr(e2)) printf("\t%s %s,%s+%d\n",move(byte),register_name(creg,byte),((NMTBL*)caddr(e2))->nm,cadr(e2)); else @@ -1619,8 +1548,8 @@ void code_assign_lvar(int e2,int creg,int byte) { - use_int(creg); - if (byte) use_data_reg(creg,1); + if (byte) { use_data_reg(creg,1); + } else { use_int(creg); } printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),lvar(e2)); } @@ -1634,10 +1563,9 @@ void code_assign(int e2,int byte,int creg) { use_int(e2); - use_int(creg); - if (byte) use_data_reg(creg,1); + if (byte) { use_data_reg(creg,1); + } else { use_int(creg); } printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0)); - regv[creg]=1; } void @@ -1646,64 +1574,79 @@ int xreg = creg; creg = reg = e2; tosop(op,reg,xreg); - creg = xreg; - // printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg,0)); - regs[creg]=regv[creg]=1; + set_ireg(xreg,0); } - void -code_assop(int op,int reg,int byte,int sign) { - char *xrn; +code_assop(int op,int creg,int byte,int sign) { int xreg; - int edx = edx_setup(-1); + // (*creg) op = pop() + + use_int(creg); + xreg = emit_pop(0); /* pop e3 value */ + emit_push(); + emit_pop_free(xreg); + ld_indexx(byte,0,creg,ireg,sign); + tosop(op,ireg,xreg); + if (byte) { + use_data_reg(ireg,1); + } + xreg = emit_pop(0); /* pop e3 value */ + printf("\t%s %s,(%s)\n",move(byte),register_name(ireg,byte),register_name(xreg,0)); + emit_pop_free(xreg); +} + +#if 0 + int xreg; + int edx; use_int(reg); - xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ - regv[xreg]=regs[xreg]=1; + xreg = emit_pop(0); /* pop e3 value */ + regs[xreg]=1; + edx = get_register(); printf("\tmovl %s,%s # assop \n",register_name(reg,0),register_name(edx,0)); - regv[edx]=1; ld_indexx(byte,0,edx,reg,sign); tosop(op,reg,xreg); printf("\t%s %s,(%s)\n",move(byte),register_name(reg,byte),register_name(edx,0)); - edx_cleanup(); + emit_pop_free(xreg); - regv[creg]=1; + free_register(edx); } +#endif void tosop(int op,int reg,int oreg) { - int dx; + int ox=0; char *orn,*crn; - use_int(reg); + // creg = creg op oreg + + use_int(creg); + + if(oreg==-1) { + error(-1); + } else if (oreg<= -REG_LVAR_OFFSET) { + ox = get_register(); if (ox<0) error(-1); + code_rlvar(oreg+REG_LVAR_OFFSET,ox); + oreg = ox; + } switch(op) { case LSHIFT: case ULSHIFT: shift("sall",oreg,reg); - regv[creg]=1; + if(ox) free_register(ox); return; case RSHIFT: shift("sarl",oreg,reg); - regv[creg]=1; + if(ox) free_register(ox); return; case URSHIFT: shift("shrl",oreg,reg); - regv[creg]=1; + if(ox) free_register(ox); return; } - if(oreg==-1) { - printf("\tpopl %s\n",register_name(dreg,0)); - oreg = dreg; - regv[dreg]=1; - } else if (oreg<= -REG_LVAR_OFFSET) { - code_rlvar(oreg+REG_LVAR_OFFSET,dreg); - free_lvar(oreg+REG_LVAR_OFFSET); - oreg = dreg; - regv[dreg]=1; - } - regv[oreg]=1; regs[oreg]=1; + // regs[oreg]=1; orn = register_name(oreg,0); crn = register_name(creg,0); switch(op) { @@ -1729,35 +1672,35 @@ case DIV: case UDIV: use_register(creg,REG_EAX,1); - edx_setup(REG_EDX); + if (oreg==REG_EAX) oreg=creg; + else if (oreg==REG_EDX) { + use_register(oreg,REG_ECX,1); + oreg = REG_ECX; + } orn = register_name(oreg,0); if (op==DIV) printf("\tcltd\n\tidivl %s\n",orn); else printf("\txor %%edx,%%edx\n\tdivl %s\n",orn); - edx_cleanup(); + set_ireg(REG_EAX,0); break; case MOD: case UMOD: use_register(creg,REG_EAX,1); - edx_setup(REG_EDX); + if (oreg==REG_EAX) oreg=creg; + else if (oreg==REG_EDX) { + use_register(oreg,REG_ECX,1); + oreg = REG_ECX; + } orn = register_name(oreg,0); if (op==MOD) printf("\tcltd\n\tidivl %s\n",orn); else printf("\txor %%edx,%%edx\n\tdivl %s\n",orn); - dx = virtual(REG_EDX); - if (dx!=creg) { - rname[dx]=rname[creg]; - rname[creg]=REG_EDX; - } - edx_cleanup(); + set_ireg(REG_EDX,0); break; } - if (oreg!=dreg&&oreg!=creg&&oreg>=0) - free_register(oreg); - else if (oreg==dreg) regv[dreg]=0; - regv[creg]=1; + if(ox) free_register(ox); } int @@ -1777,7 +1720,7 @@ use_int(reg); crn = register_name(reg,0); orn = cadr(orn); - datareg=(rname[reg]<MAX_DATA_REG); + datareg=is_data_reg(reg); switch(op) { case LSHIFT: @@ -1832,37 +1775,7 @@ } -static int edx_stack=0; - -int -edx_setup(int rreg) -{ - int edx_save; - /* make real EDX (or rreg) register empty */ - if (free_register_count(0)<1) { - for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++); - printf("\tpushl %s\n",register_name(edx_save,0)); - edx_stack = list3(edx_save,edx_stack,0); - } else { - edx_save = get_register(); - edx_stack = list3(edx_save,edx_stack,1); - } - regv[edx_save]=0; - if (rreg!=-1) - use_register(edx_save,rreg,0); - return edx_save; -} - - -void -edx_cleanup() -{ - if (caddr(edx_stack)==0) { - printf("\tpopl %s\n",register_name(car(edx_stack),0)); - } else - free_register(car(edx_stack)); - edx_stack = cadr(edx_stack); -} + void shift(char *op, int reg,int creg) @@ -1870,15 +1783,8 @@ use_int(creg); if (reg>=0) { use_register(reg,REG_ECX,1); - } else if (reg<= -REG_LVAR_OFFSET) { - use_register(dreg,REG_ECX,0); - code_rlvar(reg+REG_LVAR_OFFSET,dreg); - reg = dreg; - regv[dreg]=0; } else { - use_register(dreg,REG_ECX,0); printf("\tpopl %%ecx\n"); - regv[dreg]=0; } printf("\t%s %%cl,%s\n",op,register_name(creg,0)); } @@ -1886,7 +1792,11 @@ void ld_indexx(int byte, int n, int xreg,int reg,int sign) { - use_int(reg); + if (byte) { + use_data_reg(reg,1); + } else { + use_int(reg); + } if (n) printf("\t%s %d(%s),%s\n",cload(sign,byte),n, register_name(xreg,0),register_name(reg,0)); @@ -1898,7 +1808,7 @@ int code_csvalue() { - return glist2(REGISTER,rname[creg]); /* for switch value */ + return glist2(REGISTER,creg); /* for switch value */ } void @@ -1950,8 +1860,7 @@ char *s; if (!(s=code_cond(car(e1),1))) return 0; g_expr(list3(CMP,cadr(e1),caddr(e1))); - use_int(reg); - use_data_reg(reg,0); + use_data_reg(reg,1); printf("\tset%s\t%s\n",s,register_name(reg,1)); printf("\tmovzbl %s,%s\n",register_name(reg,1),register_name(reg,0)); return 1; @@ -1979,9 +1888,7 @@ /* align? */ /* this is not allowed because of ? operator - regv[creg]=regv[dreg]=0; use_register(creg,REG_EAX,0); - use_register(dreg,REG_EBX,0); */ } @@ -2082,10 +1989,9 @@ car(cadr(fnptr->ty))==STRUCT || car(cadr(fnptr->ty))==UNION)) { sz = size(cadr(fnptr->ty)); - printf("\tlea %d(%%ebp),%s\n",-sz,register_name(dreg,0)); printf("\tmovl %d(%%ebp),%s\n",disp-SIZE_OF_INT, register_name(creg,0)); - emit_copy(dreg,creg,sz,0,1,1); + // emit_copy(dreg,creg,sz,0,1,1); } else if (cadr(fnptr->ty)!=VOID) { use_register(creg,REG_EAX,0); printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0)); @@ -2116,7 +2022,7 @@ return reg; } else { use_int(reg); - return rname[reg]; + return reg; } } @@ -2131,11 +2037,15 @@ void code_set_return_register(int mode) { - if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) { - } else if (fnptr->ty==LONGLONG||fnptr->ty==ULONGLONG) { - use_longlong0(USE_CREG); + if (cadr(fnptr->ty)==FLOAT) { + // set_freg(RET_FREGISTER,mode); + } else if (cadr(fnptr->ty)==DOUBLE) { + // set_dreg(RET_DREGISTER,mode); + } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) { + set_lreg(RET_LREGISTER,mode); + } else if (cadr(fnptr->ty)==VOID) { } else { - use_register(creg,REG_EAX,mode); + set_ireg(RET_REGISTER,mode); } } @@ -2707,7 +2617,7 @@ if (mode==COND_BRANCH) { printf("\tj%s\t_%d\n",s,l1); } else { - use_int(reg); use_data_reg(reg,0); + use_data_reg(reg,0); printf("\tset%s\t%s\n",s,register_name(reg,1)); printf("\tmovzbl\t%s,%s\n", register_name(reg,1),register_name(reg,0)); @@ -2788,22 +2698,31 @@ void code_save_stacks() { + /* registers stacks are saved in local variable */ + int i,reg; + for(i=0;i<reg_sp;i++) { + if ((reg=reg_stack[i])>=0) { + code_assign_lvar( + (reg_stack[i]=new_lvar(SIZE_OF_INT)),reg,0); + reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; + free_register(reg); + } + } +} + +static void +code_clear_stack_reg(int reg1) +{ + /* specified registers stacks are saved in local variable */ /* temporal registers or stacks in fpu are saved in local variable */ - int xreg,sp,screg; - sp=reg_sp; - while(sp-->0) { - if ((xreg=reg_stack[sp])>=0) { - screg=creg; - if(creg!=xreg) { - if (xreg!=dreg) free_register(xreg); - creg = xreg; - } - code_assign_lvar( - (reg_stack[sp]=new_lvar(SIZE_OF_INT)),creg,0); - reg_stack[sp]= reg_stack[sp]-REG_LVAR_OFFSET; - regv[xreg]=0; - creg=screg; - } + int i,reg; + for(i=0;i<reg_sp;i++) { + if ((reg=reg_stack[i])>=0 && reg==reg1) { + code_assign_lvar( + (reg_stack[i]=new_lvar(SIZE_OF_INT)),reg,0); + reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; + free_register(reg); + } } } @@ -3200,11 +3119,13 @@ if (il==0) return; else if (il==32) { code_register(regv_h(reg),regv_l(reg)); + creg = ireg = REG_EAX; code_i2ll(reg); return; } else if (il>32) { code_register(regv_h(reg),regv_l(reg)); printf("\tsarl $%d,%s\n",(int)il-32,l_eax(reg)); + creg = ireg = REG_EAX; code_i2ll(reg); return; } @@ -3220,6 +3141,7 @@ code_const(0,regv_h(reg)); return; } else if (il>32) { + if (il>64) error(-1); code_register(regv_h(reg),regv_l(reg)); printf("\tsarl $%d,%s\n",(int)il-32,l_eax(reg)); code_const(0,regv_h(reg)); @@ -3258,7 +3180,6 @@ use_longlong(reg0); use_register(creg0,REG_EAX,1); - regv[creg0]=0; printf("\tcltd\n"); check_lreg(reg); @@ -3277,7 +3198,6 @@ use_longlong(reg0); use_register(creg0,REG_EAX,1); - regv[creg0]=0; use_longlong(reg0); printf("\txorl %%edx,%%edx\n"); @@ -3293,7 +3213,7 @@ void code_ll2i(int reg) { use_int(reg); - if (virtual(REG_EAX)!=reg) + if (REG_EAX!=reg) printf("\tmovl %%eax,%s\n",register_name(creg,0)); } @@ -3461,7 +3381,7 @@ return; } use_register(creg,REG_EAX,1); - edx_setup(-1); + switch(delta) { case 2: printf("\tmovl\t$1,%%edx\n"); @@ -3480,7 +3400,7 @@ printf("\tjne\t_%d\n",dlabel); printf("\tjmp\t*_%d(,%%eax,4)\n",l); break; } - edx_cleanup(); + } void @@ -3873,7 +3793,7 @@ a = ~mask|c; if (a!=-1) { /* do conjunction */ - if (rname[reg]<MAX_DATA_REG && ((a& ~0xffff)==~0xffff)) { + if (reg<MAX_DATA_REG && ((a& ~0xffff)==~0xffff)) { if ((a& ~0xff)==~0xff) printf("\tandb $%d,%s\n",a&0xff,register_name(reg,1)); else @@ -3885,7 +3805,7 @@ c = mask&c; if (c!=0) { /* do disjunction */ - if (rname[reg]<MAX_DATA_REG && (!(c& ~0xffff))) { + if (reg<MAX_DATA_REG && (!(c& ~0xffff))) { if (!(c& ~0xff)) printf("\torb $%d,%s\n",c&0xff,register_name(reg,1)); else
--- a/mc-code-mips.c Mon Jan 16 00:52:56 2006 +0900 +++ b/mc-code-mips.c Tue Jan 17 23:38:57 2006 +0900 @@ -1574,6 +1574,7 @@ default: if (length <0) { if (length > -MAX_COPY_LEN) { + free_register(dreg); dreg = 0; for(;length<=-4;length+=4,offset-=4) emit_copy(from,to,-4,offset-4,0,det); for(;length<=-2;length+=2,offset-=2) @@ -1583,6 +1584,7 @@ break; } } else if (length <=MAX_COPY_LEN) { + free_register(dreg); dreg = 0; for(;length>=4;length-=4,offset+=4) emit_copy(from,to,4,offset,0,det); for(;length>=2;length-=2,offset+=2) @@ -1619,7 +1621,7 @@ // set_ireg(to,1); } } - free_register(dreg); + if (dreg) free_register(dreg); } int @@ -2486,13 +2488,13 @@ void code_assop(int op,int creg, int byte,int sign) { - char *xrn,*crn,*drn; + char *crn,*drn; int xreg; int edx = get_register(); if(!edx) error(-1); // (*creg) op = pop() use_int(creg); - xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ + xreg = emit_pop(0); /* pop e3 value */ #if 1 set_ireg(edx,0); ld_indexx(byte,0,creg,ireg,sign);
--- a/mc-code-powerpc.c Mon Jan 16 00:52:56 2006 +0900 +++ b/mc-code-powerpc.c Tue Jan 17 23:38:57 2006 +0900 @@ -1587,6 +1587,7 @@ default: if (length <0) { if (length >= -MAX_COPY_LEN) { + free_register(dreg); dreg = 0; for(;length<=-4;length+=4,offset-=4) emit_copy(from,to,-4,offset-4,0,det); for(;length<=-2;length+=2,offset-=2) @@ -1596,6 +1597,7 @@ break; } } else if (length <=MAX_COPY_LEN) { + free_register(dreg); dreg = 0; for(;length>=4;length-=4,offset+=4) emit_copy(from,to,4,offset,0,det); for(;length>=2;length-=2,offset+=2) @@ -1631,7 +1633,7 @@ // set_ireg(to,1); } } - free_register(dreg); + if (dreg) free_register(dreg); } int