changeset 256:d80e6387c539

powerpc function call complex arugment pre computation. (incomplete)
author kono
date Sat, 15 May 2004 12:04:56 +0900
parents 8cd8d72286ae
children e2f5671c413d
files Changes mc-code-powerpc.c mc-codegen.c
diffstat 3 files changed, 121 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri May 14 20:57:52 2004 +0900
+++ b/Changes	Sat May 15 12:04:56 2004 +0900
@@ -4207,3 +4207,5 @@
 その部分はcodegen でやってもいいんだけど... ia32 のような場合は
 むしろ不要なのか。
 
+でも、やっぱり、意外に複雑だよ。struct をどうするかとかさ。
+
--- a/mc-code-powerpc.c	Fri May 14 20:57:52 2004 +0900
+++ b/mc-code-powerpc.c	Sat May 15 12:04:56 2004 +0900
@@ -127,6 +127,8 @@
     "f30","f31"
 }; 
 
+#define round4(i)   ((i+3)&~3)
+
 #define register_name(i)  reg_name[i]
 #define fregister_name(i) reg_name[i]
 #define lregister_name_low(i) reg_name[regv_l(i)]
@@ -1648,10 +1650,10 @@
 	e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD;
 }
 
-int
-simple_args(int e3)
+static int
+simple_arg(int e3)
 {
-    return !contains_in_list_p(e3,not_simple_p);
+    return !contains_p(e3,not_simple_p);
 }
 
 int
@@ -1697,6 +1699,88 @@
     if (mode) use_reg(reg);
 }
 
+static void
+compute_complex_arg(int e3,int reg_arg_list,int arg,int stack) {
+    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 (stack) {
+	car(e3) = 0;
+    } else {
+	if (car(arg)==REGISTER||car(arg)==DREGISTER||
+	    car(arg)==FREGISTER||car(arg)==LREGISTER)
+	    use_input_reg(cadr(arg),1);
+	car(e3) = arg;
+    }
+}
+
+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) {
+	nargs ++ ; reg_arg++;
+	nargs ++ ; reg_arg++;
+    } else if (t==DOUBLE||t==FLOAT) {
+	if (*preg_arg<MAX_INPUT_REGISTER_VAR) {
+	    reg_arg += 2;
+	}
+	freg_arg++;
+	nargs += size(t)/SIZE_OF_INT;
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	nargs += round4(size(t));
+    } else {
+	error(TYERR);
+    }
+    ++nargs;
+    *pnargs += nargs;
+    *preg_arg += reg_arg;
+    *pfreg_arg += freg_arg;
+}
+
+static int
+get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg,int *stack) 
+{
+    *stack = 0;
+    if(scalar(t)) {
+	if (reg_arg>=MAX_INPUT_REGISTER_VAR) {
+	    *stack = 1;
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	}
+	return mode?get_register_var(0):get_input_register_var(reg_arg,0,0);
+    } else if (t==LONGLONG||t==ULONGLONG) {
+	if (reg_arg>=MAX_INPUT_REGISTER_VAR)  {
+	    *stack = 1;
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	}
+	return mode?get_lregister_var(0):get_input_lregister_var(reg_arg,0,0);
+    } else if (t==FLOAT) {
+	if (freg_arg>=MAX_INPUT_DREGISTER_VAR) {
+	    *stack = 1;
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	}
+	return mode?get_dregister_var(0,0):
+		get_input_dregister_var(freg_arg,0,0,0);
+    } else if (t==DOUBLE) {
+	if (freg_arg>=MAX_INPUT_DREGISTER_VAR) {
+	    *stack = 1;
+	    return list2(LVAR,caller_arg_offset_v(nargs));
+	}
+	return mode?get_dregister_var(0,1):
+		get_input_dregister_var(freg_arg,0,0,1);
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	*stack = 1;
+	return list2(LVAR,caller_arg_offset_v(nargs));
+    } else {
+	error(-1);
+	*stack = 1;
+	return list2(LVAR,caller_arg_offset_v(nargs));
+    }
+}
+
 int
 function(int e1)
 {
@@ -1707,6 +1791,9 @@
     NMTBL *fn = 0;
     int jmp = 0;
     char *jrn;
+    int complex;
+    int pnargs,preg_arg,pfreg_arg;
+    int stack;
 
     special_lvar = -1;
     ret_type = cadr(cadddr(e1));
@@ -1734,6 +1821,20 @@
 	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 */
+    complex = 0;
+    nargs = reg_arg = freg_arg = arg_assign = 0;
+    for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
+	t=caddr(e3);
+	if (complex) {
+	    arg = get_input_arg(t,1,pnargs,preg_arg,pfreg_arg,&stack);
+	    compute_complex_arg(complex,reg_arg_list,arg,stack);
+	}
+	if (simple_arg(car(complex=e3))) complex=0;
+	pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
+	increment_function_arg(e3,&nargs,&reg_arg,&freg_arg);
+    }
 
     /* now all input register vars are free */
     code_save_stacks();
@@ -1741,71 +1842,41 @@
     set_freg(FREG_FREGISTER,0);
     set_ireg(CREG_REGISTER,0);
 
+    if (complex) {
+	arg = get_input_arg(caddr(complex),0,pnargs,preg_arg,pfreg_arg,&stack);
+	compute_complex_arg(complex,reg_arg_list,arg,stack);
+    }
+
     nargs = reg_arg = freg_arg = arg_assign = 0;
-    for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
+    for (e3 = reverse0(caddr(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,0,nargs,reg_arg,freg_arg,&stack);
 	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) {
 	    if (reg_arg>=MAX_INPUT_REGISTER_VAR) { 
-		arg = list2(LVAR,caller_arg_offset_v(nargs));
 	    } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { 
 		// half register, half memory case
 		// put whole long long anyway
-		arg = list2(LVAR,caller_arg_offset_v(nargs));
 		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 if (!simple_args(e3) && cadr(e3)) {
-		arg = get_lregister_var(0); 
-		if (car(arg)==LREGISTER) {
-		    // r0=get_input_lregiste... is not preserved
-		    // we cannot mark r0 used, it consumes unused register
-		    // but get_input_register is preserved.
-		    arg_assign = list2(
-			assign_expr0(get_input_register_var(reg_arg,0,0),
-			    list2(REGISTER,regv_h(cadr(arg))),INT,INT), 
-			list2(
-			assign_expr0(get_input_register_var(reg_arg+1,0,0),
-			    list2(REGISTER,regv_l(cadr(arg))),INT,INT), 
-			arg_assign));
-		} else {
-		    arg_assign = list2(
-			assign_expr0(get_input_register_var(reg_arg,0,0),
-			    list2(LVAR,cadr(arg)+SIZE_OF_INT),INT,INT), 
-			list2(
-			assign_expr0(get_input_register_var(reg_arg+1,0,0),
-			    list2(LVAR,cadr(arg)),INT,INT), 
-			arg_assign));
-		}
 	    } else {
-		arg = 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||t==FLOAT) {
 	    if (reg_arg<MAX_INPUT_REGISTER_VAR) {
@@ -1839,7 +1910,6 @@
 			    list2(LVAR,special_lvar+SIZE_OF_INT),
 			    INT,INT), arg_assign);
 		}
-		reg_arg += 2;
 	    }
 	    if (dots && freg_arg>=4 && freg_arg<MAX_INPUT_DREGISTER_VAR) { 
 		/* oh my god! 
@@ -1851,32 +1921,17 @@
 			    get_input_dregister_var(freg_arg,0,0,1),t,t),
 		    arg_assign);
 	    }
-	    if (freg_arg>=MAX_INPUT_DREGISTER_VAR) {
-		arg = list2(LVAR,caller_arg_offset_v(nargs));
-	    } else if (!simple_args(e3) && cadr(e3)) {
-		arg = get_dregister_var(0,1); 
-		arg_assign = list2(
-		    assign_expr0(get_input_dregister_var(freg_arg,0,0,1),
-			arg,t,t),
-		    arg_assign);
-	    } else {
-		arg = get_input_dregister_var(freg_arg,0,0,1); 
-	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
 	    if (car(arg)==DREGISTER)
 		use_input_reg(cadr(arg),1); /* protect from input register free */
 	    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);
+            struct_push(e4,t,arg);
 	    continue;
 	} else {
 	    error(TYERR);
 	}
-	++nargs;
     }
     if (max_func_args<nargs) max_func_args=nargs;
     for(;arg_assign;arg_assign=cadr(arg_assign)) {
--- a/mc-codegen.c	Fri May 14 20:57:52 2004 +0900
+++ b/mc-codegen.c	Sat May 15 12:04:56 2004 +0900
@@ -1636,6 +1636,7 @@
 {
     while(e) {
 	if (car(e)==type) return 1;
+	if (!car(e)) return 0;
 	if (LIST_ARGS(car(e))){
         /* list arguments */
 	    return contains_in_list(caddr(e),type);
@@ -1680,6 +1681,7 @@
 contains_p(int e,int (*p)(int))
 {
     while(e) {
+	if (!car(e)) return 0;
 	if (p(car(e))) return 1;
 	if (LIST_ARGS(car(e))){
         /* list arguments */