Mercurial > hg > CbC > old > device
changeset 42:a89cf0d6904f
regv assop
author | kono |
---|---|
date | Thu, 13 Feb 2003 15:56:31 +0900 |
parents | 886ca1f2cf15 |
children | a792cf69d698 |
files | Idea mc-nop-386.c mc-parse.c mc.h |
diffstat | 4 files changed, 187 insertions(+), 112 deletions(-) [+] |
line wrap: on
line diff
--- a/Idea Wed Feb 12 06:10:09 2003 +0900 +++ b/Idea Thu Feb 13 15:56:31 2003 +0900 @@ -1475,3 +1475,11 @@ register を使用しているかだけじゃなくて、実際にcreg/dregに 値があるかどうかを記憶する必要がある。 + +Wed Feb 12 11:09:22 JST 2003 + +それだけどさ... やっぱりアドホックに実現するのは難しいんじゃないの? + +まぁねぇ。register の場所の確保と、寿命は別だから、それで +いいんだけど、regs flag だけでなんとかならないのかな。 +こういう変更ははまるが虚しい。
--- a/mc-nop-386.c Wed Feb 12 06:10:09 2003 +0900 +++ b/mc-nop-386.c Thu Feb 13 15:56:31 2003 +0900 @@ -28,7 +28,7 @@ extern void opening(char *filename); extern void ret(void); -static char *div_setup(int oreg) ; +static int edx_setup() ; static int lvar(int l); static void jump(int e1, int env); static void data_mode(char *name); @@ -53,7 +53,7 @@ /* static void st_indexx(int byte, int n, int xreg); */ static void string(int e1); static void tosop(int op); -static void div_cleanup(char *orn); +static void edx_cleanup(); static void use_register(int virt, int real, int move); static void emit_copy(int from,int to,int length,int offset); @@ -102,7 +102,6 @@ int MAX_REGISTGER_VAR=2; static int creg; /* current register */ -static int lreg; /* operand register */ static int dreg; /* temporary register */ static int reg_sp; /* REGister Stack-Pointer */ @@ -125,11 +124,9 @@ /* creg currrent virtual register - lreg operand virtual register dreg spare virtual register rname[creg] currrent real register - rname[lreg] operand real register rname[dreg] spare real register regs[] virtual register usage @@ -227,11 +224,23 @@ int i,count; count = 0; for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) count++; + if (! regs[i] && ! regv[i]) count++; } return count; } +static void +free_all_register(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + regs[i]=regv[i]=0; + } + creg = get_register(); + dreg = get_register(); + return; +} + void use_register_var(int i) { regv[i]=1; @@ -254,6 +263,28 @@ creg = creg_back; creg_regvar = creg_regvar_back; } +void +register_usage(char *s) +{ + 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++) { + 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)); + for(i=reg_sp;i>=0;i--) { + if(reg_stack[i]>=0) + printf(" %s",register_name(reg_stack[i],0)); + } +#endif + printf("\n"); +} void gexpr_init(void) @@ -263,17 +294,18 @@ } text_mode(); use_register(creg,REG_EAX,0); - /* use_register(dreg,REG_EDX,0); */ + regv[dreg]=0; creg_regvar = -1; + register_usage("gexpr_init"); } + void emit_init(void) { int i; for(i=0;i<REAL_MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} - creg = get_register(); /* must be EAX */ - dreg = get_register(); /* must be EBX */ + free_all_register(); reg_sp = 0; text_mode(); } @@ -303,6 +335,7 @@ return; real_v = virtual(real); move_op = regs[real_v]?"\txchg %s,%s\n":"\tmovl %s,%s\n"; +#define REGFLOW #ifdef REGFLOW if (move || (regv[real_v])) { printf(move_op,reg_name[rname[virt]],reg_name[real]); @@ -351,20 +384,7 @@ int pop_register(void) { /* レジスタから値を取り出す */ - int i,j; - - j = creg; - i = reg_stack[--reg_sp]; - - if(i<0) { - return i; - } else { - free_register(i); - lreg = i; - regs[i]=0; - regv[i]=1; - return lreg; - } + return reg_stack[--reg_sp]; } int @@ -380,29 +400,57 @@ if(new_reg<0) { /* もうレジスタがない */ reg_stack[reg_sp++] = -1; printf("\tpushl %s\n",register_name(creg,0)); + /* creg is used soon, don't regv[creg]=0 */ } else { reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ creg = new_reg; + regv[creg]=1; } - regv[creg]=0; +} + +void +emit_push_x(int xreg) +{ + int new_reg; + new_reg = get_register(); + if(new_reg<0) { /* もうレジスタがない */ + reg_stack[reg_sp++] = -1; + printf("\tpushl %s\n",register_name(xreg,0)); + /* creg is used soon, don't regv[xreg]=0 */ + } else { + reg_stack[reg_sp++] = xreg; /* push するかわりにレジスタを使う */ + xreg = new_reg; + regv[xreg]=1; + } } int emit_pop(int type) { int xreg; - if (pop_register()==-1) { + if ((xreg=pop_register())==-1) { if (type==POINTER_REG) use_pointer(dreg,0); else if (type==DATA_REG) use_data_reg(dreg,0); +if (regv[dreg]) { + printf("# emit_pop dreg conflict\n"); +} printf("\tpopl %s\n",register_name(dreg,0)); xreg = dreg; + regv[xreg]=1; + } + return xreg; +} + +static void +emit_pop_free(int xreg) +{ + if (xreg==dreg) { + regv[dreg]=0; } else { - xreg = lreg; + free_register(xreg); } - regv[xreg]=1; - return xreg; } int @@ -426,12 +474,16 @@ #if 0 if(lineno==2862) { g_expr(e1); /*break here*/ - csvalue = rname[creg]; /* for siwtch value */ return; } #endif g_expr(e1); - csvalue = rname[creg]; /* for siwtch value */ +} + +int +csvalue() +{ + return rname[creg]; /* for siwtch value */ } void @@ -447,41 +499,52 @@ case GVAR: /* use_pointer(creg,0); */ printf("\tmovl $%s,%s\n",(char *)caddr(e1),register_name(creg,0)); + regv[creg]=1; return; case RGVAR: /* use_pointer(creg,0); */ printf("\tmovl %s,%s\n",(char *)caddr(e1),register_name(creg,0)); + regv[creg]=1; return; case CRGVAR: printf("\tmovsbl %s,%s\n",(char *)caddr(e1),register_name(creg,0)); + regv[creg]=1; return; case LVAR: /* use_pointer(creg,0); */ printf("\tlea %d(%%ebp),%s\n",lvar(e2),register_name(creg,0)); + regv[creg]=1; return; case REGISTER: /* this is of course redundant... */ /* we can use rname for this? */ /* or why not creg=e2? */ printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0)); + regv[creg]=1; return; case RLVAR: printf("\tmovl %d(%%ebp),%s\n",lvar(e2),register_name(creg,0)); + regv[creg]=1; return; case CRLVAR: printf("\tmovsbl %d(%%ebp),%s\n",lvar(e2),register_name(creg,0)); + regv[creg]=1; return; case FNAME: printf("\tmovl $%s,%s\n",((NMTBL *)e2)->nm,register_name(creg,0)); + regv[creg]=1; return; case CONST: /* 代入する値が0でも特別な処理はしない */ printf("\tmovl $%d,%s\n",e2,register_name(creg,0)); + regv[creg]=1; return; case STRING: string(e1); + regv[creg]=1; return; case FUNCTION: function(e1); + regv[creg]=1; return; case CODE: jump(e2,caddr(e1)); @@ -532,11 +595,10 @@ } g_expr(e2); emit_push(); -/* in case of register full we should copy creg to dreg */ xrn = register_name((e2=emit_pop(0)),0); printf("\tmovl (%s),%s\n",xrn,register_name(creg,0)); printf("\taddl $%d,(%s)\n",caddr(e1),xrn); - regv[e2]=0; + emit_pop_free(e2); return; case CPOSTINC: /* char *p; *p++ */ @@ -546,11 +608,11 @@ return; } g_expr(e2); - emit_push(); /* in case of register full we should copy creg to dreg */ + emit_push(); xrn = register_name((e2=emit_pop(0)),1); printf("\tmovsbl (%s),%s\n",xrn,register_name(creg,0)); printf("\tincl (%s)\n",xrn); - regv[e2]=0; + emit_pop_free(e2); return; case CPREINC: if (car(e2)==REGISTER) { @@ -583,7 +645,7 @@ e2 = emit_pop(0); printf("\tdecl (%s)\n",register_name(e2,0)); printf("\tmovsbl (%s),%s\n",register_name(e2,0),register_name(creg,0)); - regv[e2]=0; + emit_pop_free(e2); return; case MUL: case UMUL: case DIV: case UDIV: @@ -628,9 +690,11 @@ if (retcont==0) retcont=fwdlabel(); printf("\tleal _%d,%s\n",retcont,register_name(creg,0)); + regv[creg]=1; return; case ENVIRONMENT: printf("\tmovl %%ebp,%s\n",register_name(creg,0)); + regv[creg]=1; return; default: b_expr(e1,1,e2=fwdlabel()); /* including > < ... */ @@ -640,6 +704,7 @@ fwddef(e2); printf("\tmovl $1,%s\n",xrn); fwddef(e3); + regv[creg]=1; } } @@ -824,15 +889,17 @@ /* otherwise we don't need this */ if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0)); if(creg!=to) { + if (to==dreg) error(-1); free_register(creg); creg=to; } regv[from]=regv[to]=regv[dreg]=0; + regv[creg]=1; } int struct_push(int e4,int t) { - int length,xreg,save; + int length,xreg,save,lreg; g_expr(e4); length=size(t); if(length%size_of_int) { @@ -850,6 +917,7 @@ if (register_full()) { /* this is wrong assumption */ save = 1; + for(lreg=0;lreg!=creg&&lreg!=dreg;lreg++); printf("\tpushl %s\n",register_name(lreg,0)); xreg = lreg; } else { @@ -859,6 +927,7 @@ printf("\tmovl %%esp,%s\n",register_name(xreg,0)); regv[xreg]=1; emit_copy(creg,xreg,length,0); + /* we have value in creg */ if (save) { printf("\tpopl %s\n",register_name(lreg,0)); } else @@ -1013,7 +1082,7 @@ { int i,args,e2,e3,e4,e5,nargs,regs; NMTBL *n,*code0; - int new_disp,scode,disp1; + int new_disp,scode,disp1,xreg; char *xrn; /* We need three passes. Compute Stack size, Compute Arg, Copy it. */ @@ -1115,13 +1184,15 @@ /* same positioned variable */ reg_sp--; } else { - printf("\tmovl %s,%d(%%ebp)\n",register_name(emit_pop(0),0), lvar(e4)); + printf("\tmovl %s,%d(%%ebp)\n",register_name((xreg=emit_pop(0)),0), lvar(e4)); } } } + free_register(xreg); if (car(e2) != FNAME) { - xrn=register_name(emit_pop(0),0); + xrn=register_name((xreg=emit_pop(0)),0); } + free_register(xreg); if (!env && new_disp+disp1>disp) { /* shrink stack if necessary */ printf("\tleal %d(%%ebp),%%esp\n",new_disp-size_of_int); @@ -1147,6 +1218,7 @@ emit_push(); g_expr(e2); tosop(car(e1)); + regv[creg]=1; return; } @@ -1179,7 +1251,7 @@ g_expr(e2); xreg = emit_pop(0); emit_copy(xreg,creg,sz,0); - regv[xreg]=0; + emit_pop_free(xreg); return; } @@ -1218,7 +1290,8 @@ if (byte) use_data_reg(creg,1); e2 = emit_pop(0); printf("\t%s %s,(%s)\n",op,register_name(creg,byte),register_name(e2,0)); - regv[e2]=0; + emit_pop_free(e2); + regv[creg]=1; return; } @@ -1227,7 +1300,7 @@ { int e2,e3,byte,op,new_reg; char *xrn; - int xreg; + int xreg,edx; /* e2 op= e3 */ byte = (car(e1) == CASSOP); @@ -1244,35 +1317,30 @@ tosop(op); creg = new_reg; printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + regv[creg]=1; return; } g_expr(e2); + edx = edx_setup(); xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ - printf("\tpushl %s # assop \n",register_name(creg,0)); /* push e2 address */ - ld_indexx(byte,0,creg); - new_reg = get_register(); - /* push e3 value */ - if(new_reg<0) { /* もうレジスタがない */ - reg_stack[reg_sp++] = -1; - printf("\tpushl %s\n",xrn); - } else { - reg_stack[reg_sp++] = xreg; /* push するかわりにレジスタを使う */ - } - regv[xreg]=0; + regv[xreg]=regs[xreg]=1; + printf("\tmovl %s,%s # assop \n",register_name(creg,0),register_name(edx,0)); + regv[edx]=1; + emit_push_x(xreg); + ld_indexx(byte,0,edx); tosop(op); - if(new_reg>=0) free_register(new_reg); - printf("\tpopl %s # assop \n",register_name(dreg,0)); - printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(dreg,0)); - regv[dreg]=0; + printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0)); + edx_cleanup(); + emit_pop_free(xreg); + regv[creg]=1; return; - } void tosop(int op) { - int oreg; + int oreg,dx; char *orn,*crn; oreg = pop_register(); @@ -1291,8 +1359,9 @@ if(oreg==-1) { printf("\tpopl %s\n",register_name(dreg,0)); oreg = dreg; - regv[oreg]=1; + regv[dreg]=1; } + regv[oreg]=1; regs[oreg]=1; orn = register_name(oreg,0); crn = register_name(creg,0); switch(op) { @@ -1313,70 +1382,76 @@ break; case MUL: case UMUL: - /* use_register(dreg,REG_EDX,0); */ printf("\t%s %s,%s\n","imull",orn,crn); break; case DIV: case UDIV: - orn = div_setup(oreg); + use_register(creg,REG_EAX,1); + edx_setup(); + orn = register_name(oreg,0); if (op==DIV) printf("\tcltd\n\tdivl %s\n",orn); else printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - div_cleanup(orn); + edx_cleanup(); break; case MOD: case UMOD: - orn = div_setup(oreg); + use_register(creg,REG_EAX,1); + edx_setup(); + orn = register_name(oreg,0); if (op==DIV) printf("\tcltd\n\tdivl %s\n",orn); else printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - rname[creg]=REG_EDX; - rname[dreg]=REG_EAX; - div_cleanup(orn); + dx = virtual(REG_EDX); + if (dx!=creg) { + rname[dx]=rname[creg]; + rname[creg]=REG_EDX; + } + edx_cleanup(); break; } - if (oreg>=0) regv[oreg]=0; - regv[dreg]=0; + if (oreg!=dreg&&oreg>=0) + free_register(oreg); } -static char *dvi_push = "(%esp)"; +static int edx_stack=0; -char * -div_setup(int oreg) +int +edx_setup() { - if (oreg<0) { - use_register(creg,REG_EAX,1); - use_register(dreg,REG_EDX,0); - return 0; + int edx_save; + /* make real EDX register empty */ + if (free_register_count()<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); } - if (register_full()) { - printf("\tpushl %s\n",register_name(oreg,0)); - use_register(creg,REG_EAX,1); - use_register(oreg,REG_EDX,0); - return dvi_push; - } - regs[oreg]=1; - use_register(creg,REG_EAX,1); - use_register(dreg,REG_EDX,0); - regs[oreg]=0; - return register_name(oreg,0); + regv[edx_save]=0; + use_register(edx_save,REG_EDX,0); + return edx_save; } void -div_cleanup(char *orn) +edx_cleanup() { - if (orn==dvi_push) - printf("\taddl $4,%%esp\n"); + 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) { if (reg>=0) { - use_register(lreg,REG_ECX,1); + use_register(reg,REG_ECX,1); } else { use_register(dreg,REG_ECX,0); printf("\tpopl %%ecx\n"); @@ -1441,22 +1516,6 @@ printf("\t.ident \"Micro-C compiled\"\n"); } -/* -void -jmp_label(int l) -{ - printf("\tjmp\t_%d\n",l); -} - */ - -/* -void -jmp_eq_label(int l) -{ - printf("\tje\t_%d\n",l); -} - */ - void rexpr(int e1, int l1, char *s) { @@ -1476,6 +1535,12 @@ control=0; printf("\tjmp\t_%d\n",l); /* 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); + */ } int @@ -1536,6 +1601,7 @@ printf(".globl %s\n",name); printf("\t.type\t%s,@function\n",name); printf("%s:\n",name); + free_all_register(); } void @@ -1574,6 +1640,7 @@ printf("\tpushl %%ebx\n"); printf("\tpushl %%esi\n"); printf("\tpushl %%edi\n"); + free_all_register(); } void @@ -1598,7 +1665,7 @@ /* printf("\tleave\n"); */ } fwddef(retlabel); - use_register(creg,REG_EAX,0); + /* use_register(creg,REG_EAX,0); too late */ /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ printf("\tlea %d(%%ebp),%%esp\n",disp_offset); printf("\tpopl %%edi\n");
--- a/mc-parse.c Wed Feb 12 06:10:09 2003 +0900 +++ b/mc-parse.c Thu Feb 13 15:56:31 2003 +0900 @@ -123,6 +123,7 @@ extern void code_enter(char *name) ; extern void code_leave(char *name,int disp) ; extern void code_enter1(int disp0,int args); +extern int csvalue(); extern void emit_data_closing(NMTBL *n); extern void emit_data(int e, int t, NMTBL *n); @@ -1329,7 +1330,7 @@ slfree=lfree; svalue=csvalue1; /* save parents switch value */ gexpr(expr()); - csvalue1=csvalue ; + csvalue1=csvalue() ; lfree=slfree; checksym(RPAR); cslabel = control = 0; @@ -2315,8 +2316,7 @@ macropp[-1] ='\n'; *macropp =0; lfree = slfree; - if (lsrc && !asmf ) gen_comment(macro_buf); -/* fprintf(stderr,"#macro: %s => %s\n",nptrm->nm,macro_buf); */ + if (lsrc && !asmf && nptrm->sc==FMACRO) gen_comment(macro_buf); chptrsave = chptr; chsave = ch = chptr[-1]; chptr = macro_buf;
--- a/mc.h Wed Feb 12 06:10:09 2003 +0900 +++ b/mc.h Thu Feb 13 15:56:31 2003 +0900 @@ -193,7 +193,7 @@ EXTERN char *chptrsave; EXTERN char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr; EXTERN char *name,*cheapp,**av,/*obuf[320],*/*sptr,escape(void); -EXTERN int arg_offset,stat_no,size_of_int,disp_offset,endian,csvalue,csvalue1; +EXTERN int arg_offset,stat_no,size_of_int,disp_offset,endian,csvalue1; EXTERN int code_arg_offset; EXTERN int retlabel,retpending,retcont;