changeset 795:a4fd2ab28e24

i64 va_list
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 23 Nov 2010 12:45:22 +0900
parents 032dc03be02e
children 80a59598df5f
files mc-code-i64.c mc-inline.c mc-inline.h
diffstat 3 files changed, 69 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Tue Nov 23 09:42:08 2010 +0900
+++ b/mc-code-i64.c	Tue Nov 23 12:45:22 2010 +0900
@@ -28,6 +28,7 @@
 #include "mc-parse.h"
 #include "mc-codegen.h"
 #include "mc-code.h"
+#include "mc-inline.h"
 
 #ifdef __APPLE__
 #define USE_SSE2
@@ -56,8 +57,7 @@
     if (adr >= ap->stack_top) ap->arg = ap->float_first = adr; \\\n\
     if (__builtin_types_compatible_p(typeof(v),double))  \\\n\
 	ap->float_first = adr; \\\n\
-    else \\\n\
-	ap->arg = adr; \\\n\
+    ap->arg = adr; \\\n\
 } \\\n\
 \n\
 #define __builtin_va_arg(ap,type) ({ \\\n\
@@ -1226,7 +1226,6 @@
             offset+=SIZE_OF_LONGLONG;
             reg_var++;
         }
-        int long_last = offset-SIZE_OF_LONGLONG;
 	//  Intel64 keeps number of double value in %al
         while ((reg = get_input_dregister_var(freg_var,0,0,0))) {
             g_expr_u(assign_expr0(
@@ -1234,7 +1233,24 @@
             offset+=SIZE_OF_DOUBLE;
             freg_var++;
         }
-        int float_last = offset-SIZE_OF_LONGLONG;
+    }
+    // my_func_args = offset;
+}
+
+static void
+def_va_list_truct(int long_last, int float_last)
+{
+    int stype = type;
+    int smode = mode;
+    int sstmode = stmode;
+
+    NMTBL *nptr =name_space_search(get_name("__builtin_va_list1",0,NONDEF),0);
+    if (!nptr) error(-1);
+    type = nptr->ty;
+    typedefed=glist3n(TYPEDEF,typedefed,nptr);
+    mode = LDECL;
+    stmode = 0;
+    NMTBL *n = def(lsearch("__my_va_list",0),0);
 
         // ssetup va_list structure
         // __my_va_list is defined as local in code_arg_register
@@ -1245,16 +1261,25 @@
     long float_last; \n\
     long stack_top; \n\
  */
-        NMTBL *n = lsearch("__my_va_list",0);
+    if (inmode) {
+	parse = list5n(ST_DECL,parse,list3(mode,0,0),0,n);
         // long_last
-	g_expr_u(assign_expr0( list3n(LVAR,n->dsp,n),list2(ADDRESS,list3(LVAR,long_last,0)),LONGLONG,LONGLONG));
+	parse = list3(ST_COMP,parse,assign_expr0( list3n(LVAR,n->dsp,n),list3(LADD,list2(LREGISTER,REG_EBP),llist2(LCONST,FUNC_LVAR(long_last))),LONGLONG,LONGLONG));
         // float_last
-	g_expr_u(assign_expr0( list3n(LVAR,n->dsp+16,n),list2(ADDRESS,list3(LVAR,float_last,0)),LONGLONG,LONGLONG));
+	parse = list3(ST_COMP,parse,assign_expr0( list3(ADD,list3n(LVAR,n->dsp,n),list2(CONST,16)),list3(LADD,list2(LREGISTER,REG_EBP),llist2(LCONST,FUNC_LVAR(float_last))),LONGLONG,LONGLONG));
+        // stack_top
+	parse = list3(ST_COMP,parse,assign_expr0( list3(ADD,list3n(LVAR,n->dsp,n),list2(CONST,24)),list3(LADD,list2(LREGISTER,REG_EBP),llist2(LCONST,16)),LONGLONG,LONGLONG));
+    } else {
+        // long_last
+	g_expr_u(assign_expr0( list3n(LVAR,n->dsp,n),list3(LADD,list2(LREGISTER,REG_EBP),llist2(LCONST,FUNC_LVAR(long_last))),LONGLONG,LONGLONG));
+        // float_last
+	g_expr_u(assign_expr0( list3n(LVAR,n->dsp+16,n),list3(LADD,list2(LREGISTER,REG_EBP),llist2(LCONST,FUNC_LVAR(float_last))),LONGLONG,LONGLONG));
         // stack_top
 	g_expr_u(assign_expr0( list3n(LVAR,n->dsp+24,n),list3(LADD,list2(LREGISTER,REG_EBP),llist2(LCONST,16)),LONGLONG,LONGLONG));
-
     }
-    // my_func_args = offset;
+    mode = smode;
+    type = stype;
+    stmode = sstmode;
 }
 
 void
@@ -1271,25 +1296,6 @@
     arg_offset_v = 0;
     function_type(fnptr->ty,&dots);
 
-    if (dots && (in || is_inline(fnptr))) {  
-
-        // special structure for variadic function
-        //    this have to be defined before va_start
-
-        // in parse mode, fnptr is not inline function, but we have to generated  this.
-
-        NMTBL *nptr =name_space_search(get_name("__builtin_va_list1",0,NONDEF),0);
-	if (!nptr) error(-1);
-        type = nptr->ty;
-	typedefed=glist3n(TYPEDEF,typedefed,nptr);
-	int smode = mode;
-        mode = LDECL;
-        stmode = 0;
-        def(lsearch("__my_va_list",0),0);
-        mode = smode;
-	// inline function is generated in pfdecl, we have to do code_arg_register also
-    }
-    if (in || !is_inline(fnptr)) return;
 
     while (args) {
         // we should use increment_arg
@@ -1298,33 +1304,41 @@
         type = n->ty;
         if (type==LONGLONG||type==ULONGLONG) { // scalar includes LONGLONG, check first
             if ((reg = get_input_lregister_var(reg_var,n,is_code0))) {
-                n->sc = LREGISTER;
-                n->dsp = cadr(reg);
-                regs[n->dsp]= INPUT_REG;
-                reg_var+=1;
-                arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
+		if (!in) {
+		    n->sc = LREGISTER;
+		    n->dsp = cadr(reg);
+		    regs[n->dsp]= INPUT_REG;
+		}
+		reg_var+=1;
+		arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
             }
         } else if (scalar(type)) { 
             if ((reg = get_input_register_var(reg_var,n,is_code0))) {
-                n->sc = (car(type)==POINTER && lp64) ?LREGISTER:REGISTER;
-                n->dsp = cadr(reg);
-                regs[n->dsp]= INPUT_REG;
+		if (!in) {
+		    n->sc = (car(type)==POINTER && lp64) ?LREGISTER:REGISTER;
+		    n->dsp = cadr(reg);
+		    regs[n->dsp]= INPUT_REG;
+		}
                 reg_var++;
                 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))) {
-                n->sc = FREGISTER;
-                n->dsp = cadr(reg);
-                regs[n->dsp]= INPUT_REG;
+		if (!in) {
+		    n->sc = FREGISTER;
+		    n->dsp = cadr(reg);
+		    regs[n->dsp]= INPUT_REG;
+		}
                 freg_var++;
                 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))) {
-                n->sc = DREGISTER;
-                n->dsp = cadr(reg);
-                regs[n->dsp]= INPUT_REG;
+		if (!in) {
+		    n->sc = DREGISTER;
+		    n->dsp = cadr(reg);
+		    regs[n->dsp]= INPUT_REG;
+		}
                 freg_var++;
                 arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type));
             }
@@ -1337,16 +1351,21 @@
                 arg_offset_v =
                     MAX_INPUT_REGISTER_VAR*SIZE_OF_LONGLONG +
                     MAX_INPUT_DREGISTER_VAR*SIZE_OF_DOUBLE;
+
+		int long_last = -arg_offset_v + reg_var*SIZE_OF_LONGLONG;
+		int float_last = long_last + freg_var*SIZE_OF_LONGLONG;
+
+		def_va_list_truct(long_last,float_last);
 #ifndef __APPLE__
-        printf(".set %s%d, %d\n",lpfx, arg_offset_label,
-            arg_offset_v+ arg_offset);
+		if (!in) 
+		printf(".set %s%d, %d\n",lpfx, arg_offset_label,
+		    arg_offset_v+ arg_offset);
 #endif
 	}
-	code_save_input_registers(dots, arg_offset_v);
+	if (!in) code_save_input_registers(dots, arg_offset_v);
     }
 }
 
-
 void 
 gexpr_init(void)
 {
--- a/mc-inline.c	Tue Nov 23 09:42:08 2010 +0900
+++ b/mc-inline.c	Tue Nov 23 12:45:22 2010 +0900
@@ -3,7 +3,7 @@
 /************************************************************************
 ** Copyright (C) 2006 Shinji Kono
 ** 連絡先: 琉球大学情報工学科 河野 真治  
-** (E-Mail Address: kono@ie.u-ryukyu.ac.jp)
+*)* (E-Mail Address: kono@ie.u-ryukyu.ac.jp)
 **
 **    このソースのいかなる複写,改変,修正も許諾します。ただし、
 **    その際には、誰が貢献したを示すこの部分を残すこと。
@@ -475,7 +475,7 @@
     return pvartable;
 }
 
-static int
+extern int
 p_lvar(int e1)
 {
     int sz = is_memory(e1);
@@ -483,7 +483,7 @@
     int d1,e;
     if ((d1=(heap[pdisp+d]))) return d1;
 fprintf(stderr,"## undeclared ivar %d\n",d);
-    // error(-1);
+    error(-1);
     e =  heap[pdisp+d]=list3(LVAR,new_lvar(sz),0);
     inline_lvars = glist2(e,inline_lvars);
     return e;
--- a/mc-inline.h	Tue Nov 23 09:42:08 2010 +0900
+++ b/mc-inline.h	Tue Nov 23 12:45:22 2010 +0900
@@ -41,6 +41,7 @@
 extern void st_asm(int e1);
 extern void st_label(int e1);
 extern void st_comment(int e1);
+extern int p_lvar(int e1);
 
 
 /* end */