changeset 403:562d76edddee

arg on register
author kono
date Sun, 17 Oct 2004 11:23:10 +0900
parents cda558feec30
children 95956779df2e
files .gdbinit mc-code-arm.c
diffstat 2 files changed, 34 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Sun Oct 17 00:04:48 2004 +0900
+++ b/.gdbinit	Sun Oct 17 11:23:10 2004 +0900
@@ -6,8 +6,8 @@
 # run  -s -ob01.s mc-switch.c
 # run  -s l.c
 # run  -s test/const.c
-# run  -s test/basic.c
-run -s test/code-gen-all.c
+run  -s test/basic.c
+# run -s test/code-gen-all.c
 define regs 
 printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4
 printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
--- a/mc-code-arm.c	Sun Oct 17 00:04:48 2004 +0900
+++ b/mc-code-arm.c	Sun Oct 17 11:23:10 2004 +0900
@@ -58,6 +58,7 @@
 // static int r1_offset_label;
 static int lvar_offset_label;
 static int    max_func_args = 0;
+static int arg_on_register = 0;
 
 
 static int freg,ireg,lreg;
@@ -327,7 +328,7 @@
                       prev $sp=$fp                                   $sp=$fp
  */
 
-#define arg_offset (-12)
+#define arg_offset (4)
 #define arg_offset1 (-16)
 int disp_offset=0;    // fore mc-codegen.c
 #define disp_offset  0
@@ -1945,19 +1946,29 @@
 {
     int length,count;
     int dreg,sreg; char *drn,*crn,*srn;
+    int arg_disp = cadr(arg);
     g_expr(e4);
     if (!is_int_reg(creg)) error(-1);
     length=size(t);
     if(length%SIZE_OF_INT) {
         length += SIZE_OF_INT - (length%SIZE_OF_INT);
     }
+    crn = register_name(creg);
+    count = 0;
+    dreg = 1-CALLER_ARG(arg_disp-ARG_LVAR_OFFSET)/SIZE_OF_INT;
+    while (arg_disp>=ARG_LVAR_OFFSET && CALLER_ARG(arg_disp-ARG_LVAR_OFFSET)<0) {
+	/* some part will be in registers */
+	printf("\tldr\t%s, [%s, #%d]\n", register_name(dreg), crn,count);
+	count += SIZE_OF_INT; length-=SIZE_OF_INT; arg_disp+= SIZE_OF_INT;
+	dreg ++;
+    }
+    if (!(length>0)) return length/SIZE_OF_INT;
     dreg = get_register(); if (!dreg) error(-1);
     drn = register_name(dreg);
-    crn = register_name(creg);
     if (length<MAX_COPY_LEN) {
         sreg = get_register(); if (!sreg) error(-1);
         srn = register_name(sreg);
-        code_lvar(cadr(arg),dreg);
+        code_lvar(arg_disp,dreg);
         for(count=0;count<length;count+=SIZE_OF_INT) {
 	    inc_inst(2);
             printf("\tldr\t%s, [%s, #%d]\n",srn,crn,count);
@@ -1967,7 +1978,7 @@
         free_register(dreg);
         return length/SIZE_OF_INT;
     } else {
-        code_lvar(cadr(arg),dreg);
+        code_lvar(arg_disp,dreg);
         /* downward direction copy */
         emit_copy(creg,dreg,length,0,0,1);
     }
@@ -2119,51 +2130,29 @@
     NMTBL *n;
     int reg;
     int tag;
-    int t;
     /* fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); */
-    int reg_offset = 0;
     int offset = 0;
     int reg_var = 0;
+    int len;
+    arg_on_register = 0;
 
     for(args = fnptr->dsp;args;args = cadr(args)) {
 	n = (NMTBL *)caddr(args);
 	tag = n->sc;
 	reg = n->dsp;
 	if (!n||n==&null_nptr) error(REG_ERR);
-	if (tag==REGISTER) {
-	    /* regs[reg]==INPUT_REG case should be considered */
-	    if (struct_return && !cadr(args)) {
-		cadr(car(struct_return)) = n->dsp = new_lvar(SIZE_OF_INT);
-	    } else {
-		n->dsp = new_lvar(SIZE_OF_INT);
+	if (reg_var<MAX_INPUT_REGISTER_VAR) {
+	    n->dsp = offset;
+	    n->sc  = LVAR;
+	    len = size(n->ty); len = round4(len);
+	    for(;len>0 && reg_var<MAX_INPUT_REGISTER_VAR;len-=SIZE_OF_INT) {
+		reg_var++;
+		g_expr_u(assign_expr0(list2(LVAR,offset),
+			list3(REGISTER,reg_var,0),INT,INT));
+		arg_on_register += SIZE_OF_INT;
+		free_register(reg);
+		offset += SIZE_OF_INT;
 	    }
-	    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);
-	    // 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;
-	}
-	n->sc  = LVAR;
-	g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t));
-	if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) {
-	    free_register(reg);
 	}
     }
     if (dots) {
@@ -2172,6 +2161,7 @@
                 list2(LVAR,offset),reg,INT,INT));
             offset+=SIZE_OF_INT;
             reg_var++;
+	    arg_on_register += SIZE_OF_INT;
         }
     }
     my_func_args = offset;
@@ -3346,11 +3336,11 @@
 //  entry part  (save register)
 
     fwddef(entry_label);
+    if (arg_on_register>0)
+	printf("\tsub\tsp, sp, #%d\n",arg_on_register);
     code_register_save(max_reg_var,max_freg_var,0);
 
-    // code_add(REG_fp,-4,REG_ip);
-    printf("\tsub\tfp, ip, #4\n");
-
+    printf("\tsub\tfp, ip, #%d\n",4+arg_on_register);
     code_add(REG_sp,disp-max_func_args*SIZE_OF_INT,REG_sp);
     jmp(register_save_return_label);
     local_table();