changeset 260:9843979a270e

mips fix
author kono
date Sat, 15 May 2004 21:36:16 +0900
parents 18837238e306
children 31d7f050ec0d
files mc-code-mips.c mc-code-powerpc.c mc-parse.c stdio.h
diffstat 4 files changed, 202 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-mips.c	Sat May 15 21:11:01 2004 +0900
+++ b/mc-code-mips.c	Sat May 15 21:36:16 2004 +0900
@@ -1677,9 +1677,9 @@
 }
 
 int
-simple_args(int e3)
+simple_arg(int e3)
 {
-    return !contains_in_list_p(e3,not_simple_p);
+    return !contains_p(e3,not_simple_p);
 }
 
 int
@@ -1765,20 +1765,105 @@
     }
 }
 
+static void
+compute_complex_arg(int e3,int reg_arg_list,int arg) {
+    int t=caddr(e3);
+    int e4 = car(e3);
+    reg_arg_list = list2(arg,reg_arg_list);
+    g_expr_u(assign_expr0(arg,e4,t,t));
+    if (car(arg)==REGISTER||car(arg)==DREGISTER||
+	car(arg)==FREGISTER||car(arg)==LREGISTER)
+	use_input_reg(cadr(arg),1);
+    car(e3) = arg;
+}
+
+#define round4(i)   ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1))
+
+static void
+increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) {
+    int nargs=0,reg_arg=0,freg_arg=0;
+    int t=caddr(e3);
+    if(scalar(t)) {
+	nargs ++ ; reg_arg++;
+    } else if (t==LONGLONG||t==ULONGLONG||DOUBLE) {
+	nargs ++ ; reg_arg++;
+	nargs ++ ; reg_arg++;
+    } else if (t==FLOAT) {
+	nargs ++ ; reg_arg ++ ; freg_arg++;
+	nargs += size(t)/SIZE_OF_INT;
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	nargs += round4(size(t))/SIZE_OF_INT;
+    } else {
+	error(TYERR);
+	nargs ++ ;
+    }
+    *pnargs += nargs;
+    *preg_arg += reg_arg;
+    *pfreg_arg += freg_arg;
+}
+
+#define AS_SAVE 1
+#define AS_ARG  0
+
+static int
+get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) 
+{
+    if(scalar(t)) {
+	if (mode==AS_SAVE) {
+	    return get_register_var(0);
+	} else if (reg_arg>=MAX_INPUT_REGISTER_VAR) {
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	} else 
+	    return get_input_register_var(reg_arg,0,0);
+    } else if (t==LONGLONG||t==ULONGLONG) {
+	if (mode==AS_SAVE) {
+	    return get_lregister_var(0);
+	} else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR)  {
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	} else
+	    return get_input_lregister_var(reg_arg,0,0);
+    } else if (t==FLOAT) {
+	if (mode==AS_SAVE) {
+	    return get_dregister_var(0,0);
+	} else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) {
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	} else
+	    return get_input_dregister_var(freg_arg,0,0,0);
+    } else if (t==DOUBLE) {
+	if (mode==AS_SAVE) {
+	    return get_dregister_var(0,1);
+	} else if (reg_arg+1>=MAX_INPUT_DREGISTER_VAR) {
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	} else
+	    return get_input_dregister_var(freg_arg,0,0,1);
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	if (mode==AS_SAVE) {
+	    return get_register_var(0);
+	} else
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+    } else {
+	error(-1);
+	return get_register_var(0);
+    }
+}
+
 int
 function(int e1)
 {
-    int e2,e3,e4,nargs,t,r0;
+    int e2,e3,e4,e5,nargs,t,r0;
     int arg,reg_arg,freg_arg,arg_assign;
     int dots;
     int reg_arg_list=0,ret_type,special_lvar;
     NMTBL *fn = 0;
     int jmp = 0;
     char *jrn;
+    int complex_;
+    int pnargs,preg_arg,pfreg_arg;
+    int stargs;
 
     special_lvar = -1;
     ret_type = cadr(cadddr(e1));
-    if (ret_type==CHAR) ret_type=INT;
+    if (ret_type==CHAR) ret_type=INT;  // ???
 
     /* check argments type is DOTS? */
     t = caddr(cadddr(e1));
@@ -1802,6 +1887,42 @@
 	code_register(creg,cadr(jmp));
         /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */
     }
+    /* first we execute complex argument to avoid interaction with
+       input variables */
+    stargs = 0;
+    complex_ = 0;
+    nargs = reg_arg = freg_arg = 0;
+    for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
+	t=caddr(e3);
+	if ((e5= !simple_arg(car(e3)))) {
+	    if (complex_) {
+		arg = get_input_arg(caddr(complex_),AS_SAVE,
+					pnargs,preg_arg,pfreg_arg);
+		compute_complex_arg(complex_,reg_arg_list,arg);
+	    }
+	    pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
+	    complex_ = e3;
+	}
+	if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	    // The struct should be pushed after complex arguments.
+	    if (e5) { // compute address only, complex_ is me now. Clear it.
+		complex_ = 0;
+		e4 = car(e3);
+		if (car(e4)!=RSTRUCT) error(-1);
+		if (!simple_arg(cadr(e4))) {
+		    // Calculate complex struct address here.
+		    // If simple, leave it.
+		    arg = get_register_var(0);
+		    g_expr_u(assign_expr0(arg,list2(ADDRESS,car(e3)),INT,INT));
+		    car(e3)=arg;
+		    reg_arg_list = list2(arg,reg_arg_list);
+		    if (car(arg)==REGISTER) use_input_reg(cadr(arg),1);
+		}
+	    }
+	    stargs = list4(e3,stargs,nargs,reg_arg);
+	}
+	increment_function_arg(e3,&nargs,&reg_arg,&freg_arg);
+    }
 
     /* now all input register vars are free */
     code_save_stacks();
@@ -1809,117 +1930,94 @@
     set_freg(FREG_FREGISTER,0);
     set_ireg(CREG_REGISTER,0);
 
+    if (complex_) {
+	arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
+	compute_complex_arg(complex_,reg_arg_list,arg);
+    }
+    for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) {
+	e3 = car(stargs);
+	e4 = car(e3);
+	t  = caddr(e3);
+	arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
+	struct_push(e4,t,arg);
+	car(e3)=0;  // done
+    }
+
     nargs = reg_arg = freg_arg = arg_assign = 0;
-    for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
+    // calc stack arguments first
+    for (e3 = e1; e3; 
+		increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
+		e3 = cadr(e3)) {	
+	if (!(e4=car(e3))) continue;
 	t=caddr(e3);
-	e4 = car(e3);
+	arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg);
+	if (car(arg)!=LVAR) continue;
+	g_expr_u(assign_expr0(arg,e4,t,t));
+	if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) {
+	    if (reg_arg+1==MAX_INPUT_REGISTER_VAR) {
+		// half register, half memory case
+		arg_assign = list2(
+		    assign_expr0(r0=get_input_register_var(reg_arg,0,0),
+			arg,INT,INT),
+		    arg_assign);
+		use_input_reg(cadr(r0),1);
+	    }
+	}
+	car(e3)=0;  // done
+    }
+    nargs = reg_arg = freg_arg = 0;
+    for (e3 = e1; e3; 
+		increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
+		e3 = cadr(e3)) {	
+	if (!(e4=car(e3))) continue;
+	t=caddr(e3);
+	arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg);
 	if(scalar(t)) {
-	    if (reg_arg>=MAX_INPUT_REGISTER_VAR) { 
-		arg = list2(LVAR,caller_arg_offset_v(nargs));
-	    } else if (!simple_args(e3) && cadr(e3)) {
-		arg = get_register_var(0); 
-		arg_assign = list2(
-		    assign_expr0(get_input_register_var(reg_arg,0,0),
-			arg,t,t),
-		    arg_assign);
-	    } else {
-		arg = get_input_register_var(reg_arg,0,0); 
-	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
 	    /* protect from input register free */
 	    if (car(arg)==REGISTER)
 		use_input_reg(cadr(arg),1);
 	    g_expr_u(assign_expr0(arg,e4,t,t));
-	    nargs ++ ; reg_arg++;
-	    continue;
-	} else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) {
-	    if (reg_arg>=MAX_INPUT_REGISTER_VAR) { 
-		arg = list2(LVAR,caller_arg_offset_v(nargs));
-	    } else if (!simple_args(e3) && cadr(e3)) {
-		arg = t==DOUBLE?get_dregister_var(0,1):get_lregister_var(0); 
-                if (car(arg)==LREGISTER||car(arg)==DREGISTER) {
-                    // r0=get_input_lregiste... is not preserved
-                    // we cannot mark r0 used, it consumes unused register
-                    // but get_input_register is preserved.
-		    // Beware endian.
-                    arg_assign = list2(
-                        assign_expr0(get_input_register_var(reg_arg,0,0),
-                            list2(REGISTER,regv_l(cadr(arg))),INT,INT), 
-                        list2(
-                        assign_expr0(get_input_register_var(reg_arg+1,0,0),
-                            list2(REGISTER,regv_h(cadr(arg))),INT,INT), 
-                        arg_assign));
-                } else {
-                    arg_assign = list2(
-                        assign_expr0(get_input_register_var(reg_arg,0,0),
-                            list2(LVAR,cadr(arg)),INT,INT), 
-                        list2(
-                        assign_expr0(get_input_register_var(reg_arg+1,0,0),
-                            list2(LVAR,cadr(arg)+SIZE_OF_INT),INT,INT), 
-                        arg_assign));
-                }
-
+	} else if (t==LONGLONG||t==ULONGLONG) {
+	    if (reg_arg+1==MAX_INPUT_REGISTER_VAR) { 
+		// half register, half memory case
+		// put whole long long anyway
+		arg_assign = list2(
+		    assign_expr0(r0=get_input_register_var(reg_arg,0,0),
+			arg,INT,INT),
+		    arg_assign);
+		use_input_reg(cadr(r0),1);
 	    } else {
-		arg = t==DOUBLE?get_input_dregister_var(reg_arg,0,0,1):
-		                get_input_lregister_var(reg_arg,0,0);
-		use_input_reg(cadr(arg),1);
+		if (car(arg)==LREGISTER)
+		    use_input_reg(cadr(arg),1);
 	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
 	    g_expr_u(assign_expr0(arg,e4,t,t));
-	    nargs ++ ; reg_arg++;
-	    nargs ++ ; reg_arg++;
-	    continue;
+	} else if (t==DOUBLE) {
+	    reg_arg_list = list2(arg,reg_arg_list);
+	    if (car(arg)==DREGISTER)
+		use_input_reg(cadr(arg),1);
 	} else if (t==FLOAT) {
-	    if (freg_arg>=MAX_INPUT_FREGISTER_VAR) {
-		arg = list2(LVAR,caller_arg_offset_v(nargs));
-	    } else if (!simple_args(e3) && cadr(e3)) {
-		arg = get_dregister_var(0,0); 
-		if (freg_arg<2) {
-		    arg_assign = list2(
-			list3(FASS_INPUT, 
-			    get_input_dregister_var(freg_arg,0,0,0),arg),
-		    arg_assign);
-		} else {
-		    arg_assign = list2(
-		    assign_expr0(get_input_dregister_var(freg_arg,0,0,0),
-			arg,t,t),
-		    arg_assign);
-		}
-	    } else {
-		arg = get_input_dregister_var(freg_arg,0,0,0); 
-	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
-	    if (car(arg)==FREGISTER) {
+            if (car(arg)==FREGISTER) {
+                use_input_reg(cadr(arg),1);/* protect from input register free */
+                g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */
+            } else if (car(arg)==REGISTER) {
 		use_input_reg(cadr(arg),1);/* protect from input register free */
-		g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */
-	    } else if (car(arg)==REGISTER) {
-		code_assign_input_float_int(list3(FASS_INPUT, arg, e4));
-	    } else {
-		g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */
-	    }
-	    freg_arg++;
-	    nargs += size(t)/SIZE_OF_INT;
-	    continue;
-	} else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
-	    arg = list2(LVAR,caller_arg_offset_v(nargs));
-	    nargs += struct_push(e4,t,arg);
-	    continue;
-	} else {
-	    error(TYERR);
+                code_assign_input_float_int(list3(FASS_INPUT, arg, e4));
+            } else {
+                g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */
+            }
 	}
-	++nargs;
+	// structs are finished
     }
     if (max_func_args<nargs) max_func_args=nargs;
     for(;arg_assign;arg_assign=cadr(arg_assign)) {
-	if (car(car(arg_assign))==FASS_INPUT) {
-	    code_assign_input_float_int(car(arg_assign));
-	} else {
-	    g_expr_u(car(arg_assign));
-	}
+	g_expr_u(car(arg_assign));
     }
     clear_ptr_cache();
-    if (car(e2) == FNAME) {	
-	printf("\tjal\t%s\n",fn->nm);
+    if (car(e2) == FNAME) {
+        printf("\tjal\t%s\n",fn->nm);
     } else {
         jrn = register_name(cadr(jmp));
         printf("\tj %s\n",jrn);
@@ -1932,16 +2030,16 @@
 	else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg));
     }
     if (ret_type==DOUBLE) {
-	set_dreg(RET_DREGISTER,0);
-	use_reg(RET_DREGISTER);
-    } else if (ret_type==DOUBLE||ret_type==FLOAT) {
-	set_freg(RET_FREGISTER,0);
+        set_dreg(RET_DREGISTER,0);
+        use_reg(RET_DREGISTER);
+    } else if (ret_type==FLOAT) {
+        set_freg(RET_FREGISTER,0);
     } else if (ret_type==ULONGLONG||ret_type==LONGLONG) {
-	set_lreg(RET_LREGISTER,0);
-	use_reg(RET_LREGISTER);
+        set_lreg(RET_LREGISTER,0);
+        use_reg(RET_LREGISTER);
     } else if (ret_type==VOID) {
     } else {
-	set_ireg(RET_REGISTER,0);
+        set_ireg(RET_REGISTER,0);
     }
     return ret_type;
 }
--- a/mc-code-powerpc.c	Sat May 15 21:11:01 2004 +0900
+++ b/mc-code-powerpc.c	Sat May 15 21:36:16 2004 +0900
@@ -127,7 +127,7 @@
     "f30","f31"
 }; 
 
-#define round4(i)   ((i+3)&~3)
+#define round4(i)   ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1))
 
 #define register_name(i)  reg_name[i]
 #define fregister_name(i) reg_name[i]
--- a/mc-parse.c	Sat May 15 21:11:01 2004 +0900
+++ b/mc-parse.c	Sat May 15 21:36:16 2004 +0900
@@ -1024,7 +1024,7 @@
 	    args += size_of_int;
 	} else if(type>0&&(type==UNION||type==STRUCT)) {
 	    n->dsp = args;
-	    args += ((sz+(size_of_int-1))&~size_of_int);
+	    args += ((sz+(size_of_int-1))&~(size_of_int-1));
 	} else {
 	    /* if (n->dsp==0) (argument list in ADECL is useless, type
                list can be found in type ) */
--- a/stdio.h	Sat May 15 21:11:01 2004 +0900
+++ b/stdio.h	Sat May 15 21:36:16 2004 +0900
@@ -1,4 +1,4 @@
-#ifndef __micro_c__aaa
+#ifndef __micro_c__
 #include "/usr/include/stdio.h"
 long long strtoll(const char *, char **, int);
 #else