changeset 400:a9427845ca4c

ARM test/basic test pass.
author kono
date Sat, 16 Oct 2004 16:08:41 +0900
parents 9d0015a1fa54
children d621a113b0ca
files Makefile mc-code-arm.c
diffstat 2 files changed, 33 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sat Oct 16 10:29:51 2004 +0900
+++ b/Makefile	Sat Oct 16 16:08:41 2004 +0900
@@ -83,6 +83,7 @@
 	make check TARGET=test/bitfield
 	make check TARGET=test/bitfield1
 	make check TARGET=test/cext
+	make check TARGET=test/const
 #	make check TARGET=test/scope STDFLAG="-std=gnu99"
 #MK =-make
 MK=
--- a/mc-code-arm.c	Sat Oct 16 10:29:51 2004 +0900
+++ b/mc-code-arm.c	Sat Oct 16 16:08:41 2004 +0900
@@ -39,6 +39,7 @@
 static int search_const(int tag,int value,int *label);
 static char * cstore(int sz);
 static void code_int_lib(char *lib,int reg,int oreg); 
+static int caller_arg_offset_v(int arg);
 #if FLOAT_CODE
 static int code_d1(double d);
 static int code_d2(double d);
@@ -2131,18 +2132,27 @@
 	if (!n||n==&null_nptr) error(REG_ERR);
 	if (tag==REGISTER) {
 	    /* regs[reg]==INPUT_REG case should be considered */
-	    n->dsp = new_lvar(SIZE_OF_INT);
+	    n->dsp = new_lvar(SIZE_OF_INT); n->sc  = LVAR;
 	    offset+=SIZE_OF_INT;
 	    t = INT;
 	    reg_var++;
 	} else if (tag==LREGISTER) {
 	    /* regs[reg]==INPUT_REG case should be considered */
-	    n->dsp = new_lvar(SIZE_OF_LONGLONG);
+	    n->dsp = new_lvar(SIZE_OF_LONGLONG); n->sc  = LVAR;
 	    // t = n->ty;
 	    t = LONGLONG;
 	    offset+=SIZE_OF_LONGLONG; reg_offset+=2;
 	    reg_var += 2;
 	} else {
+	    if (reg_var==3 && (n->ty==DOUBLE||n->ty==LONGLONG||n->ty==ULONGLONG)) {
+		// half register, half stack case
+		n->dsp = new_lvar(SIZE_OF_LONGLONG); n->sc  = LVAR;
+		g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(REGISTER,4,0),INT,INT));
+		g_expr_u(assign_expr0(list2(LVAR,n->dsp+SIZE_OF_INT),
+		    list2(LVAR,caller_arg_offset_v(offset)),INT,INT));
+		free_register(4);
+		offset -= SIZE_OF_INT;
+	    }
 	    offset += size(n->ty);
 	    continue;
 	}
@@ -2181,7 +2191,7 @@
     return !contains_p(e3,not_simple_p);
 }
 
-int
+static int
 caller_arg_offset_v(int arg)
 {
     return ARG_LVAR_OFFSET+arg*SIZE_OF_INT;
@@ -2317,8 +2327,14 @@
     if(scalar(t)) {
 	nargs ++ ; reg_arg++;
     } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) {
-	if (*preg_arg%2==1) reg_arg++;  // alignment
-        if (*pnargs%2==1) nargs++;  // alignment
+#if 0
+	if (*preg_arg>3 && *preg_arg%2==1) reg_arg++;  // alignment
+        if (*preg_arg>3 && *pnargs%2==1) nargs++;  // alignment
+	if (*preg_arg==3) {
+	    // half register, half stack case
+	    nargs --;
+	}
+#endif
 	nargs ++ ; reg_arg++;
 	nargs ++ ; reg_arg++;
     } else if (t==FLOAT) {
@@ -2349,8 +2365,6 @@
 	} else 
 	    return get_input_register_var(reg_arg,0,0);
     } else if (t==LONGLONG||t==ULONGLONG) {
-	if (reg_arg%2==1) reg_arg++;  // alignment
-        if (nargs%2==1) nargs++;  // alignment
 	if (mode==AS_SAVE) {
 	    return get_lregister_var(0);
 	} else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR)  {
@@ -2408,6 +2422,7 @@
     int complex_;
     int pnargs,preg_arg,pfreg_arg;
     int stargs;
+    int half_register = 0;
 
     special_lvar = -1;
     ret_type = cadr(cadddr(e1));
@@ -2446,12 +2461,16 @@
     nargs = reg_arg = freg_arg = 0;
     for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
 	t=caddr(e3);
+	if (reg_arg==3 && (t==DOUBLE||t==LONGLONG||t==ULONGLONG)) {
+	    half_register=1;
+	}
 	if ((e5= !simple_arg(car(e3)))) {
 	    if (complex_) {
 		arg = get_input_arg(caddr(complex_),AS_SAVE,
 					pnargs,preg_arg,pfreg_arg);
 		reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg);
 	    }
+	    // memorise last complex arg parameter
 	    pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
 	    complex_ = e3;
 	}
@@ -2566,6 +2585,12 @@
     for(;arg_assign;arg_assign=cadr(arg_assign)) {
 	g_expr_u(car(arg_assign));
     }
+    if (half_register) {
+	//  half register case writes *(sp-1) but it will be Ok.
+	if (max_func_args<4) max_func_args=4;
+	g_expr_u(assign_expr0(list3(REGISTER,4,0),
+		list2(LVAR,caller_arg_offset_v(3)),INT,INT));
+    }
     clear_ptr_cache();
     code_call(e2,fn,jmp);
     for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {