changeset 759:b03d486a8a3e

i64 continue... fix struct/ldiv
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 17 Nov 2010 08:42:15 +0900
parents 7a19e49db6ac
children ac471ccd1cc8
files mc-code-i64.c mc-codegen.c
diffstat 2 files changed, 22 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Tue Nov 16 20:50:22 2010 +0900
+++ b/mc-code-i64.c	Wed Nov 17 08:42:15 2010 +0900
@@ -514,8 +514,8 @@
 #define func_disp_offset (16)
 #define code_disp_offset (16)
 
-#define arg_offset  16
-#define arg_offset1  0
+#define arg_offset  (16)
+#define arg_offset1  (-48)
 #define ARG_LVAR_OFFSET 0x10000000
 
 #define code_disp_offset0 (-16)
@@ -1178,11 +1178,11 @@
         type = n->ty;
         if (scalar(type)) {
             if ((reg = get_input_register_var(reg_var,n,is_code0))) {
-                n->sc = REGISTER;
+                n->sc = (car(type)==POINTER && lp64) ?LREGISTER:REGISTER;
                 n->dsp = cadr(reg);
                 regs[n->dsp]= INPUT_REG;
                 reg_var++;
-                arg_offset_v += (caddr(args)=SIZE_OF_INT);
+                arg_offset_v += (caddr(args)=size(type));
             }
         } else if (type==FLOAT) {
             if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) {
@@ -2001,6 +2001,7 @@
         t = type_value(cadr(t));
     }
     if(scalar(t)) {
+        nargs ++ ; 
         nargs ++ ; reg_arg++;
     } else if (t==LONGLONG||t==ULONGLONG) {
         nargs ++ ; reg_arg++;
@@ -2008,9 +2009,10 @@
     } else if (t==FLOAT) {
         freg_arg++;
         nargs += size(t)/SIZE_OF_INT;
+        nargs ++ ; 
     } else if (t==DOUBLE) {
+        freg_arg++;
         nargs += size(t)/SIZE_OF_INT;
-        freg_arg++;
     } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
         nargs += round4(size(t))/SIZE_OF_INT;
     } else {
@@ -2253,6 +2255,7 @@
         car(e3)=0;  // done
     }
     nargs = reg_arg = freg_arg = 0;
+    int max_freg = 0;
     for (e3 = e1; e3;
                 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
                 e3 = cadr(e3)) {
@@ -2269,8 +2272,10 @@
             g_expr_u(assign_expr0(arg,e4,t,t));
         } else if (t==DOUBLE||t==FLOAT) {
             reg_arg_list = list2(arg,reg_arg_list);
-            if (car(arg)==DREGISTER)
+            if (car(arg)==DREGISTER) {
                 use_input_reg(cadr(arg),1); /* protect from input register free */
+		max_freg ++;
+	    }
             g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */
         }
         // structs are finished
@@ -2283,7 +2288,7 @@
     clear_ptr_cache();
     if (dots) {
 	// needs number of fregister in double
-	printf("\tmovl $%d,%%eax\n", freg_arg);
+	printf("\tmovl $%d,%%eax\n", max_freg);
     }
     code_call(e2,fn,jmp);
     free_register_var(reg_arg_list);
@@ -2291,7 +2296,7 @@
         if (use)
             set_freg(RET_DREGISTER,0);
         else
-            set_freg(CREG_REGISTER,0);
+            set_freg(FREG_FREGISTER,0);
     } else if (ret_type==VOID) {
     } else {
         if (use)
@@ -2576,9 +2581,13 @@
 	    set_ireg(reg,1);
         } else {
 	    orn = register_name(oreg,0);
-	    printf((op==LDIV||op==LMOD)?
-		"\tcltq\n\tidivq %s\n":
-		"\txorl %%edx,%%edx\n\tdivq %s\n",orn);
+	    if (op==LDIV||op==LMOD) {
+		code_lassign_lregister(REG_EDX,oreg);
+		printf("\tsarq $63,%%rdx\n");
+		printf("\tidivq %s\n",orn);
+            } else {
+		printf("\txorl %%edx,%%edx\n\tdivq %s\n",orn);
+            }
 	    set_lreg((op==LMOD||op==LUMOD)?REG_EDX:REG_EAX,0);
 	    set_lreg(reg,1);
         }
--- a/mc-codegen.c	Tue Nov 16 20:50:22 2010 +0900
+++ b/mc-codegen.c	Wed Nov 17 08:42:15 2010 +0900
@@ -4088,7 +4088,7 @@
 	str_ret.dsp = 0; str_ret.ty = 0;
 	type=list2(POINTER,t);
 	/* fix all argument's offset */
-	sz = inmode?1:size(type);
+	sz = inmode?1:size_of_pointer;
 	for(t=fnptr->dsp;t;t=cadr(t)) {
 	    n=ncadddr(t);
 	    n->dsp += inmode?1:sz;
@@ -4098,7 +4098,7 @@
 	else {
 	    args=0;  // set struct var dsp = 0
 	    def(&str_ret,0); 
-	    args = sargs + (inmode?1:size_of_int);
+	    args = sargs + (inmode?1:size_of_pointer);
 	    struct_return = inmode
 		?list3(list3n(IVAR,str_ret.dsp,0),sz,type)
 		:list3(list3n(LVAR,str_ret.dsp,0),sz,type);