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;