changeset 147:cb7aa0089681 creg-ireg-freg

creg/ireg done for powerpc.
author kono
date Wed, 11 Jun 2003 12:26:03 +0900
parents af841e8d739d
children e0eba2993c37
files .gdbinit Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c
diffstat 8 files changed, 295 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Fri May 23 13:55:40 2003 +0900
+++ b/.gdbinit	Wed Jun 11 12:26:03 2003 +0900
@@ -1,5 +1,5 @@
 tb main
-r -s test/basic.c
+run  -s -ob00.s mc-parse.c
 define regs 
 printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4
 printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
--- a/Changes	Fri May 23 13:55:40 2003 +0900
+++ b/Changes	Wed Jun 11 12:26:03 2003 +0900
@@ -3038,3 +3038,49 @@
 みたいな時にまずい。これは、どうするんだっけ?
 
 LMACRO ってのがあったみたいね。
+
+Sun May 25 21:48:46 JST 2003
+
+macro_eval がまだおかしいのは置いといて...
+
+単純にcreg/fregを統一してしまうと、
+     fdecl で creg をセット
+した時に、float/double/int にどれかに固定される。そのまま、
+coce_rlvar(creg) とかを呼ばれてしまうので、ちょっと困る。
+code_rlvar で、if(!is_int_reg(creg)) creg = ireg;
+とかすればいいんだけど、それは、ちょっと変だよね?
+
+そもそも、mc-codgen.c でcregを持ち歩いている理由は?
+なんかあったような気がするが...
+
+そうか、
+   use_int_reg()
+とかしてやれば良いわけね。(rname を使うかどうかはともかく)
+
+code_rlvar とかで設定するregisterを勝手に変えられると
+うれしくない。(よね?) codegen 側で use_int_reg()とか
+できればいいんじゃないの?
+
+Mon May 26 21:06:14 JST 2003
+
+code_* 側でやるか、mc-codegen 側で行うか? どっちかなぁ。
+code_* 側の方が良いような気もするけど。
+
+Thu May 29 10:30:09 JST 2003
+
+freg/creg の区別は mc-codegen 側でやっていたんだから、
+mc-codegen 側でやらないと、mc-cdoe-* 側での動的
+チェックが増えすぎてしまう。
+
+creg/freg を共有するのは良いのだが、その設定は
+mc-codegen 側ですべきなんじゃないの?
+
+mc-code-* 側を修正するとバグが取り切れない...
+(といいつつ、もう、すぐなんだろうけど... でも、なぁ)
+
+cast を自分で定義できる言語なら簡単なんだろうけど。
+
+Tue Jun  3 13:03:41 JST 2003
+
+あぁ、なんか乗り切れない。CONV の直前でcregが不定だ。
+どっかで use_float を忘れているんだろうな。
--- a/mc-code-ia32.c	Fri May 23 13:55:40 2003 +0900
+++ b/mc-code-ia32.c	Wed Jun 11 12:26:03 2003 +0900
@@ -192,6 +192,10 @@
     }
 }
 
+int use_int(int i) { return i;}
+int use_float(int i) { return i;}
+int use_double(int i) { return i;}
+
 void
 gexpr_code_init(void){
     use_register(creg,REG_EAX,0);
@@ -199,6 +203,10 @@
     regv[dreg]=0;
 }
 
+void
+code_gexpr(int e){
+}
+
 int
 register_var(int r) {
     return virtual(r+REG_ESI);
@@ -247,11 +255,6 @@
     return -1;
 }
 
-void 
-free_dregister(int i) {
-    error(-1);
-}
-
 int
 register_full(void)
 {
@@ -1739,7 +1742,7 @@
     printf("\tfchs\n");
 }
 
-void code_d2i(int freg,int creg)
+void code_d2i(int freg)
 { 
     printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
     printf("\tfnstcw  (%%esp)\n");
@@ -1753,14 +1756,14 @@
     printf("\tpopl    %s\n",register_name(creg,0));
 }
 
-void code_i2d(int creg,int freg)
+void code_i2d(int creg)
 { 
     printf("\tpushl %s\n",register_name(creg,0));
     printf("\tfildl (%%esp)\n");
     printf("\tlea %d(%%esp),%%esp\n",size_of_int);
 }
 
-void code_d2u(int freg,int creg)
+void code_d2u(int freg)
 { 
     printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3);
     printf("\tfnstcw  (%%esp)\n");
@@ -1774,7 +1777,7 @@
     printf("\tlea %d(%%esp),%%esp\n",size_of_int*3);
 }
 
-void code_u2d(int creg,int freg)
+void code_u2d(int creg)
 { 
     printf("\tpushl  %s\n",register_name(creg,0));
     printf("\tpushl  %s\n",register_name(creg,0));
@@ -1785,10 +1788,10 @@
 
 void code_d2f(int freg) { }
 void code_f2d(int freg) { }
-void code_f2i(int freg,int creg) { code_d2i(freg,creg); }
-void code_f2u(int freg,int creg) { code_d2u(freg,creg); }
-void code_i2f(int creg,int freg) { code_i2d(creg,freg); }
-void code_u2f(int creg,int freg) { code_u2d(creg,freg); }
+void code_f2i(int freg) { code_d2i(freg); }
+void code_f2u(int freg) { code_d2u(freg); }
+void code_i2f(int creg) { code_i2d(creg); }
+void code_u2f(int creg) { code_u2d(creg); }
 
 void code_drgvar(int e2,int d,int freg)
 { 
--- a/mc-code-powerpc.c	Fri May 23 13:55:40 2003 +0900
+++ b/mc-code-powerpc.c	Wed Jun 11 12:26:03 2003 +0900
@@ -28,6 +28,8 @@
 static int reg_save;
 static int freg_save;
 
+static int freg,ireg;
+
 int size_of_int = 4;
 int size_of_float = 4;
 int size_of_double = 8;
@@ -99,6 +101,28 @@
 #define register_name(i)  reg_name[i]
 #define fregister_name(i) reg_name[i]
 
+#define is_int_reg(i)  (0<=i&&i<REAL_MAX_REGISTER)
+#define is_float_reg(i)  (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER)
+
+
+int use_int(int i) { 
+    if (!is_int_reg(i)) i = ireg;
+    if (!regs[i]) regs[i]=1;
+    return i;
+}
+
+int use_float(int i) { 
+    if (!is_float_reg(i)) i = freg;
+    if (!regs[i]) regs[i]=1;
+    return i;
+}
+
+int use_double(int i) { 
+    if (!is_float_reg(i)) i = freg;
+    if (!regs[i]) regs[i]=1;
+    return i;
+}
+
 static
 NMTBL float_zero = {"_float_zero",STATIC,FLOAT,0};
 static
@@ -279,6 +303,11 @@
     regv[freg]=0;
 }
 
+void
+code_gexpr(int e){
+    if (is_int_reg(creg) && creg!=ireg) error(-1);
+}
+
 
 void
 code_arg_register(NMTBL *fnptr)
@@ -421,13 +450,7 @@
 
 void 
 free_register(int i) {    /* いらなくなったレジスタを開放 */
-    if (i<0||MAX_REGISTER<i) error(-1);
-    regv[i]=regs[i]=0;
-}
-
-void 
-free_dregister(int i) {    /* いらなくなったレジスタを開放 */
-    if (i<FREG_OFFSET||MAX_FREGISTER+FREG_OFFSET<i) error(-1);
+    if (i<0||MAX_FREGISTER+FREG_OFFSET<i) error(-1);
     regv[i]=regs[i]=0;
 }
 
@@ -544,8 +567,8 @@
 	free_register(reg_stack[--reg_sp]);
     }
     if (cond_freg!=-1) { 
-	if(car(cond_freg)==DREGISTER) free_dregister(cadr(cond_freg)); 
-	else if(car(cond_freg)==FREGISTER) free_dregister(cadr(cond_freg)); 
+	if(car(cond_freg)==DREGISTER) free_register(cadr(cond_freg)); 
+	else if(car(cond_freg)==FREGISTER) free_register(cadr(cond_freg)); 
 	cond_freg=-1; 
     }
     if (cond_reg!=-1)  { 
@@ -619,7 +642,7 @@
     if (reg_sp>MAX_MAX) error(-1);
     new_reg = get_register();
     reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
-    creg = new_reg;
+    ireg = creg = new_reg;
     regv[creg]=1;
 }
 
@@ -633,7 +656,7 @@
         code_rlvar(REG_LVAR_OFFSET+xreg,reg);
 	free_lvar(REG_LVAR_OFFSET+xreg);
 	xreg = reg;
-	regv[xreg]=1;
+	regv[creg]=1;
     }
     return xreg;
 }
@@ -745,6 +768,7 @@
 
 void
 code_rgvar(int e1,int creg) {
+    if (!is_int_reg(creg)) error(-1);
     printf("\tlwz %s,0(%s)\n",register_name(creg),
                              register_name(get_ptr_cache((NMTBL*)cadr(e1))));
     regv[creg]=1;
@@ -771,6 +795,7 @@
 void
 code_rlvar(int e2,int reg) {
     lvar_intro(e2);
+    if (!is_int_reg(reg)) error(-1);
     printf("\tlwz %s,",register_name(reg));
     lvar(e2);
     regv[creg]=1;
@@ -783,7 +808,7 @@
     printf("\tlbz %s,",register_name(reg));
     lvar(e2);
     printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
-    regv[reg]=1;
+    regv[creg]=1;
 }
 
 
@@ -850,7 +875,7 @@
     printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1));
     printf("\tstw %s,0(%s)\n",drn,xrn);
     i=creg;creg=dreg;dreg=i;
-    regv[creg]=1;
+    regv[creg]=1; ireg=creg;
     free_register(dreg);
 }
 
@@ -878,7 +903,7 @@
     i=creg;creg=dreg;dreg=i; 
     free_register(nreg);
     free_register(dreg);
-    regv[creg]=1;
+    regv[creg]=1; ireg=creg;
 }
 
 
@@ -908,7 +933,7 @@
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
     free_register(dreg);
-    regv[creg]=1;
+    regv[creg]=1; ireg=creg;
 }
 
 
@@ -935,7 +960,7 @@
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
     free_register(dreg);
-    regv[creg]=1;
+    regv[creg]=1; ireg=creg;
 }
 
 
@@ -966,7 +991,7 @@
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
     free_register(dreg);
-    regv[creg]=1;
+    regv[creg]=1; ireg=creg;
 }
 
 
@@ -995,7 +1020,7 @@
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
     free_register(dreg);
-    regv[creg]=1;
+    regv[creg]=1; ireg=creg;
 }
 
 
@@ -1025,6 +1050,7 @@
     char *xrn;
     int e2,e3;
     b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
+    creg = use_int(creg);
     xrn = register_name(creg);
     printf("\tli %s,0\n",xrn);
     jmp(e3=fwdlabel());
@@ -1084,6 +1110,7 @@
 code_cmp_rgvar(int e1) {
     int r;
     char *crn = register_name(creg);
+    if (!is_int_reg(creg)) error(-1);
     r = get_ptr_cache((NMTBL*)cadr(e1));
     printf("\tlwz %s,0(%s)\n",crn,register_name(r));
     code_cmp_register(creg);
@@ -1264,10 +1291,10 @@
 {
     if (reg!=creg) {
 	clear_ptr_cache_reg(reg);
-	if (mode) 
-	    printf("\tmr %s,%s\n",register_name(reg),register_name(creg));
+	if (reg!=ireg && mode) 
+	    printf("\tmr %s,%s\n",register_name(reg),register_name(ireg));
 	free_register(creg);
-	creg = reg;
+	creg = ireg = reg;
 	regs[creg]=1;
     }
 }
@@ -1275,11 +1302,12 @@
 void
 set_freg(int reg,int mode)
 {
-    if (reg!=freg) {
-	if (mode) 
+    if (reg!=creg) {
+	if (reg!=freg && mode) {
 	    printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg));
-	free_dregister(freg);
-	freg = reg;
+	}
+	free_register(creg);
+	creg = freg = reg;
 	regs[freg]=1;
     }
 }
@@ -1331,12 +1359,8 @@
 	n->sc  = LVAR;
 	lvar = list2(LVAR,n->dsp);
 	g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t));
-	if (tag==REGISTER) {
+	if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) {
 	    free_register(reg);
-	} else if (tag==DREGISTER) {
-	    free_dregister(reg);
-	} else if (tag==FREGISTER) {
-	    free_dregister(reg);
 	}
     }
     my_func_args = offset;
@@ -1506,9 +1530,8 @@
     }
     for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {
 	arg = car(reg_arg_list);
-	if (car(arg)==DREGISTER) free_dregister(cadr(arg));
-	else if (car(arg)==FREGISTER) free_dregister(cadr(arg));
-	else if (car(arg)==REGISTER) free_register(cadr(arg));
+	if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER) 
+	    free_register(cadr(arg));
 	else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg));
     }
     if (ret_type==DOUBLE||ret_type==FLOAT) {
@@ -1578,6 +1601,7 @@
 	printf("\t%s %s,%d(%s)\n",fload(car(e1)==DRINDIRECT),
 	    fregister_name(freg),offset,crn);
 	regv[creg]=0; regv[freg]=1;
+	creg = freg;
 	return DOUBLE;
     case CRINDIRECT: 
 	printf("\tlbz %s,%d(%s)\n",crn,offset,crn);
@@ -1995,6 +2019,7 @@
 code_set_return_register(int mode) {
     if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) {
 	set_freg(RET_FREGISTER,mode);
+    } else if (cadr(fnptr->ty)==VOID) {
     } else {
 	set_creg(RET_REGISTER,mode);
     }
@@ -2287,15 +2312,17 @@
     rrn = register_name(r);
     printf("\tlfs %s,0(%s)\n",grn,rrn);
     printf("\tfcmpu cr0,%s,%s\n",grn,frn);
-    free_dregister(greg);
+    free_register(greg);
     return;
 }
 
 void
 code_dregister(int e2,int freg,int d)
 {
-    if (freg!=e2)
+    if (freg!=e2) {
+	if (is_int_reg(e2)) error(-1);
 	printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2));
+    }
     regv[freg]=1;
 }
 
@@ -2303,6 +2330,7 @@
 { 
     int r;
     r = get_ptr_cache((NMTBL*)cadr(e2));
+    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r));
     regv[freg]=1;
 }
@@ -2310,6 +2338,7 @@
 void code_dassign_lvar(int e2,int freg,int d)
 { 
     lvar_intro(e2);
+    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,",fstore(d),fregister_name(freg));
     lvar(e2);
     regv[freg]=1;
@@ -2317,14 +2346,17 @@
 
 void code_dassign(int e2,int freg,int d)
 { 
+    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
     regv[freg]=1;
 }
 
 void
 code_dassign_dregister(int e2,int d,int freg) {
-    if (e2!=freg)
+    if (e2!=freg) {
+	if (is_int_reg(freg)) error(-1);
 	printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg));
+    }
 }
 
 static double d0 = 1.0;
@@ -2402,22 +2434,29 @@
 void code_dneg(int freg,int d)
 { 
     char *frn = fregister_name(freg);
+    if (is_int_reg(freg)) error(-1);
     printf("\tfneg %s,%s\n",frn,frn);
 }
 
-void code_d2i(int freg,int creg)
+void code_d2i(int freg0)
 { 
-    char *frn = fregister_name(freg);
-    char *crn = register_name(creg);
+    char *frn;
+    char *crn;
     int e2 = new_lvar(size_of_double);
+
+    freg0 = use_double(freg0);
+    frn = fregister_name(freg0);
+    creg = use_int(creg);
+    crn = register_name(creg);
+
+    freg = freg0;
     free_lvar(e2);
     printf("\tfctiwz  %s,%s\n",frn,frn);
     lvar_intro(e2);
     printf("\tstfd  %s,",frn); lvar(e2);
     lvar_intro(e2+size_of_double-size_of_int);
     printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int);
-    regs[freg]=0;
-    regs[creg]=1;
+    regv[creg]=1;
 }
 
 static int i2d_lib_used=0;
@@ -2448,7 +2487,7 @@
 0
 };
 
-void code_i2d(int creg,int freg)
+void code_i2d(int creg0)
 { 
     i2d_lib_used = 1;
     clear_ptr_cache();
@@ -2456,8 +2495,7 @@
     set_creg(RET_REGISTER,1);
     printf("\tbl i2d_\n");
     set_freg(RET_FREGISTER,0);
-    regs[freg]=1;
-    regs[creg]=0;
+    regv[freg]=1;
 }
 
 static int d2u_lib_used=0;
@@ -2496,7 +2534,7 @@
 0
 };
 
-void code_d2u(int freg,int creg)
+void code_d2u(int freg0)
 { 
     code_save_stacks();
     clear_ptr_cache();
@@ -2504,8 +2542,7 @@
     set_freg(RET_FREGISTER,1);
     printf("\tbl d2u_\n");
     set_creg(RET_REGISTER,0);
-    regs[freg]=1;
-    regs[creg]=0;
+    regv[freg]=1;
 }
 
 static int u2d_lib_used=0;
@@ -2535,29 +2572,23 @@
 0
 };
 
-void code_u2d(int creg,int freg)
+void code_u2d(int creg0)
 { 
-    char *frn;
-    char *crn;
-    u2d_lib_used = 1;
     code_save_stacks();
     clear_ptr_cache();
-    frn = fregister_name(freg);
-    crn = register_name(creg);
-
-    printf("\tmr r3,%s\n",crn);
+    u2d_lib_used = 1;
+    set_creg(RET_REGISTER,1);
     printf("\tbl u2d_\n");
-    printf("\tfmr %s,f1\n",frn);
-    regs[freg]=1;
-    regs[creg]=0;
+    set_freg(FREG_FREGISTER,0);
+    regv[freg]=1;
 }
 
 void code_d2f(int freg) { }
 void code_f2d(int freg) { }
-void code_f2i(int freg,int creg) { code_d2i(freg,creg); }
-void code_f2u(int freg,int creg) { code_d2u(freg,creg); }
-void code_i2f(int creg,int freg) { code_i2d(creg,freg); }
-void code_u2f(int creg,int freg) { code_u2d(creg,freg); }
+void code_f2i(int freg) { code_d2i(freg); }
+void code_f2u(int freg) { code_d2u(freg); }
+void code_i2f(int creg) { code_i2d(creg); }
+void code_u2f(int creg) { code_u2d(creg); }
 
 void code_drgvar(int e2,int d,int freg)
 { 
@@ -2584,7 +2615,7 @@
     r = get_ptr_cache((NMTBL*)cadr(e2));
     printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r));
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
-    free_dregister(g);
+    free_register(g);
     regv[freg]=0;
 }
 
@@ -2597,7 +2628,7 @@
     lvar_intro(e2);
     printf("\t%s %s,",fload(1),grn); lvar(e2);
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
-    free_dregister(g);
+    free_register(g);
     regv[freg]=0;
 }
 
@@ -2619,19 +2650,19 @@
     case FCMP:
     case DCMP: 
 	printf("\tfcmpu cr0,%s,%s\n",frn,grn);
-	free_dregister(e1);
+	free_register(e1);
 	return;
     case FCMPGE: 
     case DCMPGE: 
 	printf("\tfcmpu cr7,%s,%s\n",frn,grn);
-	free_dregister(e1);
+	free_register(e1);
 	return;
     default:
 	error(-1); return;
     }
     printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
     regv[freg]=1;
-    free_dregister(e1);
+    free_register(e1);
 }
 
 void
@@ -2641,6 +2672,7 @@
     int  xreg=emit_dpop(d);
     char *crn=register_name(creg);
 
+    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
     dtosop(op,xreg);
     printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
@@ -2675,9 +2707,12 @@
 	printf("\tfadd %s,%s,%s\n",frn,frn,grn);
     else
 	printf("\tfsub %s,%s,%s\n",frn,frn,grn);
+    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
-    free_dregister(g);
+    free_register(g);
     regv[freg]=1;
+    regv[ireg]=0;
+    creg = freg;
 }
 
 void
@@ -2706,9 +2741,12 @@
 	printf("\tfadd %s,%s,%s\n",grn,frn,grn);
     else
 	printf("\tfsub %s,%s,%s\n",grn,frn,grn);
+    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,0(%s)\n",fstore(d),grn,crn);
-    free_dregister(g);
+    free_register(g);
     regv[freg]=1;
+    regv[ireg]=0;
+    creg = freg;
 }
 
 void
@@ -2751,7 +2789,7 @@
 
 void emit_dpop_free(int e1,int d)
 { 
-    free_dregister(e1);
+    free_register(e1);
 }
 
 void emit_dpush(int d)
@@ -2760,7 +2798,7 @@
     if (freg_sp>MAX_MAX) error(-1);
     new_reg = get_dregister(1);
     freg_stack[freg_sp++] = freg;     /* push するかわりにレジスタを使う */
-    freg = new_reg;
+    creg = freg = new_reg;
     regv[freg]=1;
 }
 
--- a/mc-code.h	Fri May 23 13:55:40 2003 +0900
+++ b/mc-code.h	Wed Jun 11 12:26:03 2003 +0900
@@ -34,6 +34,7 @@
 extern int emit_pop(int type);
 extern void gexpr_code_init();
 extern int  code_csvalue();
+extern void code_gexpr(int e);
 extern void code_cmpdimm(int e, int csreg);
 extern void code_gvar(int e1,int reg);
 extern void code_rgvar(int e1,int reg);
@@ -113,16 +114,16 @@
 extern void dtosop(int,int);
 extern void emit_dpop_free(int,int);
 extern void emit_dpush(int);
-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_i2d(int);
+extern void code_d2i(int);
+extern void code_u2d(int);
+extern void code_d2u(int);
 extern void code_d2f(int freg);
 extern void code_f2d(int freg);
-extern void code_f2i(int freg,int creg);
-extern void code_f2u(int freg,int creg);
-extern void code_i2f(int creg,int freg);
-extern void code_u2f(int creg,int freg);
+extern void code_f2i(int freg);
+extern void code_f2u(int freg);
+extern void code_i2f(int creg);
+extern void code_u2f(int creg);
 
 
 extern void code_dpreinc(int e1,int e2,int d,int reg);
@@ -134,9 +135,11 @@
 extern int get_register(void);
 extern int get_dregister(int);
 extern void free_register(int i) ;
-extern void free_dregister(int i) ;
 extern int pop_register(void);
 extern void emit_pop_free(int xreg);
 
+extern int use_int(int);
+extern int use_float(int);
+extern int use_double(int);
 
 /* */
--- a/mc-codegen.c	Fri May 23 13:55:40 2003 +0900
+++ b/mc-codegen.c	Wed Jun 11 12:26:03 2003 +0900
@@ -7,13 +7,11 @@
 #include "mc-code.h"
 
 int  creg;     /* current register */
-int  freg;     /* current floating point register */
 
 int use;       /* generated value will be used */
 
 /*
     creg   currrent virtual register
-    freg    current floating point register
  */
 
 static void remove0(int *parent,int e) ;
@@ -59,6 +57,8 @@
     int t;
     int suse = use; use=0;
     t=g_expr0(e1);
+    code_gexpr(e1);
+
     use=suse;
     return t;
 }
@@ -69,6 +69,8 @@
     int t;
     int suse = use; use=1;
     t=g_expr0(e1);
+    code_gexpr(e1);
+
     use=suse;
     return t;
 }
@@ -79,60 +81,80 @@
     int e2,e3,t,d;
     NMTBL *n;
 
+    code_gexpr(e1);
+
     e2 = cadr(e1);
     switch (car(e1)){
     case GVAR:   
+	creg=use_int(creg);
 	code_gvar(e1,creg);
 	return ADDRESS;
     case RGVAR:
+	creg=use_int(creg);
 	code_rgvar(e1,creg);
 	return INT;
     case CRGVAR:
+	creg=use_int(creg);
 	code_crgvar(e1,creg);
 	return CHAR;
     case LVAR:
+	creg=use_int(creg);
 	code_lvar(e2,creg);
 	return ADDRESS;
     case REGISTER:
+	creg=use_int(creg);
 	code_register(e2,creg);
 	return INT;
     case DREGISTER:
-	code_dregister(e2,freg,1);
+	creg=use_double(creg);
+	code_dregister(e2,creg,1);
 	return DOUBLE;
     case FREGISTER:
-	code_dregister(e2,freg,0);
+	creg=use_float(creg);
+	code_dregister(e2,creg,0);
 	return FLOAT;
     case RLVAR:
+	creg=use_int(creg);
 	code_rlvar(e2,creg);
 	return INT;
     case CRLVAR:
+	creg=use_int(creg);
 	code_crlvar(e2,creg);
 	return CHAR;
     case FRLVAR:
-	code_drlvar(e2,0,freg);
+	creg=use_float(creg);
+	code_drlvar(e2,0,creg);
 	return FLOAT;
     case FRGVAR:
-	code_drgvar(e1,0,freg);
+	creg=use_float(creg);
+	code_drgvar(e1,0,creg);
 	return FLOAT;
     case DRLVAR:
-	code_drlvar(e2,1,freg);
+	creg=use_double(creg);
+	code_drlvar(e2,1,creg);
 	return DOUBLE;
     case DRGVAR:
-	code_drgvar(e1,1,freg);
+	creg=use_double(creg);
+	code_drgvar(e1,1,creg);
 	return DOUBLE;
     case FNAME:
+	creg=use_int(creg);
 	code_fname((NMTBL *)(e2),creg);
 	return ADDRESS;
     case CONST:  /* 代入する値が0でも特別な処理はしない */
+	creg=use_int(creg);
 	code_const(e2,creg);
 	return INT;
     case DCONST:
-	code_dconst(e1,freg,1);
+	creg=use_double(creg);
+	code_dconst(e1,creg,1);
 	return DOUBLE;
     case FCONST:
-	code_dconst(e1,freg,0);
+	creg=use_float(creg);
+	code_dconst(e1,creg,0);
 	return FLOAT;
     case STRING:
+	creg=use_int(creg);
 	code_string(e1,creg);
 	return ADDRESS;
     case FUNCTION:
@@ -155,24 +177,24 @@
 	g_expr0(e2); code_neg(creg);
 	return INT;
     case DMINUS: 
-	g_expr0(e2); code_dneg(freg,1);
+	g_expr0(e2); code_dneg(creg,1);
 	return DOUBLE;
     case FMINUS: 
-	g_expr0(e2); code_dneg(freg,0);
+	g_expr0(e2); code_dneg(creg,0);
 	return FLOAT;
     case CONV: 
 	g_expr0(e2); 
 	switch(caddr(e1)) {
-	case I2D: code_i2d(creg,freg); return DOUBLE;
-	case D2I: code_d2i(freg,creg); return INT;
-	case U2D: code_u2d(creg,freg); return DOUBLE;
-	case F2U: code_f2u(freg,creg); return UNSIGNED;
-	case I2F: code_i2f(creg,freg); return FLOAT;
-	case F2I: code_f2i(freg,creg); return INT;
-	case U2F: code_u2f(creg,freg); return FLOAT;
-	case D2U: code_d2u(freg,creg); return UNSIGNED;
-	case D2F: code_d2f(freg); return FLOAT;
-	case F2D: code_f2d(freg); return DOUBLE;
+	case I2D: code_i2d(creg); return DOUBLE;
+	case D2I: code_d2i(creg); return INT;
+	case U2D: code_u2d(creg); return DOUBLE;
+	case F2U: code_f2u(creg); return UNSIGNED;
+	case I2F: code_i2f(creg); return FLOAT;
+	case F2I: code_f2i(creg); return INT;
+	case U2F: code_u2f(creg); return FLOAT;
+	case D2U: code_d2u(creg); return UNSIGNED;
+	case D2F: code_d2f(creg); return FLOAT;
+	case F2D: code_f2d(creg); return DOUBLE;
 	default:
 	    error(-1); return INT;
 	}
@@ -183,34 +205,44 @@
 	g_expr0(e2); code_lnot(creg);
 	return INT;
     case PREINC:
+	creg=use_int(creg);
 	code_preinc(e1,e2,creg);
 	return INT;
     case POSTINC:
+	creg=use_int(creg);
 	code_postinc(e1,e2,creg);
 	return INT;
-    case DPREINC:
-	code_dpreinc(e1,e2,1,freg);
+    case DPREINC:   /* ++d */
+	creg=use_double(creg);
+	code_dpreinc(e1,e2,1,creg);
 	return DOUBLE;
-    case DPOSTINC:
-	code_dpostinc(e1,e2,1,freg);
+    case DPOSTINC:  /* d++ */
+	creg=use_double(creg);
+	code_dpostinc(e1,e2,1,creg);
 	return DOUBLE;
-    case FPREINC:
-	code_dpreinc(e1,e2,0,freg);
+    case FPREINC:   /* ++f */
+	creg=use_float(creg);
+	code_dpreinc(e1,e2,0,creg);
 	return FLOAT;
-    case FPOSTINC:
-	code_dpostinc(e1,e2,0,freg);
+    case FPOSTINC:  /* f++ */
+	creg=use_float(creg);
+	code_dpostinc(e1,e2,0,creg);
 	return FLOAT;
     case CPOSTINC:
 	/*   char *p; *p++ */
+	creg=use_int(creg);
 	code_cpostinc(e1,e2,creg);
 	return CHAR;
     case CPREINC:
+	creg=use_int(creg);
 	code_cpreinc(e1,e2,creg);
 	return CHAR;
     case CPOSTDEC:
+	creg=use_int(creg);
 	code_cpostdec(e1,e2,creg);
 	return CHAR;
     case CPREDEC:
+	creg=use_int(creg);
 	code_cpredec(e1,e2,creg);
 	return CHAR;
     case MUL: case UMUL:
@@ -218,16 +250,19 @@
     case MOD: case UMOD:
     case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
     case ADD: case SUB: case BAND: case EOR: case BOR: case CMP:
+	creg=use_int(creg);
 	machinop(e1);
 	return INT;
     case DMUL: case DDIV:
     case DADD: case DSUB:
     case DCMP: case DCMPGE:
+	creg=use_double(creg);
 	dmachinop(e1,1);
 	return DOUBLE;
     case FMUL: case FDIV:
     case FADD: case FSUB:
     case FCMP: case FCMPGE:
+	creg=use_float(creg);
 	dmachinop(e1,0);
 	return FLOAT;
     case COND:
@@ -280,12 +315,14 @@
 	g_expr_u(e2);
 	return g_expr0(caddr(e1));
     case RETURN:
+	creg = use_int(creg);
 	n = (NMTBL *)e2;
 	if (retcont==0)
 	    retcont=fwdlabel();
 	code_return(creg);
 	return VOID;
     case ENVIRONMENT:
+	creg = use_int(creg);
 	code_environment(creg);
 	return ADDRESS;
     default:
@@ -428,46 +465,57 @@
 	if(!cond) fwddef(l2);
 	return;
     case CRGVAR:
+	creg=use_int(creg);
 	code_cmp_crgvar(e1);
 	jcond(l1,cond);
 	return;
     case CRLVAR:
+	creg=use_int(creg);
 	code_cmp_crlvar(e2);
 	jcond(l1,cond);
 	return;
     case RGVAR:
+	creg=use_int(creg);
 	code_cmp_rgvar(e1);
 	jcond(l1,cond);
 	return;
     case RLVAR:
+	creg=use_int(creg);
 	code_cmp_rlvar(e2);
 	jcond(l1,cond);
 	return;
     case DRLVAR:
+	creg=use_double(creg);
 	code_cmp_drlvar(e2,1);
 	jcond(l1,cond);
 	return;
     case FRLVAR:
+	creg=use_float(creg);
 	code_cmp_drlvar(e2,0);
 	jcond(l1,cond);
 	return;
     case DRGVAR:
+	creg=use_double(creg);
 	code_cmp_drgvar(e2,1);
 	jcond(l1,cond);
 	return;
     case FRGVAR:
+	creg=use_float(creg);
 	code_cmp_drgvar(e2,0);
 	jcond(l1,cond);
 	return;
     case REGISTER:
+	creg=use_int(creg);
 	code_cmp_register(e2);
 	jcond(l1,cond);
 	return;
     case FREGISTER:
+	creg=use_float(creg);
 	code_cmp_dregister(e2,0);
 	jcond(l1,cond);
 	return;
     case DREGISTER:
+	creg=use_double(creg);
 	code_cmp_dregister(e2,1);
 	jcond(l1,cond);
 	return;
@@ -484,9 +532,9 @@
 	}
 	t=g_expr(e1);
 	if(t==FLOAT)
-	    code_cmp_dregister(freg,0);
+	    code_cmp_dregister(creg,0);
 	else if(t==DOUBLE)
-	    code_cmp_dregister(freg,1);
+	    code_cmp_dregister(creg,1);
 	else
 	    code_cmp_register(creg);
 	jcond(l1,cond);
@@ -536,13 +584,8 @@
     n->sc  = LVAR;
     lvar = list2(LVAR,n->dsp);
     g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t));
-    if (tag==REGISTER) {
+    if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) {
 	free_register(reg);
-    } else if (tag==DREGISTER) {
-	free_dregister(reg);
-    } else if (tag==FREGISTER) {
-	free_dregister(reg);
-    }
     return g_expr0(lvar);
 #endif
 }
@@ -582,14 +625,12 @@
 remove_target(int *target,int t,int *use)
 {
     int use0=*use;
+    int reg;
     while(use0) {
 	if (car(use0)==t) {
-	    if (car(caddr(use0))==REGISTER)
+	    reg = car(caddr(use0));
+	    if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER)
 		free_register(cadr(caddr(use0)));
-	    else if (car(caddr(use0))==FREGISTER)
-		free_dregister(cadr(caddr(use0)));
-	    else if (car(caddr(use0))==DREGISTER)
-		free_dregister(cadr(caddr(use0)));
 	    break;
 	}
 	use0 = cadr(use0);
@@ -755,7 +796,7 @@
 jump(int e1, int env)
 {
     int e2,e3,e4,sz,arg_size,ty,regs,fregs;
-    int t0,s0,r;
+    int t0,s0,r,reg;
     NMTBL *code0 = 0;
     int target = 0;
     int source = 0;
@@ -845,12 +886,9 @@
     /* 並列代入を実行 */
     parallel_assign(&target,&source,&processing,&use);
     while (use) {
-	if (car(caddr(use))==REGISTER)
+	reg = car(caddr(use));
+	if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER)
 	    free_register(cadr(caddr(use)));
-	else if (car(caddr(use))==FREGISTER)
-	    free_dregister(cadr(caddr(use)));
-	else if (car(caddr(use))==DREGISTER)
-	    free_dregister(cadr(caddr(use)));
 	else if (car(caddr(use))==LVAR)
 	    free_lvar(cadr(caddr(use)));
 	use=cadr(use);
@@ -996,6 +1034,7 @@
 		e5== CONST ||  e5== FNAME || e5== STRING ||
 		(e5==ADDRESS&&car(cadr(e4))==STRING) ||
 		(e5==ADDRESS&&car(cadr(e4))==GVAR) )))) {
+	creg = use_int(creg);
 	assign_opt(e5,e2,e4,byte);
 	return;
     }
@@ -1045,9 +1084,6 @@
 	default:
 	    error(-1);
 	}
-	g_expr(e2);
-	code_dassign(e2,reg,d);
-	return;
     }
     /* e2 is register now */
     if (car(e2)!=DREGISTER && car(e2)!=FREGISTER) error(-1);
@@ -1079,30 +1115,33 @@
 	    (car(e2)==DREGISTER&&(e5==DRGVAR||e5==DRLVAR||e5==DCONST))||
 	    (car(e2)==DREGISTER&&(e5==FRGVAR||e5==FRLVAR||e5==FCONST))
 	)) {
+	creg = d?use_double(creg):use_float(creg);
 	dassign_opt(e5,e2,e4,d);
 	return;
     }
     switch(car(e2)) {
     case GVAR:
             g_expr(e4);
-	    code_dassign_gvar(e2,freg,d);
+	    code_dassign_gvar(e2,creg,d);
             return;
     case LVAR:
             g_expr(e4);
-	    code_dassign_lvar(cadr(e2),freg,d);
+	    code_dassign_lvar(cadr(e2),creg,d);
             return;
     case DREGISTER:
     case FREGISTER:
             g_expr(e4);
-	    if (freg!=cadr(e2))
-		code_dassign_dregister(cadr(e2),d,freg);
+	    if (creg!=cadr(e2)) {
+		if (d) creg = use_double(creg); else creg = use_float(creg);
+		code_dassign_dregister(cadr(e2),d,creg);
+	    }
             return;
     }
     g_expr(e2);
     emit_push();
     g_expr(e4);
     e2 = emit_pop(0);
-    code_dassign(e2,freg,d);
+    code_dassign(e2,creg,d);
     emit_pop_free(e2);
     return;
 }
@@ -1119,6 +1158,7 @@
     e3 = caddr(e1);
     op = cadddr(e1);
 
+    creg = use_int(creg);
     g_expr(e3);
     if (car(e2)==REGISTER) {
 	code_register_assop(cadr(e2),op,byte);
@@ -1142,6 +1182,7 @@
     e3 = caddr(e1);
     op = cadddr(e1);
 
+    creg = d?use_double(creg):use_float(creg);
     g_expr(e3);
     emit_dpush(d);
     g_expr(e2);
--- a/mc-codegen.h	Fri May 23 13:55:40 2003 +0900
+++ b/mc-codegen.h	Wed Jun 11 12:26:03 2003 +0900
@@ -1,7 +1,6 @@
 /* for mc-codegen.c */
 
 extern int  creg;       /* current register */
-extern int  freg;       /* current floating point register */
 
 extern int use;         /* generated value will be used in gexpr */
 
--- a/mc-parse.c	Fri May 23 13:55:40 2003 +0900
+++ b/mc-parse.c	Wed Jun 11 12:26:03 2003 +0900
@@ -1308,6 +1308,19 @@
     }
 }
 
+#if 0
+static void
+statement0(void);
+
+extern    void code_gexpr();
+static void
+statement(void)
+{
+    statement0();
+    code_gexpr();
+}
+#endif
+
 static void
 statement(void)
 {