changeset 107:06f72222d6b5

prevent destorying function argument (incomeplete)
author kono
date Tue, 18 Mar 2003 12:41:32 +0900
parents 3618c0efe9d3
children 69e2e763cce5
files mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c
diffstat 4 files changed, 241 insertions(+), 190 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-ia32.c	Tue Mar 18 11:00:04 2003 +0900
+++ b/mc-code-ia32.c	Tue Mar 18 12:41:32 2003 +0900
@@ -53,6 +53,8 @@
 int MAX_REGISTGER_VAR=2;    
 int MAX_FREGISTER=1;
 
+#define MAX_FPU_STACK 7
+
 int MAX_INPUT_REGISTER_VAR = 0;
 int MAX_CODE_INPUT_REGISTER_VAR = 2;
 int MAX_INPUT_DREGISTER_VAR = 0;
@@ -120,6 +122,7 @@
 static int code_d1(double d);
 static int code_d2(double d);
 static void code_save_stacks();
+static void code_save_fstacks();
 
 void
 code_init(void)
@@ -410,7 +413,7 @@
 
 
 void 
-emit_push(void)
+emit_push()
 {
     int new_reg;
     new_reg = get_register();
@@ -457,72 +460,81 @@
 }
 
 void
-code_gvar(int e1) {
+code_gvar(int e1,int creg) {
     printf("\tmovl $%s,%s\n",(char *)caddr(e1),register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_rgvar(int e1) {
+code_rgvar(int e1,int creg) {
     printf("\tmovl %s,%s\n",(char *)caddr(e1),register_name(creg,0));
+    regv[creg]=1;
 }
 
 void
-code_crgvar(e1){
+code_crgvar(int e1,int creg){
     printf("\tmovsbl %s,%s\n",(char *)caddr(e1),register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_lvar(int e2) {
+code_lvar(int e2,int creg) {
     printf("\tlea %d(%%ebp),%s\n",e2,register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_register(int e2) {
+code_register(int e2,int creg) {
     printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
 code_rlvar(int e2,int reg) {
     printf("\tmovl %d(%%ebp),%s\n",e2,register_name(reg,0));
+    regv[creg]=1;
 }
 
 
 void
 code_crlvar(int e2,int reg) {
     printf("\tmovsbl %d(%%ebp),%s\n",e2,register_name(reg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_fname(char *e2) {
+code_fname(char *e2,int creg) {
     printf("\tmovl $%s,%s\n",e2,register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_const(int e2) {
+code_const(int e2,int creg) {
     printf("\tmovl $%d,%s\n",e2,register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_neg() {
+code_neg(int creg) {
     printf("\tnegl %s\n", register_name(creg,0));
 }
 
 
 void
-code_not() {
+code_not(int creg) {
     printf("\tnotl %s\n", register_name(creg,0));
 }
 
 
 void
-code_lnot() {
+code_lnot(int creg) {
     char *xrn;
     use_data_reg(creg,1);
     xrn = register_name(creg,1);
@@ -532,11 +544,12 @@
 }
 
 void
-code_preinc(int e1,int e2) {
+code_preinc(int e1,int e2,int reg) {
     char *xrn;
     if (car(e2)==REGISTER) {
 	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
-	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -547,11 +560,12 @@
 
 
 void
-code_postinc(int e1,int e2) {
+code_postinc(int e1,int e2,int reg) {
     char *xrn;
     if (car(e2)==REGISTER) {
-	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0));
 	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -564,12 +578,13 @@
 
 
 void
-code_cpostinc(int e1,int e2) {
+code_cpostinc(int e1,int e2,int reg) {
     char *xrn;
     if (car(e2)==REGISTER) {
 	printf("\tmovbl (%s),%s\n",register_name(cadr(e2),0),
-		register_name(creg,0));
+		register_name(reg,0));
 	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -582,11 +597,12 @@
 
 
 void
-code_cpreinc(int e1,int e2) {
+code_cpreinc(int e1,int e2,int reg) {
     if (car(e2)==REGISTER) {
 	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
 	printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0),
-		register_name(creg,0));
+		register_name(reg,0));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -596,11 +612,12 @@
 
 
 void
-code_cpostdec(int e1,int e2) {
+code_cpostdec(int e1,int e2,int reg) {
     if (car(e2)==REGISTER) {
 	printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0),
-		register_name(creg,0));
+		register_name(reg,0));
 	printf("\tdecl %s\n",register_name(cadr(e2),0));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -610,11 +627,13 @@
 
 
 void
-code_cpredec(int e1,int e2) {
+code_cpredec(int e1,int e2,int reg) {
     if (car(e2)==REGISTER) {
 	printf("\tdecl %s\n",register_name(cadr(e2),0));
 	printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0),
-		register_name(creg,0));
+		register_name(reg,0));
+	regv[reg]=1;
+	return;
     } 
     g_expr(e2);
     emit_push();
@@ -626,19 +645,21 @@
 
 
 void
-code_return() {
+code_return(int creg) {
     printf("\tleal _%d,%s\n",retcont,register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_environment() {
+code_environment(int creg) {
     printf("\tmovl %%ebp,%s\n",register_name(creg,0));
+    regv[creg]=1;
 }
 
 
 void
-code_bool(int e1) {
+code_bool(int e1,int creg) {
     char *xrn;
     int e2,e3;
     b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
@@ -648,6 +669,7 @@
     fwddef(e2);
     printf("\tmovl $1,%s\n",xrn);
     fwddef(e3);
+    regv[creg]=1;
 }
 
 char *
@@ -724,7 +746,7 @@
 }
 
 void
-string(int e1)
+code_string(int e1,int creg)
 {
     char *s;
     int i,lb;
@@ -1383,6 +1405,14 @@
 }
 
 void
+code_set_return_register(int mode) {
+    if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
+    } else {
+	use_register(creg,REG_EAX,mode);
+    }
+}
+
+void
 gen_gdecl(char *n, int gpc)
 {
     /*
@@ -1599,7 +1629,7 @@
     return (i[1] == 0x3ff00000)?j[1]:j[0];
 }
 
-void code_dconst(int e2)
+void code_dconst(int e2,int freg)
 { 
     int lb;
     double d = dcadr(e2);
@@ -1622,12 +1652,12 @@
     printf("\tfldl _%d\n",lb);
 }
 
-void code_dneg()
+void code_dneg(int freg)
 { 
     printf("\tfchs\n");
 }
 
-void code_d2i()
+void code_d2i(int freg,int creg)
 { 
     /* fuck you! */
     printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
@@ -1642,16 +1672,15 @@
     printf("\tpopl    %s\n",register_name(creg,0));
 }
 
-void code_i2d()
+void code_i2d(int creg,int freg)
 { 
     printf("\tpushl %s\n",register_name(creg,0));
     printf("\tfildl (%%esp)\n");
     printf("\tlea %d(%%esp),%%esp\n",size_of_int);
 }
 
-void code_d2u()
+void code_d2u(int freg,int creg)
 { 
-    /* fuck you! */
     printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3);
     printf("\tfnstcw  (%%esp)\n");
     printf("\tmovl    (%%esp), %s\n",register_name(creg,0));
@@ -1664,7 +1693,7 @@
     printf("\tlea %d(%%esp),%%esp\n",size_of_int*3);
 }
 
-void code_u2d()
+void code_u2d(int creg,int freg)
 { 
     printf("\tpushl  %s\n",register_name(creg,0));
     printf("\tpushl  %s\n",register_name(creg,0));
@@ -1673,13 +1702,13 @@
     printf("\tlea %d(%%esp),%%esp\n",size_of_int*2);
 }
 
-void code_drgvar(int e2,int d)
+void code_drgvar(int e2,int d,int freg)
 { 
     printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ;
 }
 
 
-void code_drlvar(int e2,int d)
+void code_drlvar(int e2,int d,int freg)
 { 
     printf("\t%s %d(%%ebp)\n",fload(d),e2);
 }
@@ -1718,7 +1747,7 @@
 }
 
 void
-code_dpreinc(int e1,int e2,int d) {
+code_dpreinc(int e1,int e2,int d,int freg) {
     g_expr(e2);
     printf("\t%s (%s)\n",fload(d),register_name(creg,0));
     printf("\tfld1\n");
@@ -1730,7 +1759,7 @@
 }
 
 void
-code_dpostinc(int e1,int e2,int d) {
+code_dpostinc(int e1,int e2,int d,int freg) {
     g_expr(e2);
     printf("\t%s (%s)\n",fload(d),register_name(creg,0));
     if (use)
@@ -1770,7 +1799,7 @@
 }
 
 void 
-code_fregister(int e2)
+code_fregister(int e2,int freg)
 {
     error(-1);
 }
@@ -1794,7 +1823,7 @@
     int xreg;
     if ((xreg=pop_fregister())==-1) {
     } else if (xreg<= -REG_LVAR_OFFSET) {
-	code_drlvar(lvar(REG_LVAR_OFFSET+xreg),1);
+	code_drlvar(lvar(REG_LVAR_OFFSET+xreg),1,freg);
 	/* pushed order is reversed.   We don't need this for comutable 
 	    operator, but it is ok to do this.  */
         printf("\tfxch\t%%st(1)\n");
@@ -1809,9 +1838,9 @@
 
 void emit_dpush()
 { 
+    if (freg_sp>MAX_FPU_STACK) code_save_fstacks();
     if (freg_sp>MAX_MAX) error(-1);
-    else
-	freg_stack[freg_sp++]=-1;
+    freg_stack[freg_sp++]=-1;
     printf("# fpush:%d\n",freg_sp);
 }
 
@@ -1835,6 +1864,13 @@
 	    creg=screg;
 	}
     }
+    code_save_fstacks();
+}
+
+void
+code_save_fstacks()
+{
+    int xreg,sp;
     sp=freg_sp;
     while(sp-->0) {
 	if ((xreg=freg_stack[sp])==-1) {
--- a/mc-code-powerpc.c	Tue Mar 18 11:00:04 2003 +0900
+++ b/mc-code-powerpc.c	Tue Mar 18 12:41:32 2003 +0900
@@ -126,6 +126,8 @@
 void clear_ptr_cache_reg(int r);
 int fregister_var(int r);
 int arg_offset_v(int arg);
+void    set_creg(int,int);
+void    set_freg(int,int);
 
 void
 code_init(void)
@@ -313,6 +315,8 @@
     for(i=0;i<MAX_FREGISTER;i++) { fregs[i]=0; fregv[i]=0; }
     creg = get_register();
     freg = get_fregister();
+    set_creg(CREG_REGISTER,0);
+    set_freg(FREG_FREGISTER,0);
     return;
 }
 
@@ -409,7 +413,7 @@
 }
 
 void 
-emit_push(void)
+emit_push()
 {
     int new_reg;
     if (reg_sp>MAX_MAX) error(-1);
@@ -426,7 +430,7 @@
     xreg=pop_register();
     if (xreg<= -REG_LVAR_OFFSET) {
 	xreg = get_register();
-        code_rlvar(lvar(REG_LVAR_OFFSET+xreg),1);
+        code_rlvar(lvar(REG_LVAR_OFFSET+xreg),xreg);
 	regv[xreg]=1;
     }
     return xreg;
@@ -516,43 +520,50 @@
 }
 
 void
-code_gvar(int e1) {
+code_gvar(int e1,int creg) {
     int r;
     r = get_ptr_cache((char*)caddr(e1));
     if(r!=creg)
 	printf("\tmr %s,%s\n",register_name(creg),register_name(r));
+    regv[creg]=1;
     return;
 }
 
 void
-code_rgvar(int e1) {
+code_rgvar(int e1,int creg) {
     printf("\tlwz %s,(%s)\n",register_name(creg),
                              register_name(get_ptr_cache((char*)caddr(e1))));
+    regv[creg]=1;
 }
 
 void
-code_crgvar(e1){
-    printf("\tlbz %s,(%s)\n",register_name(creg),
+code_crgvar(int e1,int creg){
+    char *crn = register_name(creg);
+    printf("\tlbz %s,(%s)\n",crn,
                              register_name(get_ptr_cache((char*)caddr(e1))));
-    printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+    printf("\textsb %s,%s\n",crn,crn);
+    regv[creg]=1;
 }
 
 void
-code_lvar(int e2) {
+code_lvar(int e2,int creg) {
     printf("\tla %s,%d(r1)\n",register_name(creg),e2);
+    regv[creg]=1;
 }
 
 
 void
-code_register(int e2) {
+code_register(int e2,int creg) {
     if (creg!=e2)
 	printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
+    regv[creg]=1;
 }
 
 
 void
 code_rlvar(int e2,int reg) {
     printf("\tlwz %s,%d(r1)\n",register_name(reg),e2);
+    regv[creg]=1;
 }
 
 
@@ -560,21 +571,23 @@
 code_crlvar(int e2,int reg) {
     printf("\tlbz %s,%d(r1)\n",register_name(reg),e2);
     printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
+    regv[reg]=1;
 }
 
 
 void
-code_fname(char *e2) {
+code_fname(char *e2,int creg) {
     int r;
     r = get_ptr_cache(e2);
     if(r!=creg)
 	printf("\tmr %s,%s\n",register_name(creg),register_name(r));
+    regv[creg]=1;
     return;
 }
 
 
 void
-code_const(int e2) {
+code_const(int e2,int creg) {
     char *crn = register_name(creg);
     if (-32768<e2&&e2<32768)
 	printf("\tli %s,%d\n",crn,e2);
@@ -582,36 +595,38 @@
 	printf("\tlis %s,ha16(%d)\n",crn,e2);
 	printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2);
     }
+    regv[creg]=1;
 }
 
 
 void
-code_neg() {
+code_neg(int creg) {
     printf("\tneg %s,%s\n", register_name(creg), register_name(creg));
 }
 
 
 void
-code_not() {
+code_not(int creg) {
     printf("\tnor %s,%s,%s\n", 
 	register_name(creg), register_name(creg),register_name(creg));
 }
 
 
 void
-code_lnot() {
+code_lnot(int creg) {
     printf("\tsubfic r0,%s,0\n", register_name(creg));
     printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg));
 }
 
 void
-code_preinc(int e1,int e2) {
+code_preinc(int e1,int e2,int reg) {
     char *xrn,*drn;
     int i,dreg;
     if (car(e2)==REGISTER) {
 	printf("\taddi %s,%s,%d\n", 
 		register_name(cadr(e2)),register_name(cadr(e2)), caddr(e1));
-	printf("\tmr %s,%s\n",register_name(cadr(creg)),register_name(e2));
+	printf("\tmr %s,%s\n",register_name(cadr(reg)),register_name(e2));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -622,19 +637,20 @@
     printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1));
     printf("\tstw %s,(%s)\n",drn,xrn);
     i=creg;creg=dreg;dreg=i;
-    regv[creg=1];
+    regv[creg]=1;
     free_register(dreg);
 }
 
 
 void
-code_postinc(int e1,int e2) {
+code_postinc(int e1,int e2,int reg) {
     char *xrn,*crn,*nrn;
     int dreg,nreg,i;
     if (car(e2)==REGISTER) {
-	printf("\tmr %s,%s\n",register_name(creg),register_name(cadr(e2)));
+	printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2)));
 	printf("\taddi %s,%s,%d\n", 
 	    register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -654,14 +670,15 @@
 
 
 void
-code_cpostinc(int e1,int e2) {
+code_cpostinc(int e1,int e2,int reg) {
     char *xrn,*crn,*nrn;
     int i,nreg,dreg;
     if (car(e2)==REGISTER) {
-	printf("\tlbz %s,(%s)\n",register_name(creg),register_name(cadr(e2)));
-	printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+	printf("\tlbz %s,(%s)\n",register_name(reg),register_name(cadr(e2)));
+	printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
 	printf("\taddi %s,%s,%d\n", 
 	    register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -683,12 +700,13 @@
 
 
 void
-code_cpreinc(int e1,int e2) {
+code_cpreinc(int e1,int e2,int reg) {
     char *xrn,*crn,*nrn;
     int i,nreg,dreg;
     if (car(e2)==REGISTER) {
-	printf("\tlbzu %s,%d(%s)\n",register_name(creg),caddr(e1),register_name(cadr(e2)));
-	printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+	printf("\tlbzu %s,%d(%s)\n",register_name(reg),caddr(e1),register_name(cadr(e2)));
+	printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -709,15 +727,16 @@
 
 
 void
-code_cpostdec(int e1,int e2) {
+code_cpostdec(int e1,int e2,int reg) {
     char *xrn,*crn,*nrn;
     int i,nreg,dreg;
     if (car(e2)==REGISTER) {
-	crn=register_name(creg);
+	crn=register_name(reg);
 	xrn=register_name(cadr(e2));
 	printf("\tlbz %s,(%s)\n",crn,xrn);
 	printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
 	printf("\textsb %s,%s\n",crn,crn);
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -739,14 +758,15 @@
 
 
 void
-code_cpredec(int e1,int e2) {
+code_cpredec(int e1,int e2,int reg) {
     char *xrn,*crn,*nrn;
     int i,nreg,dreg;
     if (car(e2)==REGISTER) {
-	crn=register_name(creg);
+	crn=register_name(reg);
 	xrn=register_name(cadr(e2));
 	printf("\tlbzu %s,%d(%s)\n",crn,caddr(e1),xrn);
 	printf("\textsb %s,%s\n",crn,crn);
+	regv[reg]=1;
 	return;
     } 
     g_expr(e2);
@@ -767,7 +787,7 @@
 
 
 void
-code_return() {
+code_return(int creg) {
     char *crn = register_name(creg);
     printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,retcont,code_base);
     printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn);
@@ -775,13 +795,13 @@
 
 
 void
-code_environment() {
+code_environment(int creg) {
     printf("\tmr %s,r1\n",register_name(creg));
 }
 
 
 void
-code_bool(int e1) {
+code_bool(int e1,int creg) {
     char *xrn;
     int e2,e3;
     b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
@@ -825,6 +845,7 @@
     r = get_ptr_cache((char *)caddr(e1));
     printf("\tlbz %s,(%s)\n",crn,register_name(r));
     printf("\tcmpwi cr0,%s,0\n",crn);
+    regv[creg]=0;
 }
 
 
@@ -832,7 +853,8 @@
 code_cmp_crlvar(int e1) {
     char *crn = register_name(creg);
     printf("\tlbz %s,%d(r1)\n",crn,e1);
-    printf("\tcmpwi cr0,%s,0\n",crn);
+    code_cmp_register(creg);
+    regv[creg]=0;
 }
 
 
@@ -843,6 +865,7 @@
     r = get_ptr_cache((char *)caddr(e1));
     printf("\tlwz %s,(%s)\n",crn,register_name(r));
     code_cmp_register(creg);
+    regv[creg]=0;
 }
 
 
@@ -851,6 +874,7 @@
     char *crn = register_name(creg);
     printf("\tlwz %s,%d(r1)\n",crn,e1);
     code_cmp_register(creg);
+    regv[creg]=0;
 }
 
 
@@ -879,7 +903,7 @@
 }
 
 void
-string(int e1)
+code_string(int e1,int creg)
 {
     char *s,*crn;
     int lb;
@@ -1090,6 +1114,8 @@
     ret_type = cadddr(e1);
     void code_save_stacks();
     /* now all input register vars are free */
+    set_creg(CREG_REGISTER,0);
+    set_freg(FREG_FREGISTER,0);
     e2 = cadr(e1);
     reg_arg_list = nargs = reg_arg = freg_arg = arg_assign = 0;
     for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
@@ -1105,8 +1131,8 @@
 		    arg_assign);
 	    } else {
 		arg = get_input_register_var(reg_arg,0); 
-		use_var(arg); /* protect from input register free */
 	    }
+	    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++;
@@ -1121,8 +1147,8 @@
 		    arg_assign);
 	    } else {
 		arg = get_input_fregister_var(freg_arg,0); 
-		use_var(arg); /* protect from input register free */
 	    }
+	    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));
 	    freg_arg++;
@@ -1583,21 +1609,20 @@
 
 
 void
-code_set_fixed_creg(int mode) {
+code_set_return_register(int mode) {
     if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
-	if(freg!=RET_FREGISTER) {
-	    printf("\tfmr %s,%s\n",fregister_name(RET_FREGISTER),
-		fregister_name(RET_FREGISTER));
-	}
+	set_freg(RET_FREGISTER,mode);
     } else {
-	if(freg!=RET_FREGISTER) {
-	    printf("\tmr %s,%s\n",register_name(RET_REGISTER),
-		fregister_name(RET_REGISTER));
-	}
+	set_creg(RET_REGISTER,mode);
     }
 }
 
 void
+code_set_fixed_creg(int mode) {
+    set_creg(RET_REGISTER,mode);
+}
+
+void
 gen_gdecl(char *n, int gpc)
 {
     /*
@@ -1850,14 +1875,16 @@
     printf("\tfls %s,(%s)\n",grn,rrn);
     printf("\tfcmpu cr0,%s,%s\n",grn,frn);
     free_fregister(greg);
+    fregv[freg]=0;
     return;
 }
 
 void
-code_fregister(int e2)
+code_fregister(int e2,int freg)
 {
     if (freg!=e2)
 	printf("\tfmr %s,%s\n",register_name(freg),register_name(e2));
+    fregv[freg]=1;
 }
 
 void code_dassign_gvar(int e2,int freg,int d)
@@ -1865,16 +1892,19 @@
     int r;
     r = get_ptr_cache((char*)caddr(e2));
     printf("\t%s %s,(%s)\n",fstore(d),fregister_name(freg),register_name(r));
+    fregv[freg]=1;
 }
 
 void code_dassign_lvar(int e2,int freg,int d)
 { 
     printf("\t%s %s,%d(r1)\n",fstore(d),fregister_name(freg),e2);
+    fregv[freg]=1;
 }
 
 void code_dassign(int e2,int freg,int d)
 { 
     printf("\t%s %s,(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
+    fregv[freg]=1;
 }
 
 static double d0 = 1.0;
@@ -1893,7 +1923,7 @@
     return (i[1] == 0x3ff00000)?j[1]:j[0];
 }
 
-void code_dconst(int e2)
+void code_dconst(int e2,int freg)
 { 
     int lb;
     double d = dcadr(e2);
@@ -1928,15 +1958,16 @@
     printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn);
     printf("\tlfd %s,(%s)\n",frn,rrn);
     free_register(r);
+    fregv[freg]=1;
 }
 
-void code_dneg()
+void code_dneg(int freg)
 { 
     char *frn = fregister_name(freg);
     printf("\tfneg %s,%s\n",frn,frn);
 }
 
-void code_d2i()
+void code_d2i(int freg,int creg)
 { 
     char *frn = fregister_name(freg);
     char *crn = register_name(creg);
@@ -1976,7 +2007,7 @@
 0
 };
 
-void code_i2d()
+void code_i2d(int creg,int freg)
 { 
     i2d_lib_used = 1;
     set_creg(RET_REGISTER,1);
@@ -2022,7 +2053,7 @@
 0
 };
 
-void code_d2u()
+void code_d2u(int freg,int creg)
 { 
     d2u_lib_used=1;
     set_freg(RET_FREGISTER,1);
@@ -2059,7 +2090,7 @@
 0
 };
 
-void code_u2d()
+void code_u2d(int creg,int freg)
 { 
     u2d_lib_used = 1;
     char *frn = fregister_name(freg);
@@ -2071,17 +2102,19 @@
     regs[creg]=0;
 }
 
-void code_drgvar(int e2,int d)
+void code_drgvar(int e2,int d,int freg)
 { 
     int r;
     r = get_ptr_cache((char*)caddr(e2));
     printf("\t%s %s,(%s)\n",fload(d),fregister_name(freg),register_name(r));
+    fregv[freg]=1;
 }
 
 
-void code_drlvar(int e2,int d)
+void code_drlvar(int e2,int d,int freg)
 { 
     printf("\t%s %s,%d(r1)\n",fload(d),fregister_name(freg),e2);
+    fregv[freg]=1;
 }
 
 void code_cmp_drgvar(int e2)
@@ -2094,6 +2127,7 @@
     printf("\t%s %s,(%s)\n",fload(1),grn,register_name(r));
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
     free_fregister(g);
+    fregv[freg]=0;
 }
 
 void code_cmp_drlvar(int e2)
@@ -2105,6 +2139,7 @@
     printf("\t%s %s,%d(r1)\n",fload(1),grn,e2);
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
     free_fregister(g);
+    fregv[freg]=0;
 }
 
 void dtosop(int op,int e1)
@@ -2112,6 +2147,7 @@
     char *opn;
     char *frn=fregister_name(freg);
     char *grn=fregister_name(e1);
+    fregv[freg]=1;
     switch(op) {
     case DADD: opn="fadd"; break;
     case DSUB: opn="fsub"; break;
@@ -2141,11 +2177,12 @@
     dtosop(op,xreg);
     printf("\t%s %s,(%s)\n",fstore(d),frn,crn);
     emit_dpop_free(xreg);
+    fregv[freg]=1;
 }
 
 
 void
-code_dpreinc(int e1,int e2,int d) {
+code_dpreinc(int e1,int e2,int d,int reg) {
     char *frn;
     char *crn;
     int  g;
@@ -2169,10 +2206,11 @@
 	printf("\tfsub %s,%s,%s\n",frn,frn,grn);
     printf("\t%s %s,(%s)\n",fstore(d),frn,crn);
     free_fregister(g);
+    fregv[freg]=1;
 }
 
 void
-code_dpostinc(int e1,int e2,int d) {
+code_dpostinc(int e1,int e2,int d,int reg) {
     char *frn;
     char *crn;
     int  g;
@@ -2196,6 +2234,7 @@
 	printf("\tfsub %s,%s,%s\n",grn,frn,grn);
     printf("\t%s %s,(%s)\n",fstore(d),grn,crn);
     free_fregister(g);
+    fregv[freg]=1;
 }
 
 void
@@ -2225,7 +2264,7 @@
     xreg=pop_fregister();
     if (xreg<= -REG_LVAR_OFFSET) {
 	xreg = get_fregister();
-        code_drlvar(lvar(REG_LVAR_OFFSET+xreg),1);
+        code_drlvar(lvar(REG_LVAR_OFFSET+xreg),1,freg);
 	fregv[xreg]=1;
     }
     return xreg;
--- a/mc-code.h	Tue Mar 18 11:00:04 2003 +0900
+++ b/mc-code.h	Tue Mar 18 12:41:32 2003 +0900
@@ -26,33 +26,32 @@
 extern int get_fregister_var(NMTBL *n);
 extern int get_input_register_var(int,NMTBL *);
 extern int get_input_fregister_var(int,NMTBL *);
-extern void emit_push(void);
-extern void emit_push_x(int xreg);
+extern void emit_push();
 extern int emit_pop(int type);
 extern void gexpr_code_init();
 extern int  code_csvalue();
 extern void code_cmpdimm(int e, int csreg);
-extern void code_gvar(int e1);
-extern void code_rgvar(int e1);
-extern void code_crgvar(int e1);
-extern void code_lvar(int e2);
-extern void code_register(int e2);
+extern void code_gvar(int e1,int reg);
+extern void code_rgvar(int e1,int reg);
+extern void code_crgvar(int e1,int reg);
+extern void code_lvar(int e2,int reg);
+extern void code_register(int e2,int reg);
 extern void code_rlvar(int e2,int reg);
 extern void code_crlvar(int e2,int reg);
-extern void code_fname(char *e2);
-extern void code_const(int e2);
-extern void code_neg();
-extern void code_not();
-extern void code_lnot();
-extern void code_preinc(int e1,int e2);
-extern void code_postinc(int e1,int e2);
-extern void code_cpostinc(int e1,int e2);
-extern void code_cpreinc(int e1,int e2);
-extern void code_cpostdec(int e1,int e2);
-extern void code_cpredec(int e1,int e2);
-extern void code_return();
-extern void code_environment();
-extern void code_bool(int e1);
+extern void code_fname(char *e2,int reg);
+extern void code_const(int e2,int reg);
+extern void code_neg(int reg);
+extern void code_not(int reg);
+extern void code_lnot(int reg);
+extern void code_preinc(int e1,int e2,int reg);
+extern void code_postinc(int e1,int e2,int reg);
+extern void code_cpostinc(int e1,int e2,int reg);
+extern void code_cpreinc(int e1,int e2,int reg);
+extern void code_cpostdec(int e1,int e2,int reg);
+extern void code_cpredec(int e1,int e2,int reg);
+extern void code_return(int reg);
+extern void code_environment(int reg);
+extern void code_bool(int e1,int reg);
 extern char *code_gt(int cond);
 extern char *code_ugt(int cond);
 extern char *code_ge(int cond);
@@ -63,7 +62,7 @@
 extern void code_cmp_rgvar(int e1);
 extern void code_cmp_rlvar(int e1);
 extern void code_cmp_register(int e2);
-extern void string(int e1);
+extern void code_string(int e1,int reg);
 extern void emit_copy(int from,int  to,int length,int offset,int value,int det);
 extern int function(int e1);
 extern void code_frame_pointer(int e3);
@@ -85,6 +84,7 @@
 extern void jcond(int l, char cond);
 extern void jmp(int l);
 extern void code_set_fixed_creg(int mode);
+extern void code_set_return_register(int mode);
 extern void text_mode(void);
 extern void global_table(void);
 extern int lvar(int l);
@@ -95,27 +95,27 @@
 
 extern int dpop_register();
 extern int emit_dpop(int);
-extern void code_fregister(int e2);
+extern void code_fregister(int e2,int reg);
 extern void code_cmp_fregister(int);
 extern void code_cmp_drgvar(int);
 extern void code_cmp_drlvar(int);
 extern void code_dassign(int,int,int);
 extern void code_dassign_gvar(int,int,int);
 extern void code_dassign_lvar(int,int,int);
-extern void code_dconst(int);
-extern void code_dneg();
-extern void code_drgvar(int,int);
-extern void code_drlvar(int,int);
+extern void code_dconst(int,int);
+extern void code_dneg(int);
+extern void code_drgvar(int,int,int);
+extern void code_drlvar(int,int,int);
 extern void dtosop(int,int);
 extern void emit_dpop_free(int);
 extern void emit_dpush();
-extern void code_i2d();
-extern void code_d2i();
-extern void code_u2d();
-extern void code_d2u();
+extern void code_i2d(int,int);
+extern void code_d2i(int,int);
+extern void code_u2d(int,int);
+extern void code_d2u(int,int);
 
-extern void code_dpreinc(int e1,int e2,int d);
-extern void code_dpostinc(int e1,int e2,int d);
+extern void code_dpreinc(int e1,int e2,int d,int reg);
+extern void code_dpostinc(int e1,int e2,int d,int reg);
 extern void code_dassop(int op,int d);
 
 extern void code_arg_register(int);
--- a/mc-codegen.c	Tue Mar 18 11:00:04 2003 +0900
+++ b/mc-codegen.c	Tue Mar 18 12:41:32 2003 +0900
@@ -86,76 +86,55 @@
     e2 = cadr(e1);
     switch (car(e1)){
     case GVAR:   
-	code_gvar(e1);
-	regv[creg]=1;
+	code_gvar(e1,creg);
 	return ADDRESS;
     case RGVAR:
-	code_rgvar(e1);
-	regv[creg]=1;
+	code_rgvar(e1,creg);
 	return INT;
     case CRGVAR:
-	code_crgvar(e1);
-	regv[creg]=1;
+	code_crgvar(e1,creg);
 	return CHAR;
     case LVAR:
-	code_lvar(lvar(e2));
-	regv[creg]=1;
+	code_lvar(lvar(e2),creg);
 	return ADDRESS;
     case REGISTER:
-	/* this is of course redundant... */
-	/* or why not creg=e2? */
-	code_register(e2);
-	regv[creg]=1;
+	code_register(e2,creg);
 	return INT;
     case DREGISTER:
-	/* this is of course redundant... */
-	/* or why not creg=e2? */
-	code_fregister(e2);
-	fregv[freg]=1;
+	code_fregister(e2,freg);
 	return DOUBLE;
     case RLVAR:
 	code_rlvar(lvar(e2),creg);
-	regv[creg]=1;
 	return INT;
     case CRLVAR:
 	code_crlvar(lvar(e2),creg);
-	regv[creg]=1;
 	return CHAR;
     case FRLVAR:
-	code_drlvar(lvar(e2),0);
-	fregv[freg]=1;
+	code_drlvar(lvar(e2),0,freg);
 	return FLOAT;
     case FRGVAR:
-	code_drgvar(e1,0);
-	fregv[freg]=1;
+	code_drgvar(e1,0,freg);
 	return FLOAT;
     case DRLVAR:
-	code_drlvar(lvar(e2),1);
-	fregv[freg]=1;
+	code_drlvar(lvar(e2),1,freg);
 	return DOUBLE;
     case DRGVAR:
-	code_drgvar(e1,1);
-	fregv[freg]=1;
+	code_drgvar(e1,1,freg);
 	return DOUBLE;
     case FNAME:
-	code_fname(((NMTBL *)(e2))->nm);
-	regv[creg]=1;
+	code_fname(((NMTBL *)(e2))->nm,creg);
 	return ADDRESS;
     case CONST:  /* 代入する値が0でも特別な処理はしない */
-	code_const(e2);
-	regv[creg]=1;
+	code_const(e2,creg);
 	return INT;
     case DCONST:
-	code_dconst(e1);
-	fregv[freg]=1;
+	code_dconst(e1,freg);
 	return DOUBLE;
     case STRING:
-	string(e1);
-	regv[creg]=1;
+	code_string(e1,creg);
 	return ADDRESS;
     case FUNCTION:
 	t = function(e1);
-	regv[creg]=1;
 	return t;
     case CODE:
 	jump(e2,caddr(e1));
@@ -171,59 +150,59 @@
 	else
 	    return g_expr0(e2);
     case MINUS:  /* レジスタに対し、neglを実行すれば実現可能 */
-	g_expr0(e2); code_neg();
+	g_expr0(e2); code_neg(creg);
 	return INT;
     case DMINUS: 
-	g_expr0(e2); code_dneg();
+	g_expr0(e2); code_dneg(freg);
 	return DOUBLE;
     case I2D: 
-	g_expr0(e2); code_i2d();
+	g_expr0(e2); code_i2d(creg,freg);
 	return DOUBLE;
     case D2I: 
-	g_expr0(e2); code_d2i();
+	g_expr0(e2); code_d2i(freg,creg);
 	return INT;
     case U2D: 
-	g_expr0(e2); code_u2d();
+	g_expr0(e2); code_u2d(creg,freg);
 	return DOUBLE;
     case D2U: 
-	g_expr0(e2); code_d2u();
+	g_expr0(e2); code_d2u(freg,creg);
 	return UNSIGNED;
     case BNOT:   /* ~ */
-	g_expr0(e2); code_not();
+	g_expr0(e2); code_not(creg);
 	return INT;
     case LNOT:   /* !  */
-	g_expr0(e2); code_lnot();
+	g_expr0(e2); code_lnot(creg);
 	return INT;
     case PREINC:
-	code_preinc(e1,e2);
+	code_preinc(e1,e2,creg);
 	return INT;
     case POSTINC:
-	code_postinc(e1,e2);
+	code_postinc(e1,e2,creg);
 	return INT;
     case DPREINC:
-	code_dpreinc(e1,e2,1);
+	code_dpreinc(e1,e2,1,freg);
 	return DOUBLE;
     case DPOSTINC:
-	code_dpostinc(e1,e2,1);
+	code_dpostinc(e1,e2,1,freg);
 	return DOUBLE;
     case FPREINC:
-	code_dpreinc(e1,e2,0);
+	code_dpreinc(e1,e2,0,freg);
 	return FLOAT;
     case FPOSTINC:
-	code_dpostinc(e1,e2,0);
+	code_dpostinc(e1,e2,0,freg);
 	return FLOAT;
     case CPOSTINC:
 	/*   char *p; *p++ */
-	code_cpostinc(e1,e2);
+	code_cpostinc(e1,e2,creg);
 	return CHAR;
     case CPREINC:
-	code_cpreinc(e1,e2);
+	code_cpreinc(e1,e2,creg);
 	return CHAR;
     case CPOSTDEC:
-	code_cpostdec(e1,e2);
+	code_cpostdec(e1,e2,creg);
 	return CHAR;
     case CPREDEC:
-	code_cpredec(e1,e2);
+	code_cpredec(e1,e2,creg);
 	return CHAR;
     case MUL: case UMUL:
     case DIV: case UDIV:	   
@@ -276,15 +255,12 @@
 	if (retcont==0)
 	    retcont=fwdlabel();
 	code_return(creg);
-	regv[creg]=1;
 	return VOID;
     case ENVIRONMENT:
 	code_environment(creg);
-	regv[creg]=1;
 	return ADDRESS;
     default:
-	code_bool(e1); /* type? */
-	regv[creg]=1;
+	code_bool(e1,creg); /* type? */
 	return INT;
     }
 }
@@ -1092,7 +1068,7 @@
 void
 ret(void)
 {       
-    code_set_fixed_creg(1);
+    code_set_return_register(1);
     jmp(retlabel); 
 }