diff mc-codegen.c @ 782:003067098032

code argument offset in caller and callee
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 20 Nov 2010 10:55:31 +0900
parents b8cb4e1ac922
children feeb9b9f8236
line wrap: on
line diff
--- a/mc-codegen.c	Fri Nov 19 18:57:36 2010 +0900
+++ b/mc-codegen.c	Sat Nov 20 10:55:31 2010 +0900
@@ -108,6 +108,11 @@
     init_free_lvar_list();
 }
 
+/**
+    make register argments
+    and save it into memory (sigh...)
+    we should postpone code_save_argument_register
+ */
 extern void 
 arg_register(NMTBL *fnptr)
 {
@@ -1472,6 +1477,7 @@
 // maximum size of struct divide (don't make it large)
 
 #define ASSIGN_STRUCT_DIVIDE 40
+#define ARG_OFFSET_CODE 1
 
 extern void
 jump(int e1, int env)
@@ -1488,6 +1494,7 @@
     /* e1 = list4(FUNCTION,code_segment,arglist,ftype); */
 
     if (env) {
+        error(-1); // not supported
 	envreg = get_register_var(0);
 	g_expr_u(assign_expr0(envreg,env,int_type,int_type));
     }
@@ -1526,9 +1533,12 @@
 	    target=list5(list3n(LVAR,0,0), target,ty,e2,0);
 	}
         /* keep arg space for register variables */
-        // NMTBL n;
-	// arg_size = code_arg_alignment(arg_size, &n, ty, sz);
+#if ARG_OFFSET_CODE
+        NMTBL n;
+	arg_size = code_arg_alignment(arg_size, &n, ty, sz,1);
+#else
         arg_size += sz;
+#endif
 #if DEBUG_PARALLEL_ASSIGN
 if (lsrc)printf("## target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz);
 #endif
@@ -1549,19 +1559,27 @@
     /*  複雑な式を前もって計算しておく     */
     /*  必要なら局所変数を用いる。         */
     /*  局所変数へのオフセットを覚えておく */
-    // int arg_offset = 0;
+#if ARG_OFFSET_CODE
+    NMTBL n;
+    n.dsp = 0;
+    int arg_offset = 0;
+    target = reverse0(target); 
+#endif
     for (e2 = target; e2; e2 = cadr(e2)) {	
 	t0=car(e2); s0=cadddr(e2);
 	sz=size(ty=caddr(e2));
+#if ARG_OFFSET_CODE
+	/* ここで、書込先アドレスを決める */
+	arg_offset = code_arg_alignment(arg_offset, &n, ty, sz,1);
 	if(car(t0)==LVAR) {
-	    /* ここで、書込先アドレスを決める */
-	    if (envreg) error(-1);
-	    // NMTBL n;
-	    // arg_offset = code_arg_alignment(arg_offset, &n, ty, sz);
-	    // cadr(t0) = arg_offset - n.dsp;
+	    cadr(t0) = n.dsp;
+	}
+#else
+	if(car(t0)==LVAR) {
 	    cadr(t0)=-arg_size;    // disp_offset?!
 	}
         arg_size-=sz;
+#endif
 #ifdef SAVE_ALL_NON_MEMORY
 	if (!is_simple(car(s0))) {
 #else
@@ -1576,7 +1594,7 @@
         } else if (is_same_type(t0,s0)) {
             if(cadr(t0)==cadr(s0)) {
 		if(is_writable(s0)) {
-		    caddddr(e2)=list3(s0,0,sz);
+		    caddddr(e2)=list3(s0,0,sz); // これなんだっけ?
 		    continue;
 		} else
 		    error(-1);
@@ -1607,8 +1625,7 @@
 		    case 2:
 		    case 3: caddr(e2) = USHORT; r = size_of_short; break;
 		    case 4: if (lp64) { caddr(e2) = UNSIGNED; r = size_of_int; break; }
-		    default: if (lp64) { caddr(e2) = ULONGLONG; r = int_size; break; }
-		             caddr(e2) = UNSIGNED; r = size_of_int;
+		    default: caddr(e2) = int_unsigned; r = size_of_int;
 		    }
 		    if (e4==int_size) e3=cadr(e2);
 		    car(e2) =  list3n(LVAR,cadr(t0)+e4,0);
@@ -3499,7 +3516,7 @@
 	    n->dsp = args++;
 	    n->sc = IVAR;
 	} else {
-	    args = code_arg_alignment(args,n,type0,sz);
+	    args = code_arg_alignment(args,n,type0,sz, is_code(fnptr));
 	}
 
 	caddr(fnptr->dsp)=sz;
@@ -3555,34 +3572,68 @@
 
 // standard 32bit alignment 
 
+// for code
 extern int
-code_arg_alignment0(int args,NMTBL *n, int type0,int sz)
+code_arg_alignment1(int offset,NMTBL *n, int type0,int sz, int is_code)
 {
     if(type0==CHAR||type0==UCHAR) {
         if (n->dsp==0) {
-            n->dsp = args;
+            n->dsp = -offset;
             if (endian) n->dsp += size_of_int-1;
         }
-        args += size_of_int;
+        offset += size_of_int;
     } else if(type0==SHORT||type0==USHORT) {
         if (n->dsp==0) {
-            n->dsp = args;
+            n->dsp = -offset;
             if (endian) n->dsp += size_of_int-size_of_short;
         }
-        args += size_of_int;
+        offset += size_of_int;
     } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
         /* alignment in struct in argument */
         /* should be GCD of member alignment */
         /* __attribute(alignment(16)) is ignored in argments */
-        n->dsp = args;
-        args += align(sz,size_of_int);
+        n->dsp = -offset;
+        offset += align(sz,size_of_int);
     } else {
         /* if (n->dsp==0) (argument list in ADECL is useless, type
            list can be found in type ) */
-        n->dsp = args;
-        args += sz; 
-    }
-    return args;
+        n->dsp = -offset;
+        offset += sz; 
+    }
+    return offset;
+}
+
+// for function
+extern int
+code_arg_alignment0(int offset,NMTBL *n, int type0,int sz, int is_code)
+{
+    if (is_code) return code_arg_alignment1(offset,n,type0,sz,is_code);
+
+    if(type0==CHAR||type0==UCHAR) {
+        if (n->dsp==0) {
+            n->dsp = offset;
+            if (endian) n->dsp += size_of_int-1;
+        }
+        offset += size_of_int;
+    } else if(type0==SHORT||type0==USHORT) {
+        if (n->dsp==0) {
+            n->dsp = offset;
+            if (endian) n->dsp += size_of_int-size_of_short;
+        }
+        offset += size_of_int;
+    } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
+        /* alignment in struct in argument */
+        /* should be GCD of member alignment */
+        /* __attribute(alignment(16)) is ignored in argments */
+        n->dsp = offset;
+        offset += align(sz,size_of_int);
+    } else {
+        /* if (n->dsp==0) (argument list in ADECL is useless, type
+           list can be found in type ) */
+        n->dsp = offset;
+        offset += sz; 
+    }
+    return offset;
 }
 
 // standard 32bit alignment for local variable
@@ -3605,9 +3656,9 @@
 
 // for mc-parse.c
 extern int
-arg_alignment(int args,NMTBL *n, int type0,int sz)
+arg_alignment(int args,NMTBL *n, int type0,int sz, int is_code)
 {
-    return code_arg_alignment(args,n, type0,sz);
+    return code_arg_alignment(args,n, type0,sz, is_code);
 }
 
 extern char *