changeset 103:f849af4b5ea9

*** empty log message ***
author kono
date Mon, 17 Mar 2003 14:26:22 +0900
parents 3cf2f8c120b9
children c21aeb12b78b
files .gdbinit Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-parse.c mc.h test/basic.c
diffstat 9 files changed, 264 insertions(+), 167 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Sat Mar 15 21:55:14 2003 +0900
+++ b/.gdbinit	Mon Mar 17 14:26:22 2003 +0900
@@ -13,4 +13,4 @@
 x/1i $eip
 end
 b errmsg
-r -s mc-parse.c
+r -s test/basic.c
--- a/Changes	Sat Mar 15 21:55:14 2003 +0900
+++ b/Changes	Mon Mar 17 14:26:22 2003 +0900
@@ -2184,3 +2184,45 @@
 Sat Mar 15 16:04:09 JST 2003
 
 やぁ...  まぁ.... バグだらけだな。
+
+function call のレジスタの処理がでたらめ。RISCの場合は、parallel_assing
+した方がいいんじゃないか?
+
+Sun Mar 16 20:59:10 JST 2003
+
+あぁ、まだまだ、かかりそうだ....
+
+定義されてない関数/定数をextern扱いにする必要がある。(なんで、PICなの?)
+
+function は c0(n->ty)==FUNCTION で識別する。n->sc には、FUNCTION/EXTRN[1]
+が入る。だよね。(CODE)も。だけど、n->ty に戻り型が入っている場合が
+けっこうあるらしい。
+
+(しかし、これは、結構かかるな...)
+
+Mon Mar 17 12:02:22 JST 2003
+
+function のnptrだけど、
+    nptr->ty  function の return type
+         list3(FUNCTION,return_type,arg_type_list);
+    nptr->sc  本来はFUNCTION/CODE (EXTRN/EXTRN1)
+    nptr->dsp 引数のリスト
+と言う構成なわけだよね。で、引数のリストとtypeは重複している。
+
+他のnptrとの整合性を考えると、
+    nptr->ty  return type
+    nptr->sc  FUNCTION/CODE
+    nptr->dsp 引数のリスト
+が良い。で、引数のリストにEXTRNの情報を入れる方がいいんじゃないか?
+(どっちにするんだよ...)
+
+プロトタイプと実際の引数リストの整合性はチェックしなくちゃ
+いけないわけだから、別な方がいいんじゃないか? とすると、
+やっぱり前者か...
+
+
+extern と、そうでないものとの呼出しを、呼出しの時点で
+区別しないといけない。しかし、prototype で定義されている
+ものと default extern の区別は、最終の時点でしか判別できない。
+できないよね。定義されてないものが default extern なんだから。
+ってことは、最後に、.set で定義するしかないか。(sigh...)
--- a/mc-code-ia32.c	Sat Mar 15 21:55:14 2003 +0900
+++ b/mc-code-ia32.c	Mon Mar 17 14:26:22 2003 +0900
@@ -53,8 +53,10 @@
 int MAX_REGISTGER_VAR=2;    
 int MAX_FREGISTER=1;
 
-int max_input_register_var = 2;
-int max_input_fregister_var = 0;
+int MAX_INPUT_REGISTER_VAR = 0;
+int MAX_CODE_INPUT_REGISTER_VAR = 2;
+int MAX_INPUT_DREGISTER_VAR = 0;
+int MAX_CODE_INPUT_DREGISTER_VAR = 0;
 
 /*
     creg   currrent virtual register
@@ -107,7 +109,6 @@
 static char *reg_name_w[4];
 
 static void use_register(int virt, int real, int move);
-static void use_register_var(int i);
 static int virtual(int real);
 static void shift(char *op, int reg);
 static void ld_indexx(int byte, int n, int xreg);
@@ -199,10 +200,12 @@
 int 
 get_input_register_var(int i)
 {
-    return virtual(i+REG_ESI);
+    i =  virtual(i+REG_ESI);
+    regs[i]=regv[i]=1;
+    return i;
 }
+
 int 
-
 get_input_fregister_var(int i)
 {
     error(-1);
@@ -255,28 +258,6 @@
     return;
 }
 
-void
-use_register_var(int i) {
-    regv[i]=1;
-}
-
-void
-code_arg_register(int args)
-{
-    NMTBL *n;
-    if (args) {
-	/* process in reverse order */
-        n = (NMTBL*)caddr(args);
-        if(n->sc==REGISTER) {
-            if ((n->dsp = get_register_var()) <0) {
-                error(-1); return;
-            }
-            use_register_var(n->dsp); /* it has now value in it */
-        }
-	code_arg_register(cadr(args));
-    }
-}
-
 
 void
 register_usage(char *s)
@@ -1035,13 +1016,13 @@
 }
 
 void
-code_assign_gvar(int e2,int byte) {
+code_assign_gvar(int e2,int creg,int byte) {
     if (byte) use_data_reg(creg,1);
     printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2));
 }
 
 void
-code_assign_lvar(int e2,int byte) {
+code_assign_lvar(int e2,int creg,int byte) {
     if (byte) use_data_reg(creg,1);
     printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2);
 }
@@ -1205,9 +1186,15 @@
 {
     if (reg>=0) {
 	use_register(reg,REG_ECX,1);
+    } else if (reg<= -REG_LVAR_OFFSET) {
+	use_register(dreg,REG_ECX,0);
+        code_rlvar(lvar(reg+REG_LVAR_OFFSET),dreg);
+        reg = dreg;
+        regv[dreg]=0;
     } else {
 	use_register(dreg,REG_ECX,0);
 	printf("\tpopl %%ecx\n");
+        regv[dreg]=0;
     }
     printf("\t%s %%cl,%s\n",op,register_name(creg,0));
 }
@@ -1574,17 +1561,17 @@
 }
 
 
-void code_dassign_gvar(int e2,int d)
+void code_dassign_gvar(int e2,int freg,int d)
 { 
     printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ;
 }
 
-void code_dassign_lvar(int e2,int d)
+void code_dassign_lvar(int e2,int freg,int d)
 { 
     printf("\t%s %d(%%ebp)\n",fstore(d),e2);
 }
 
-void code_dassign(int e2,int d)
+void code_dassign(int e2,int freg,int d)
 { 
     printf("\t%s (%s)\n",fstore(d),register_name(e2,0));
 }
@@ -1835,7 +1822,7 @@
 		creg = xreg;
 	    }
 	    code_assign_lvar(
-		lvar(reg_stack[sp]=new_lvar(size_of_int)),0); 
+		lvar(reg_stack[sp]=new_lvar(size_of_int)),creg,0); 
 	    reg_stack[sp]= reg_stack[sp]-REG_LVAR_OFFSET;
 	    regv[xreg]=0;
 	    creg=screg;
@@ -1845,7 +1832,7 @@
     while(sp-->0) {
 	if ((xreg=freg_stack[sp])==-1) {
 	    code_dassign_lvar(
-		lvar(freg_stack[sp]=new_lvar(size_of_double)),1); 
+		lvar(freg_stack[sp]=new_lvar(size_of_double)),freg,1); 
 	    freg_stack[sp]= freg_stack[sp]-REG_LVAR_OFFSET;
 	}
     }
--- a/mc-code-powerpc.c	Sat Mar 15 21:55:14 2003 +0900
+++ b/mc-code-powerpc.c	Mon Mar 17 14:26:22 2003 +0900
@@ -15,7 +15,6 @@
 static void ld_indexx(int byte, int n, int xreg);
 static void local_table(void);
 static void shift(char *op, int reg);
-static void use_register_var(int i);
 
 static int output_mode = TEXT_EMIT_MODE;
 static int data_alignment = 0;
@@ -78,15 +77,18 @@
 #define MAX_TMP_FREG 12
 
 #define RET_REGISTER 3
-#define RET_DREGISTER 1
+#define RET_FREGISTER 1
 
 int MAX_REGISTER=30;             /* PowerPCのレジスタを10個まで使う*/
 int MAX_FREGISTER=30;
 #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_input_fregister_var = MAX_TMP_FREG-MIN_TMP_FREG;
+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 powerpc_regs[REAL_MAX_REGISTER];
 int powerpc_regv[REAL_MAX_REGISTER];
@@ -123,7 +125,6 @@
 void clear_ptr_cache_reg(int r);
 int fregister_var(int r);
 int get_fregister_var(void);
-void use_fregister_var(int r);
 int arg_offset_v(int arg);
 
 void
@@ -179,7 +180,7 @@
     /* INPUT_REG か PTR_CACHE をつぶす */
     for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) {
 	if (regs[i]==INPUT_REG) {
-	    code_assign_lvar(lvar(replace_arg_var(i,INT)),0);
+	    code_assign_lvar(lvar(replace_arg_var(i,INT)),i,0);
 	} else if (regs[i]==PTRC_REG) {
 	    clear_ptr_cache_reg(i);
 	} else 
@@ -191,7 +192,7 @@
     for(i=0;i<reg_sp;i++) {
 	if (reg_stack[i]>=0) {
             code_assign_lvar(
-                lvar(reg_stack[i]=new_lvar(size_of_int)),0); 
+                lvar(reg_stack[i]=new_lvar(size_of_int)),i,0); 
             reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET;
 	    return i;
 	}
@@ -209,7 +210,7 @@
 int 
 get_fregister(void)
 {    /* 使われていないレジスタを調べる */
-    int i;
+    int i,reg;
     for(i=MAX_TMP_FREG;i>MIN_TMP_FREG;i--) {
 	if (fregs[i]) continue;    /* 使われている */
 	fregs[i]=USING_REG;      /* そのレジスタを使うことを宣言し */
@@ -217,7 +218,7 @@
     }
     for(i=MAX_TMP_FREG;i>MIN_TMP_FREG;i--) {
 	if (fregs[i]==INPUT_REG) {
-	    code_dassign_lvar(lvar(replace_arg_var(i,DOUBLE)),0);
+	    code_dassign_lvar(lvar(replace_arg_var(i,DOUBLE)),i,0);
 	} else 
 	    continue;
 	fregs[i]=USING_REG;      /* そのレジスタを使うことを宣言し */
@@ -225,9 +226,9 @@
     }
     /* search register stack */
     for(i=0;i<freg_sp;i++) {
-	if (freg_stack[i]>=0) {
+	if ((reg=freg_stack[i])>=0) {
             code_dassign_lvar(
-                lvar(freg_stack[i]=new_lvar(size_of_double)),1); 
+                lvar(freg_stack[i]=new_lvar(size_of_double)),reg,1); 
             freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
 	    return i;
 	}
@@ -246,7 +247,8 @@
 void
 emit_pop_free(int xreg)
 {
-    free_register(xreg);
+    if (xreg>=0)
+	free_register(xreg);
 }
 
 void 
@@ -276,6 +278,21 @@
 }
 
 int
+free_register_count(void)
+{
+    int i,count,fcount;
+    fcount = count = 0;
+    for(i=0;i<MAX_REGISTER;i++) {
+        if (! regs[i] && ! regv[i]) count++;
+    }
+    for(i=0;i<MAX_FREGISTER;i++) {
+        if (! fregs[i] && ! fregv[i]) fcount++;
+    }
+    fprintf(stderr,"# free reg %d freg %d\n",count,fcount);
+    return count+fcount;
+}
+
+int
 register_full(void)
 {
     int i;
@@ -299,43 +316,6 @@
 }
 
 void
-use_register_var(int i) {
-    regv[i]=1;
-}
-
-void
-use_fregister_var(int i) {
-    fregv[i]=1;
-}
-
-void
-code_arg_register(int args)
-{
-    int r=0;
-    int f=0;
-    NMTBL *n;
-    /* all registers are freed at this time */
-    /* set up input regsiters */
-    if (args) {
-	/* process in reverse order */
-        n = (NMTBL*)caddr(args);
-        if(n->sc==REGISTER) {
-            if ((n->dsp = get_input_register_var(r++)) <0) {
-                error(-1); return;
-            }
-            use_register_var(n->dsp); /* it has now value in it */
-        } else if(n->sc==DREGISTER) {
-            if ((n->dsp = get_input_fregister_var(f++)) <0) {
-                error(-1); return;
-            }
-            use_fregister_var(n->dsp); /* it has now value in it */
-	}
-	code_arg_register(cadr(args));
-    }
-}
-
-
-void
 register_usage(char *s)
 {
     int i;
@@ -1044,24 +1024,28 @@
 	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;
+		arg = list2(REGISTER,get_register_var()); 
+		regv[cadr(arg)]=1;
 	    } else {
-		arg = list2(REGISTER,get_register()); regv[cadr(arg)]=1;
+		arg = list2(REGISTER,get_input_register_var(reg_arg)); 
+		regv[cadr(arg)]=1;
 	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
 	    g_expr_u(assign_expr0(arg,e4,t,t));
 	    nargs ++ ; reg_arg++;
 	    continue;
 	} else if (t==DOUBLE||t==FLOAT) {
-	    if (freg_arg>max_input_fregister_var) {
+	    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;
+		arg = list2(DREGISTER,get_fregister_var()); 
+		fregv[cadr(arg)]=1;
 	    } else {
-		arg = list2(DREGISTER,get_fregister()); fregv[cadr(arg)]=1;
+		arg = list2(DREGISTER,get_input_fregister_var(freg_arg)); 
+		fregv[cadr(arg)]=1;
 	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
 	    g_expr_u(assign_expr0(arg,e4,t,t));
@@ -1100,7 +1084,10 @@
 	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) {
         fregv[freg]=1; regv[creg]=0;
     } else if (fnptr->ty==VOID) {
@@ -1160,7 +1147,7 @@
 }
 
 void
-code_assign_gvar(int e2,int byte) {
+code_assign_gvar(int e2,int creg,int byte) {
     int r;
     char *crn,*rrn;
     r = get_ptr_cache((char*)caddr(e2));
@@ -1174,7 +1161,7 @@
 }
 
 void
-code_assign_lvar(int e2,int byte) {
+code_assign_lvar(int e2,int creg,int byte) {
     char *crn;
     crn=register_name(creg);
     if (byte) {
@@ -1242,6 +1229,14 @@
     int dx;
     char *orn,*crn,*drn;
 
+    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);
+        regv[oreg]=1;
+    }
+
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
@@ -1454,16 +1449,16 @@
 {
     if (control) {
 	if (regv[creg] && creg!=RET_REGISTER)
-	    printf("\tmr r%d,r%d\n",RET_REGISTER,creg);
-	if (fregv[freg] && freg!=RET_DREGISTER)
-	    printf("\tfmr f%d,f%d\n",RET_DREGISTER,freg);
+	    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));
     }
     if (retcont) fwddef(retcont);
     fwddef(retlabel);
     printf("\tlwz r1,0(r1)\n");
     if (max_freg_var>0) {
 	if (max_reg_var>0)
-	    printf("\tlmw r%d,-%d(r1)\n",
+	    printf("\tlmw r%d,%d(r1)\n",
 			REG_VAR_BASE-max_reg_var,reg_save_offset());
 	printf("\tb restFP+%d ; restore f%d-f31\n",
 			68-(31-FREG_VAR_BASE-max_freg_var)*4,
@@ -1472,7 +1467,7 @@
 	printf("\tlwz r0,8(r1)\n");
 	printf("\tmtlr r0\n");
 	if (max_reg_var>0)
-	    printf("\tlmw r%d,-%d(r1)\n",
+	    printf("\tlmw r%d,%d(r1)\n",
 			REG_VAR_BASE-max_reg_var,reg_save_offset());
 	printf("\tblr\n");
     }
@@ -1481,9 +1476,9 @@
     fwddef(code_setup);
     fwddef(code_base);
     if (max_reg_var>0)
-	printf("\tstmw r%d,-%d(r1)\n",
+	printf("\tstmw r%d,%d(r1)\n",
 			REG_VAR_BASE-max_reg_var,reg_save_offset());
-    printf("\tstwu r1,-%d(r1)\n",disp+disp_offset);
+    printf("\tstwu r1,%d(r1)\n",disp+disp_offset);
     if (max_freg_var>0)
 	printf("\tb saveFP+%d ; save f%d-f31\n",
 			68-(31-FREG_VAR_BASE-max_freg_var)*4,
@@ -1501,7 +1496,17 @@
 
 void
 code_set_fixed_creg(int mode) {
-    creg=0;
+    if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
+	if(freg!=RET_FREGISTER) {
+	    printf("\tfmr %s,%s\n",fregister_name(RET_FREGISTER),
+		fregister_name(RET_FREGISTER));
+	}
+    } else {
+	if(freg!=RET_FREGISTER) {
+	    printf("\tmr %s,%s\n",register_name(RET_REGISTER),
+		fregister_name(RET_REGISTER));
+	}
+    }
 }
 
 void
@@ -1613,11 +1618,11 @@
 	}
     }
     for(n=ntable;n < &ntable[GSYMS];n++) {
-	if (n->dsp == EXTRN1 && n->ty>0 &&
-	    (car(n->ty)==FUNCTION||car(n->ty)==CODE)) {
+	if (is_code(n)||is_function(n)) {
 	    extrn = n->nm;
-printf(".data");
-printf(".picsymbol_stub");
+	    if (n->sc==EXTRN1) {
+		data_mode(0);
+printf(".picsymbol_stub\n");
 printf("L_%s$stub:\n",extrn);
 printf("\t.indirect_symbol _%s\n",extrn);
 printf("\tmflr r0\n");
@@ -1635,14 +1640,17 @@
 printf("L_%s$lazy_ptr:\n",extrn);
 printf("\t.indirect_symbol _%s\n",extrn);
 printf("\t.long dyld_stub_binding_helper\n");
+	    } else if (n->sc==FUNCTION||n->sc==CODE) {
+		text_mode();
+printf("\t.set L_%s$stub,_%s\n",extrn,extrn);
+	    }
 	}
     }
     init = 0;
     for(n=ntable;n < &ntable[GSYMS];n++) {
-	if (n->dsp == EXTRN1 && !(n->ty>0 &&
-	    (car(n->ty)==FUNCTION||car(n->ty)==CODE))) {
+	if (n->sc==GVAR&& n->dsp == EXTRN1) {
 	    if(init==0) {
-printf(".data\n");
+		data_mode(0);
 printf(".non_lazy_symbol_pointer\n");
 		init=1;
 	    }
@@ -1763,19 +1771,19 @@
     printf("\tfmr %s,%s\n",register_name(freg),register_name(e2));
 }
 
-void code_dassign_gvar(int e2,int d)
+void code_dassign_gvar(int e2,int freg,int d)
 { 
     int r;
     r = get_ptr_cache((char*)caddr(e2));
     printf("\t%s %s,(%s)\n",fstore(d),fregister_name(freg),register_name(r));
 }
 
-void code_dassign_lvar(int e2,int d)
+void code_dassign_lvar(int e2,int freg,int d)
 { 
     printf("\t%s %s,%d(r1)\n",fstore(d),fregister_name(freg),e2);
 }
 
-void code_dassign(int e2,int d)
+void code_dassign(int e2,int freg,int d)
 { 
     printf("\t%s %s,(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
 }
@@ -2156,18 +2164,18 @@
 void
 code_save_stacks()
 {
-    int i;
+    int i,reg;
     for(i=0;i<reg_sp;i++) {
-        if (reg_stack[i]>=0) {
+        if ((reg=reg_stack[i])>=0) {
             code_assign_lvar(
-                lvar(reg_stack[i]=new_lvar(size_of_int)),1); 
+                lvar(reg_stack[i]=new_lvar(size_of_int)),reg,1); 
             reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET;
         }
     }
     for(i=0;i<freg_sp;i++) {
-        if (freg_stack[i]>=0) {
+        if ((reg=freg_stack[i])>=0) {
             code_dassign_lvar(
-                lvar(freg_stack[i]=new_lvar(size_of_double)),1); 
+                lvar(freg_stack[i]=new_lvar(size_of_double)),reg,1); 
             freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
         }
     }
--- a/mc-code.h	Sat Mar 15 21:55:14 2003 +0900
+++ b/mc-code.h	Mon Mar 17 14:26:22 2003 +0900
@@ -10,8 +10,11 @@
 extern int MAX_REGISTER; 
 extern int MAX_REGISTGER_VAR;
 extern int MAX_FREGISTER;
-extern int max_input_register_var;
-extern int max_input_fregister_var;
+
+extern int MAX_INPUT_REGISTER_VAR;
+extern int MAX_CODE_INPUT_REGISTER_VAR;
+extern int MAX_INPUT_DREGISTER_VAR;
+extern int MAX_CODE_INPUT_DREGISTER_VAR;
 
 #define REG_LVAR_OFFSET 2
 
@@ -67,8 +70,8 @@
 extern void code_jmp(char *s);
 extern void code_indirect_jmp(int e2);
 extern int rindirect(int e1);
-extern void code_assign_gvar(int e2,int byte);
-extern void code_assign_lvar(int e2,int byte);
+extern void code_assign_gvar(int e2,int reg,int byte);
+extern void code_assign_lvar(int e2,int reg,int byte);
 extern void code_assign_register(int e2,int byte);
 extern void code_assign(int e2,int byte);
 extern void code_register_assop(int e2,int op,int byte);
@@ -95,9 +98,9 @@
 extern void code_cmp_fregister(int);
 extern void code_cmp_drgvar(int);
 extern void code_cmp_drlvar(int);
-extern void code_dassign(int,int);
-extern void code_dassign_gvar(int,int);
-extern void code_dassign_lvar(int,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);
--- a/mc-codegen.c	Sat Mar 15 21:55:14 2003 +0900
+++ b/mc-codegen.c	Mon Mar 17 14:26:22 2003 +0900
@@ -446,7 +446,47 @@
 void
 arg_register(NMTBL *fnptr)
 {
-    code_arg_register(fnptr->dsp);
+    int args = fnptr->dsp;
+    NMTBL *n;
+    int reg_var = 0;
+    int freg_var = 0;
+    int type;
+    int max_input_register_var;
+    int max_input_fregister_var;
+
+    if (is_function(fnptr)) {
+	max_input_register_var = MAX_INPUT_REGISTER_VAR;
+	max_input_fregister_var = MAX_INPUT_DREGISTER_VAR;
+    } else {
+	max_input_register_var = MAX_CODE_INPUT_REGISTER_VAR;
+	max_input_fregister_var = MAX_CODE_INPUT_DREGISTER_VAR;
+    }
+
+    while (args) {
+	/* process in reverse order */
+        n = (NMTBL*)caddr(args);
+	type = n->ty;
+        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;
+		}
+                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;
+		}
+                freg_var++;
+                cadddr(fnptr->dsp)=size_of_double;
+            }
+        }
+	args = cadr(args);
+    }
 }
 
 /* goto arguments list                                      */
@@ -673,10 +713,12 @@
     fregs = 0;
     for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
 	e2 = car(e3); sz = size(ty=caddr(e3)); 
-	if (scalar(ty) && regs < max_input_register_var&&sz==size_of_int) {
+	if (scalar(ty) && 
+		regs < MAX_CODE_INPUT_REGISTER_VAR) {
 	    target=list4(list2(REGISTER,get_input_register_var(regs++)), 
 		    target,ty,e2);
-	} else if ((ty==DOUBLE||ty==FLOAT) && fregs < max_input_fregister_var) {
+	} else if ((ty==DOUBLE||ty==FLOAT) && 
+		fregs < MAX_CODE_INPUT_DREGISTER_VAR) {
 	    target=list4(list2(DREGISTER,get_input_fregister_var(fregs++)), 
 		    target,ty,e2);
 	} else {
@@ -851,11 +893,11 @@
     switch(car(e2)) {
     case GVAR:      /*   i=3 */
             g_expr(e4);
-	    code_assign_gvar(e2,byte);
+	    code_assign_gvar(e2,creg,byte);
             return;
     case LVAR:
             g_expr(e4);
-	    code_assign_lvar(lvar(cadr(e2)),byte);
+	    code_assign_lvar(lvar(cadr(e2)),creg,byte);
             return;
     case REGISTER:
             g_expr(e4);
@@ -886,18 +928,18 @@
     switch(car(e2)) {
     case GVAR:
             g_expr(e4);
-	    code_dassign_gvar(e2,d);
+	    code_dassign_gvar(e2,freg,d);
             return;
     case LVAR:
             g_expr(e4);
-	    code_dassign_lvar(lvar(cadr(e2)),d);
+	    code_dassign_lvar(lvar(cadr(e2)),freg,d);
             return;
     }
     g_expr(e2);
     emit_push();
     g_expr(e4);
     e2 = emit_pop(0);
-    code_dassign(e2,d);
+    code_dassign(e2,freg,d);
     emit_pop_free(e2);
     return;
 }
--- a/mc-parse.c	Sat Mar 15 21:55:14 2003 +0900
+++ b/mc-parse.c	Mon Mar 17 14:26:22 2003 +0900
@@ -556,7 +556,7 @@
 	    n->dsp=0;
 	    if (type==CODE) {
 		n->ty=CODE;
-		n->sc=EMPTY;
+		/* n->sc=EMPTY; */
 		if(sym==RPAR) {
 		    getsym();t=0;
 		} else {
@@ -564,15 +564,18 @@
 		    t=adecl(n);
 		    stmode=0;
 		}
-		type=list3(CODE,CODE,t);
+		type=glist3(CODE,CODE,t);
 	    } else {
-		n->ty=type;
-		n->sc=EMPTY;
+		/* n->sc=EMPTY; */
 		if(sym==RPAR) {
 		    getsym();t=0;
-		} else
+		} else {
+		    stmode=REGISTER;
 		    t=adecl(n);
-		type=list3(FUNCTION,type,t);
+		    stmode=0;
+		}
+		type=glist3(FUNCTION,type,t);
+		n->ty=type;
 	    }
             /* in GDECL mode dsp contains real parameter, if not,
                it contains arg type list. Real parameter list is compatible
@@ -785,13 +788,6 @@
 	    type=list2(POINTER,type); n->ty = type;
 	}
 	fnptr->dsp=list4(type,fnptr->dsp,(int)n,0);
-	if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR &&
-	    size(type)==size_of_int) {
-	    n->sc = REGISTER;
-	    reg_var++;
-	    cadddr(fnptr->dsp)=size_of_int;
-	    return n;
-	}
 	n->sc = LVAR;
 	if(type==CHAR) {
 	    if (n->dsp==0) {
@@ -1039,13 +1035,12 @@
 {
     int t,arglist;
 
-    if (n->sc==EMPTY) n->sc = CODE;
     if(!chk) code_enter(n->nm);
     fnptr=n;
+    n->sc = CODE;
     disp = -args;
     mode=ADECL;
     if (sym!=LC) {
-	stmode=REGISTER;
 	reg_var=0;
 	args=0; fnptr->dsp=0;
 	while (sym!=LC) { /* argument declaration !ANSI */
@@ -1100,6 +1095,7 @@
 
     reg_var=0;
     fcheck(n);
+    n->sc = FUNCTION;
     mode=ADECL;
     if (sym!=LC) {
 	args=0; fnptr->dsp=0;
@@ -1116,6 +1112,7 @@
     disp=0;
     init_vars=0;
     /* local variable declaration */
+    stmode=0;
     mode=STAT;
     while (typeid(getsym()) || sym==STATIC || sym==EXTRN
 		|| sym==REGISTER || sym==TYPEDEF) {
@@ -1190,15 +1187,14 @@
 {
     if(!(mode==GDECL||mode==ADECL)||
              (car(type)!=FUNCTION&&car(type)!=CODE)) error(DCERR);
-    if(n->sc==FUNCTION) compatible(n->ty,cadr(type));
-    else if(n->sc==CODE) compatible(n->ty,cadr(type));
+    if(is_code(n)) compatible(cadr(n->ty),cadr(type));
+    else if(is_function(n)) compatible(cadr(n->ty),cadr(type));
     else {
-	if(n->sc!=EMPTY)
+	if (n->sc==EMPTY) {
+	    n->sc=EXTRN;
+	    n->ty=type;
+	} else
 	    error(DCERR);
-	else {
-	    n->sc=FUNCTION;
-	    n->ty=cadr(type);
-	}
     }
 }
 
@@ -1627,8 +1623,12 @@
 	e2 = cadr(e1);
 	if (car(e2) == FNAME) {
 	    nptr0=(NMTBL *)cadr(e2);
-	    if (nptr0->sc==EMPTY||nptr0->sc==FUNCTION)
+	    if (nptr0->sc==EMPTY)
+		nptr0->sc = EXTRN1;
+	    else if(nptr0->sc==FUNCTION)
 		nptr0->sc = CODE;
+	    if (nptr0->ty>0&&car(nptr0->ty)==FUNCTION)
+		car(nptr0->ty)=CODE;
 	}
 	gexpr(list3(CODE,e1,env),0);
 	control=0;
@@ -1683,10 +1683,12 @@
 
 
 int
-assign_expr0(int e1,int e2,int t,int type) {
+assign_expr0(int e1,int e2,int t,int type0) {
     int stype;
     stype=type;
-    e1=assign_expr(e1,rvalue_t(e2,type),t,type);
+    type = type0;
+    e2 = rvalue(e2);
+    e1=assign_expr(e1,e2,t,type);
     type=stype;
     return e1;
 }
@@ -2134,7 +2136,7 @@
 {
     int e1;
     e1=list2(FNAME,(int)nptr);
-    type=list3(nptr->sc,nptr->ty,nptr->dsp);
+    type=list3(car(nptr->ty),nptr->ty,nptr->dsp);
     getsym();
     extrn_use(nptr);
     return expr16(e1);
@@ -2174,12 +2176,14 @@
 	    break;
 	case EMPTY:
 	    if(getsym()==LPAR) {
-		nptr->sc = FUNCTION;
-		nptr->ty= INT;
-		type= list3(FUNCTION,INT,0);
+		nptr->sc = EXTRN1;
+		type= glist3(FUNCTION,INT,0);
+		nptr->ty= type;
 		e1=expr15(list2(FNAME,(int)nptr));
 		break;
 	    } else {
+		nptr->sc = EXTRN1;
+		nptr->ty= glist3(FUNCTION,INT,0);
 		e1=list2(FNAME,(int)nptr);
 		type=list3(nptr->sc,nptr->ty,nptr->dsp);
 		break;
@@ -2207,7 +2211,7 @@
 	break;
     case RETURN:
 	conv-> return_f_();
-	if (fnptr->sc != FUNCTION) {
+	if (!is_function(fnptr)) {
 	    error(STERR);
 	}
 	type=list2(POINTER,CODE);
@@ -2344,6 +2348,7 @@
 	    t = cadr(type); /* size */
 	    return list3(RSTRUCT,e,t);
 	} else if(t==FUNCTION) {
+	    type=cadr(type);
 	    return e;
 	} else if(t==CODE) {
 	    return e;
@@ -2646,14 +2651,14 @@
 	if (car(cadr(type))==FUNCTION||car(cadr(type))==CODE) {
 	    e1=rvalue(e1);
 	    type=cadr(type);
-	}
+	} /* else error */
     }
     if(integral(type)|| ((car(type)!=FUNCTION)&&(car(type)!=CODE))) {
 	error(TYERR);
     }
     conv->funcall_(type);
-    getsym();
     argtypes = caddr(type);
+    type = cadr(type); /* return type */
     if (!integral(t=cadr(type))&&(car(t)==STRUCT||car(t)==UNION)) {
 	/* skip return struct pointer */
 	if (argtypes==0) error(-1);
@@ -2661,6 +2666,7 @@
     }
     t=type;
     arglist=0;
+    getsym();
     while(sym!=RPAR) {
 	e=rvalue(expr1());
 	if(argtypes==0) at=DOTS;
@@ -2676,7 +2682,7 @@
     conv->funcall_args_();
     if(car(t)==CODE)
 	return list3(FUNCTION,e1,arglist);
-    type=cadr(t);
+    type=t;
     if(type==CHAR) type=INT;
     else if(car(type)==STRUCT||car(type)==UNION) {
 	/* make temporaly struct for return value */
@@ -3388,7 +3394,7 @@
 }
 
 void
-extern_define(char *s,int dsp,int type)
+extern_define(char *s,int d,int type)
 {
     NMTBL *nptr0;
     int i;
@@ -3400,7 +3406,7 @@
     if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR);
     name[i++] = 0;
     (nptr0 = gsearch())->sc = EXTRN;
-    nptr0->dsp = dsp; nptr0->ty=type;
+    nptr0->dsp = d; nptr0->ty=type;
 }
 
 static void
--- a/mc.h	Sat Mar 15 21:55:14 2003 +0900
+++ b/mc.h	Mon Mar 17 14:26:22 2003 +0900
@@ -19,7 +19,6 @@
 #define STRUCT	(-6)
 #define UNION	(-7)
 #define FUNCTION	(-8)
-#define EMPTY	(-9)
 
 #define STATIC	(-10)
 #define GOTO	(-11)
@@ -64,6 +63,8 @@
 #define DREGISTER       (-49)
 #define LONGLONG	(-50)
 
+#define EMPTY	(-99)
+
 #define TOP	0
 #define GDECL	1
 #define GSDECL	2
--- a/test/basic.c	Sat Mar 15 21:55:14 2003 +0900
+++ b/test/basic.c	Mon Mar 17 14:26:22 2003 +0900
@@ -57,6 +57,13 @@
     return a8;
 }
 
+int 
+h( int a0,int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
+{
+g( a0,a1,a2,a3,a4,a5,a6,a7,a8);
+}
+
+
 double 
 f(
 double a0,double a1,double a2,double a3,double a4,double a5,double a6,double a7,double a8
@@ -71,6 +78,7 @@
 void 
 tmp1 () { 
 
+    h(0,1,2,3,4,5,6,7,1);
 g(g(0,1,2,3,4,5,6,7,0),
     g(0,1,2,3,4,5,6,7,1),
     g(0,1,2,3,4,5,6,7,2),