changeset 104:c21aeb12b78b

*** empty log message ***
author kono
date Mon, 17 Mar 2003 20:57:01 +0900
parents f849af4b5ea9
children 7e3d59e56a53
files Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc.h
diffstat 8 files changed, 149 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Mon Mar 17 14:26:22 2003 +0900
+++ b/Changes	Mon Mar 17 20:57:01 2003 +0900
@@ -2226,3 +2226,27 @@
 ものと default extern の区別は、最終の時点でしか判別できない。
 できないよね。定義されてないものが default extern なんだから。
 ってことは、最後に、.set で定義するしかないか。(sigh...)
+
+Mon Mar 17 14:34:12 JST 2003
+
+えーと、input register に regv/regs をセットしないとだめ。
+関数呼び出しの引数を評価する前に save する必要がある。
+さらに、引数の評価の後に、save された変数を呼び出す必要が
+ある。(ってことは、いままでのは、まったくのでたらめか..)
+
+register 変数の場合は、問題ない。ってことは、ia32 側も
+変更してしまったので、おかしくなっているね。もっとも、
+code の場合は、そういうsaveとかは必要ないから良いのか。
+
+(11日目か...)
+
+    mr creg,hoge
+    mr hoge2,creg 
+
+とかは、g_expr_u で最適化するべし。set_freg/set_creg でレジ
+スタ変数に割り振ると、set_freg でfreeされてしまう。
+
+浮動小数点定数の共有はやった方が良い?
+
+input register のsaveを忘れている。
+input register の割当が逆順。
--- a/mc-code-ia32.c	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc-code-ia32.c	Mon Mar 17 20:57:01 2003 +0900
@@ -202,7 +202,7 @@
 {
     i =  virtual(i+REG_ESI);
     regs[i]=regv[i]=1;
-    return i;
+    return list2(REGISTER,i);
 }
 
 int 
@@ -348,10 +348,16 @@
         if (! regs[i]) {    /* 使われていないなら */
             regs[i]=1;      /* そのレジスタを使うことを宣言し */
             regv[i]=0;
-            return i;       /* その場所を表す番号を返す */
+            return list2(REGISTER,i); /* その場所を表す番号を返す */
         }
     }
-    return -1;
+    return list2(LVAR,new_lvar(size_of_int));
+}
+
+int
+get_fregister_var(void)
+{
+    return list2(LVAR,new_lvar(size_of_double));
 }
 
 void 
--- a/mc-code-powerpc.c	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc-code-powerpc.c	Mon Mar 17 20:57:01 2003 +0900
@@ -65,16 +65,14 @@
 #define REG_VAR_BASE 29
 #define REG_VAR_MIN  22
 #define MIN_TMP_REG 3
-#define MAX_TMP_REG 12
+#define MAX_TMP_REG 15
 
 #define PTRC_REG 3
-#define INPUT_REG 2
-#define USING_REG 1
 
 #define FREG_VAR_BASE 31
 #define FREG_VAR_MIN  24
 #define MIN_TMP_FREG 1
-#define MAX_TMP_FREG 12
+#define MAX_TMP_FREG 15
 
 #define RET_REGISTER 3
 #define RET_FREGISTER 1
@@ -84,10 +82,10 @@
 #define  REAL_MAX_REGISTER 32    /* PowerPCのレジスタが32ということ*/
 #define  REAL_MAX_FREGISTER 32    /* PowerPCのレジスタが32ということ*/
 
-int MAX_INPUT_REGISTER_VAR = MAX_TMP_REG-MIN_TMP_REG;
-int MAX_CODE_INPUT_REGISTER_VAR = MAX_TMP_REG-MIN_TMP_REG;
-int MAX_INPUT_DREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG;
-int MAX_CODE_INPUT_DREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG;
+int MAX_INPUT_REGISTER_VAR = 12-MIN_TMP_REG;
+int MAX_CODE_INPUT_REGISTER_VAR = 12-MIN_TMP_REG;
+int MAX_INPUT_DREGISTER_VAR = 12-MIN_TMP_FREG;
+int MAX_CODE_INPUT_DREGISTER_VAR = 12-MIN_TMP_FREG;
 
 
 int powerpc_regs[REAL_MAX_REGISTER];
@@ -124,7 +122,6 @@
 void code_save_stacks();
 void clear_ptr_cache_reg(int r);
 int fregister_var(int r);
-int get_fregister_var(void);
 int arg_offset_v(int arg);
 
 void
@@ -162,6 +159,7 @@
 	    n->sc=LVAR; n->dsp = lvar;
 	    return lvar;
 	}
+	arglist = cadr(arglist);
 	nargs++;
     }
     error(-1);
@@ -267,14 +265,14 @@
 get_input_fregister_var(int i)
 {
     if (i<0||MAX_FREGISTER<i+MIN_TMP_FREG) error(-1);
-    return i+MIN_TMP_FREG;
+    return list2(DREGISTER,i+MIN_TMP_FREG);
 }
 
 int
 get_input_register_var(int i)
 {
     if (i<0||MAX_REGISTER<i+MIN_TMP_REG) error(-1);
-    return i+MIN_TMP_REG;
+    return list2(REGISTER,i+MIN_TMP_REG);
 }
 
 int
@@ -381,10 +379,10 @@
             regs[REG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */
             regv[REG_VAR_BASE-i]=0;
 	    if (i>max_reg_var) max_reg_var=i;
-            return i;                       /* その場所を表す番号を返す */
+            return list2(REGISTER,i);       /* その場所を表す番号を返す */
         }
     }
-    return -1;
+    return list2(LVAR,new_lvar(size_of_int));
 }
 
 int
@@ -401,10 +399,10 @@
             regs[FREG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */
             regv[FREG_VAR_BASE-i]=0;
 	    if (i>max_freg_var) max_freg_var=i;
-            return i;                       /* その場所を表す番号を返す */
+            return list2(DREGISTER,i);       /* その場所を表す番号を返す */
         }
     }
-    return -1;
+    return list2(LVAR,new_lvar(size_of_double));
 }
 
 void 
@@ -1006,11 +1004,44 @@
     return arg*size_of_int+0;
 }
 
+void
+set_creg(int reg,int mode)
+{
+    if (reg!=creg) {
+	if (mode) 
+	    printf("\tmr %s,%s\n",register_name(reg),register_name(creg));
+	free_register(creg);
+	creg = reg;
+	regs[creg]=1;
+    }
+}
+
+void
+set_freg(int reg,int mode)
+{
+    if (reg!=freg) {
+	if (mode) 
+	    printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg));
+	free_fregister(freg);
+	freg = reg;
+	fregs[freg]=1;
+    }
+}
+
+void
+use_var(int arg)
+{
+    if (car(arg)==REGISTER)
+	regs[arg]=USING_REG;
+    else if (car(arg)==DREGISTER)
+	fregs[arg]=USING_REG;
+}
+
 int
 function(int e1)
 {
     int e2,e3,e4,e5,nargs,t;
-    int arg,reg_arg,freg_arg;
+    int arg,reg_arg,freg_arg,arg_assign;
     int reg_arg_list;
     NMTBL *n;
     int jmp;
@@ -1019,19 +1050,21 @@
     code_save_stacks();
     /* now all input register vars are free */
     e2 = cadr(e1);
-    reg_arg_list = nargs = reg_arg = freg_arg = 0;
+    reg_arg_list = nargs = reg_arg = freg_arg = arg_assign = 0;
     for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
 	t=caddr(e3);
 	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
 	if(scalar(t)) {
-	    if (reg_arg>MAX_INPUT_REGISTER_VAR) {
+	    if (reg_arg>MAX_INPUT_REGISTER_VAR) { 
 		arg = list2(LVAR,arg_offset_v(nargs));
-	    } else if (contains(e3,FUNCTION)) {
-		arg = list2(REGISTER,get_register_var()); 
-		regv[cadr(arg)]=1;
+	    } else if (contains_in_list(e3,FUNCTION)) {
+		arg = get_register_var(); 
+		arg_assign = list2(
+		    assign_expr0(get_input_register_var(reg_arg),arg,t,t),
+		    arg_assign);
 	    } else {
-		arg = list2(REGISTER,get_input_register_var(reg_arg)); 
-		regv[cadr(arg)]=1;
+		arg = get_input_register_var(reg_arg); 
+		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));
@@ -1040,12 +1073,14 @@
 	} else if (t==DOUBLE||t==FLOAT) {
 	    if (freg_arg>MAX_INPUT_DREGISTER_VAR) {
 		arg = list2(LVAR,arg_offset_v(nargs));
-	    } else if (contains(e3,FUNCTION)) {
-		arg = list2(DREGISTER,get_fregister_var()); 
-		fregv[cadr(arg)]=1;
+	    } else if (contains_in_list(e3,FUNCTION)) {
+		arg = get_fregister_var(); 
+		arg_assign = list2(
+		    assign_expr0(get_input_register_var(reg_arg),arg,t,t),
+		    arg_assign);
 	    } else {
-		arg = list2(DREGISTER,get_input_fregister_var(freg_arg)); 
-		fregv[cadr(arg)]=1;
+		arg = get_input_fregister_var(freg_arg); 
+		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));
@@ -1068,6 +1103,9 @@
 	regv[creg]=1;
     }
 
+    for(;arg_assign;arg_assign=cadr(arg_assign)) {
+	g_expr_u(car(arg_assign));
+    }
     clear_ptr_cache();
     if (car(e2) == FNAME) {	
 	printf("\tbl\tL_%s$stub\n",n->nm);
@@ -1084,15 +1122,13 @@
 	if (car(reg_arg_list)==DREGISTER) free_fregister(cadr(reg_arg_list));
 	else if (car(reg_arg_list)==REGISTER) free_register(cadr(reg_arg_list));
     }
-    free_fregister(freg);
-    freg = RET_FREGISTER; fregs[freg]=1;
-    free_register(creg); 
-    creg = RET_REGISTER;  regs[creg]=1;
     if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
+	set_freg(RET_FREGISTER,0);
         fregv[freg]=1; regv[creg]=0;
     } else if (fnptr->ty==VOID) {
         fregv[freg]=0; regv[creg]=0;
     } else {
+	set_creg(RET_REGISTER,0);
         fregv[freg]=0; regv[creg]=1;
     }
     return fnptr->ty;
@@ -1173,7 +1209,14 @@
 
 void
 code_assign_register(int e2,int byte) {
-    printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
+    if (e2!=creg)
+	printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
+}
+
+void
+code_assign_fregister(int e2,int byte) {
+    if (e2!=creg)
+	printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
 }
 
 void
@@ -1196,7 +1239,8 @@
     creg = reg = e2;
     tosop(op,xreg);
     creg = xreg;
-    printf("\tmr %s,%s\n",register_name(creg),register_name(reg));
+    if (creg!=reg)
+	printf("\tmr %s,%s\n",register_name(creg),register_name(reg));
 }
 
 
@@ -1232,8 +1276,9 @@
     if(oreg==-1) {
 	error(-1);
     } else if (oreg<= -REG_LVAR_OFFSET) {
-	oreg = get_register(); if (oreg<0) error(-1);
-        code_rlvar(lvar(oreg+REG_LVAR_OFFSET),oreg);
+	dx = get_register(); if (dx<0) error(-1);
+        code_rlvar(lvar(oreg+REG_LVAR_OFFSET),dx);
+	oreg = dx;
         regv[oreg]=1;
     }
 
@@ -1448,10 +1493,7 @@
 leave(int control, char *name)
 {
     if (control) {
-	if (regv[creg] && creg!=RET_REGISTER)
-	    printf("\tmr %s,%s\n",register_name(RET_REGISTER),register_name(creg));
-	if (fregv[freg] && freg!=RET_FREGISTER)
-	    printf("\tfmr %s,%s\n",fregister_name(RET_FREGISTER),fregister_name(freg));
+	code_set_fixed_creg(0);
     }
     if (retcont) fwddef(retcont);
     fwddef(retlabel);
@@ -1768,7 +1810,8 @@
 void
 code_fregister(int e2)
 {
-    printf("\tfmr %s,%s\n",register_name(freg),register_name(e2));
+    if (freg!=e2)
+	printf("\tfmr %s,%s\n",register_name(freg),register_name(e2));
 }
 
 void code_dassign_gvar(int e2,int freg,int d)
@@ -1890,11 +1933,9 @@
 void code_i2d()
 { 
     i2d_lib_used = 1;
-    char *frn = fregister_name(freg);
-    char *crn = register_name(creg);
-    printf("\tmr r3,%s\n",crn);
+    set_creg(RET_REGISTER,1);
     printf("\tbl i2d_\n");
-    printf("\tfmr %s,f1\n",frn);
+    set_freg(RET_FREGISTER,0);
     fregs[freg]=1;
     regs[creg]=0;
 }
@@ -1938,11 +1979,9 @@
 void code_d2u()
 { 
     d2u_lib_used=1;
-    char *frn = fregister_name(freg);
-    char *crn = register_name(creg);
-    printf("\tfmr f1,%s\n",frn);
+    set_freg(RET_FREGISTER,1);
     printf("\tbl d2u\n");
-    printf("\tmr %s,r3\n",crn);
+    set_creg(RET_REGISTER,0);
     fregs[freg]=1;
     regs[creg]=0;
 }
--- a/mc-code.h	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc-code.h	Mon Mar 17 20:57:01 2003 +0900
@@ -23,6 +23,7 @@
 extern void gexpr_code_init(void);
 extern int register_var(int r);
 extern int get_register_var(void);
+extern int get_fregister_var(void);
 extern int get_input_register_var(int);
 extern int get_input_fregister_var(int);
 extern void emit_push(void);
--- a/mc-codegen.c	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc-codegen.c	Mon Mar 17 20:57:01 2003 +0900
@@ -469,18 +469,18 @@
         if (scalar(type)) {
             if(reg_var<max_input_register_var) {
                 n->sc = REGISTER;
-		if ((n->dsp = get_input_register_var(reg_var++)) <0) {
-		    error(-1); return;
-		}
+		n->dsp = cadr(get_input_register_var(reg_var));
+		regv[reg_var]= 1;
+		regs[reg_var]= INPUT_REG;
                 reg_var++;
                 cadddr(fnptr->dsp)=size_of_int;
             }
         } else if ((type==FLOAT||type==DOUBLE)&&stmode==REGISTER) {
             if(freg_var<max_input_fregister_var) {
                 n->sc = DREGISTER;
-		if ((n->dsp = get_input_fregister_var(freg_var++)) <0) {
-		    error(-1); return;
-		}
+		n->dsp = cadr(get_input_fregister_var(freg_var));
+		fregv[reg_var]= 1;
+		fregs[reg_var]= INPUT_REG;
                 freg_var++;
                 cadddr(fnptr->dsp)=size_of_double;
             }
@@ -715,11 +715,11 @@
 	e2 = car(e3); sz = size(ty=caddr(e3)); 
 	if (scalar(ty) && 
 		regs < MAX_CODE_INPUT_REGISTER_VAR) {
-	    target=list4(list2(REGISTER,get_input_register_var(regs++)), 
+	    target=list4(get_input_register_var(regs++), 
 		    target,ty,e2);
 	} else if ((ty==DOUBLE||ty==FLOAT) && 
 		fregs < MAX_CODE_INPUT_DREGISTER_VAR) {
-	    target=list4(list2(DREGISTER,get_input_fregister_var(fregs++)), 
+	    target=list4(get_input_fregister_var(fregs++), 
 		    target,ty,e2);
 	} else {
 	    target=list4(list2(LVAR,0), target,ty,e2);
--- a/mc-codegen.h	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc-codegen.h	Mon Mar 17 20:57:01 2003 +0900
@@ -2,6 +2,11 @@
 /* max stack in an expression (for each int, float ) */
 #define MAX_MAX 10
 
+/* flag in regs/fregs */
+
+#define INPUT_REG 2    /* input register ( can be reused ) */
+#define USING_REG 1    /* unreusable register usage */
+
 extern int  creg;     /* current register */
 extern int  reg_sp;   /* REGister Stack-Pointer */
 
@@ -20,6 +25,11 @@
 
 extern int use;                 /* generated value will be used in gexpr */
 
+/* function provided by mc-code-*.c */
+
+extern int get_register_var(void);
+extern int get_fregister_var(void);
+
 /* function provided by mc-codegen.c */
 
 extern void codegen_init();
@@ -66,6 +76,7 @@
 extern void arg_register(NMTBL *fnptr);
 
 extern int contains(int e,int type);
+extern int contains_in_list(int e,int type);
 
 /* floating point */
 
--- a/mc-parse.c	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc-parse.c	Mon Mar 17 20:57:01 2003 +0900
@@ -809,13 +809,14 @@
 	return n;
     case STAT: /* of course this is wrong */
     case LDECL:
-	if (stmode==REGISTER && reg_var <=MAX_REGISTER_VAR) {
-	    if(!scalar(type)) /* non integer register type ... */
-		error(DCERR);
-	    nsc = REGISTER;
-	    reg_var++;
-           if ((ndsp = get_register_var())<0)
-               error(-1);
+	if (stmode==REGISTER) {
+	    if(scalar(type)) {
+		ndsp = get_register_var();
+	    } else if (type==FLOAT||type==DOUBLE) {
+		ndsp = get_fregister_var();
+	    } else error(DCERR);
+	    nsc = car(ndsp);
+	    ndsp = cadr(ndsp);
 	} else {
 	    nsc = LVAR;
 	    ndsp = new_lvar(sz);
--- a/mc.h	Mon Mar 17 14:26:22 2003 +0900
+++ b/mc.h	Mon Mar 17 20:57:01 2003 +0900
@@ -306,7 +306,6 @@
 EXTERN int assign_expr0(int e1,int e2,int t,int type);
 EXTERN int backdef(void);
 EXTERN int fwdlabel(void);
-EXTERN int get_register_var(void);
 EXTERN int glist2(int e1,int e2);
 EXTERN int glist3(int e1,int e2,int e3);
 EXTERN int integral(int t);