changeset 762:236d49777503

i64 continue integer pass
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 17 Nov 2010 16:22:51 +0900
parents 684dcbd0e170
children 3c09f0b8b377
files mc-code-i64.c
diffstat 1 files changed, 46 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Wed Nov 17 12:16:08 2010 +0900
+++ b/mc-code-i64.c	Wed Nov 17 16:22:51 2010 +0900
@@ -509,6 +509,7 @@
 
 #define round16(i)   align(i,16)
 #define round4(i)    align(i,4)
+#define round8(i)    align(i,8)
 
 
 #define func_disp_offset (16)
@@ -529,7 +530,8 @@
 #define CALLEE_ARG(l) ((l)+arg_offset)
 static int r1_offset_label;
 static const char lpfx[] = "_";
-// static int lvar_offset_label;
+static int lvar_offset_label;
+static int reg_in_arg;
 static int max_func_args,max_func_arg_label;
 
 /*
@@ -571,7 +573,6 @@
 	printf("\t.set _%d,%d\n",code_disp_label,r1_offsetv);
     } else {
 	//  +8 makes esp alignment 16
-    //    printf(".set %s%d,%d\n",lpfx,lvar_offset_label,lvar_offsetv);
 	if (r1_offsetv-lvar_offsetv > 65000) error(-1);
 	    // too large function arguments?
 	// printf(".set %s%d,%d\n",lpfx,r1_offset_label,r1_offsetv);
@@ -618,7 +619,7 @@
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
         printf("%d(%%rsp)",CALLER_ARG(l-ARG_LVAR_OFFSET));
     } else { /* callee's arguments */
-        printf("%d(%%rbp)",CALLEE_ARG(l));
+        printf("%d-_%d(%%rbp)",CALLEE_ARG(l), lvar_offset_label);
     }
 }
 
@@ -1094,7 +1095,7 @@
     we need this always because of one path compiler
  */
 static void
-code_save_input_registers(int dots)
+code_save_input_registers(int dots, int arg_size)
 {
     int args;
     NMTBL *n;
@@ -1105,6 +1106,11 @@
     int reg_var = 0;
     int freg_var = 0;
 
+    disp -= arg_size;
+    offset = disp;
+    reg_in_arg = arg_size;
+    printf("\t.set %s%d,%d\n",lpfx,lvar_offset_label,reg_in_arg);
+
     for(args = fnptr->dsp;args;args = cadr(args)) {
         n = ncadddr(args);
         tag = n->sc;
@@ -1112,13 +1118,13 @@
         if (!n||n==&null_nptr) error(REG_ERR);
         if (tag==REGISTER) {
             n->dsp = offset;
-            offset+=SIZE_OF_INT;
+            offset+=SIZE_OF_LONGLONG;
             t = INT;
             reg_var++;
         } else if (tag==FREGISTER) {
             n->dsp = offset;
             t = n->ty;
-	    offset+=SIZE_OF_FLOAT; 
+	    offset+=SIZE_OF_DOUBLE; 
             freg_var++;
         } else if (tag==DREGISTER) {
             n->dsp = offset;
@@ -1131,7 +1137,7 @@
             offset+=SIZE_OF_LONGLONG; 
             reg_var++;
         } else {
-            offset += size(n->ty);
+            offset += SIZE_OF_LONGLONG; // size(n->ty);
             continue;
         }
         n->sc  = LVAR;
@@ -1173,6 +1179,7 @@
 
     function_type(fnptr->ty,&dots);
     while (args) {
+        // we should use increment_arg
         /* process in reverse order */
         n = ncadddr(args);
         type = n->ty;
@@ -1182,7 +1189,7 @@
                 n->dsp = cadr(reg);
                 regs[n->dsp]= INPUT_REG;
                 reg_var++;
-                arg_offset_v += (caddr(args)=size(type));
+                arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
             }
         } else if (type==FLOAT) {
             if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) {
@@ -1190,7 +1197,7 @@
                 n->dsp = cadr(reg);
                 regs[n->dsp]= INPUT_REG;
                 freg_var++;
-                arg_offset_v += (caddr(args)=size(type));
+                arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
             }
         } else if (type==DOUBLE) {
             if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) {
@@ -1198,7 +1205,7 @@
                 n->dsp = cadr(reg);
                 regs[n->dsp]= INPUT_REG;
                 freg_var++;
-                arg_offset_v += (caddr(args)=size(type));
+                arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
             }
         } else if (type==LONGLONG||type==ULONGLONG) {
             if ((reg = get_input_lregister_var(reg_var,n,is_code0))) {
@@ -1206,7 +1213,7 @@
                 n->dsp = cadr(reg);
                 regs[n->dsp]= INPUT_REG;
                 reg_var+=1;
-                arg_offset_v += (caddr(args)=size(type));
+                arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
             }
         }
         args = cadr(args);
@@ -1222,7 +1229,7 @@
         printf(".set %s%d, %d\n",lpfx, arg_offset_label,
             arg_offset_v+ arg_offset);
 #endif
-        code_save_input_registers(dots);
+        code_save_input_registers(dots, arg_offset_v);
     }
 }
 
@@ -2014,7 +2021,7 @@
         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;
+        nargs += round8(size(t))/SIZE_OF_INT;
     } else {
         error(TYERR);
         nargs ++ ;
@@ -2903,7 +2910,7 @@
 	printf(".globl _%s\n",name);
     printf("_%s:\n",name);
 #endif
-//    lvar_offset_label = fwdlabel();
+    lvar_offset_label = fwdlabel();
     r1_offset_label = fwdlabel();
     max_func_args = 0;
     printf("\tpushq %%rbp\n");
@@ -5070,7 +5077,31 @@
 extern int 
 code_arg_alignment(int args,NMTBL *n, int type0,int sz)
 {
-    return code_arg_alignment0(args,n, type0,sz);
+    if(type0==CHAR||type0==UCHAR) {
+        if (n->dsp==0) {
+            n->dsp = args;
+            if (endian) n->dsp += size_of_longlong-1;
+        }
+        args += size_of_longlong;
+    } else if(type0==SHORT||type0==USHORT) {
+        if (n->dsp==0) {
+            n->dsp = args;
+            if (endian) n->dsp += size_of_longlong-size_of_short;
+        }
+        args += size_of_longlong;
+    } 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_longlong);
+    } else {
+        /* if (n->dsp==0) (argument list in ADECL is useless, type
+           list can be found in type ) */
+        n->dsp = args;
+        args += align(sz,size_of_longlong);
+    }
+    return args;
 }