changeset 791:75e30aea08cd

stdargs
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 22 Nov 2010 13:34:27 +0900
parents a26d87f93c65
children 3622e3f561db
files .gdbinit mc-code-i64.c mc-macro.c mc-parse.c mc.h
diffstat 5 files changed, 132 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Sun Nov 21 23:03:37 2010 +0900
+++ b/.gdbinit	Mon Nov 22 13:34:27 2010 +0900
@@ -26,7 +26,8 @@
 # r -s test/basic.c
 # r -s test/float.c
 # r -s test/strinit.c
-r -s test/bitfield.c
+# r -s test/bitfield.c
+r -s test/tstdarg.c
 # r -s test/arg.c
 # r -s test/obsf2.c
 # r -s test/putenemy.c
--- a/mc-code-i64.c	Sun Nov 21 23:03:37 2010 +0900
+++ b/mc-code-i64.c	Mon Nov 22 13:34:27 2010 +0900
@@ -40,7 +40,47 @@
 
 static
 char *init_src0 = "\
-typedef long __builtin_va_list;\n\
+typedef struct __builtin_va_list { \\\n\
+    long long_last; \\\n\
+    long float_first; \\\n\
+    long float_last; \\\n\
+    long stack_top; \\\n\
+    long arg; \\\n\
+} __builtin_va_list1, *__builtin_va_list; \\\n\
+ \\\n\
+#define __builtin_va_start(ap,v) \\\n\
+__builtin_va_list1 __my_va_list; \\\n\
+{ \\\n\
+    ap = &__my_va_list; \\\n\
+    ap->float_first = ap->long_last+8; \\\n\
+    long adr = (long)&v; \\\n\
+    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\
+} \\\n\
+\n\
+#define __builtin_va_arg(ap,type) ({ \\\n\
+    long arg; \\\n\
+    if (__builtin_types_compatible_p(type,double)  \\\n\
+            && ap->float_first < ap->stack_top) { \\\n\
+	ap->float_first = ap->float_first+8; \\\n\
+	if (ap->float_first==ap->float_last) \\\n\
+	    ap->float_first = ap->stack_top;\\\n\
+	arg = ap->float_first; \\\n\
+    } else { \\\n\
+	ap->arg = ap->arg+8; \\\n\
+        if (ap->arg==ap->long_last) \\\n\
+	    ap->arg = ap->stack_top; \\\n\
+        arg = ap->arg; \\\n\
+    } \\\n\
+    *((type *)(arg)); \\\n\
+}) \\\n\
+\n"
+
+"\
+#define __builtin_va_end(v)\n\
 #define __inline inline \n\
 #define __inline__ inline \n\
 #define __DARWIN_1050(x) \n\
@@ -1166,7 +1206,7 @@
             offset+=SIZE_OF_LONGLONG; 
             reg_var++;
         } else {
-            offset += SIZE_OF_LONGLONG; // size(n->ty);
+            // offset += SIZE_OF_LONGLONG; // size(n->ty);
             continue;
         }
         n->sc  = LVAR;
@@ -1178,10 +1218,11 @@
     if (dots) {
         while ((reg = get_input_register_var(reg_var,0,0))) {
             g_expr_u(assign_expr0(
-                list3n(LVAR,offset,0),reg,INT,INT));
-            offset+=SIZE_OF_INT;
+                list3n(LVAR,offset,0),reg,LONGLONG,LONGLONG));
+            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(
@@ -1189,6 +1230,30 @@
             offset+=SIZE_OF_DOUBLE;
             freg_var++;
         }
+        int float_last = offset-SIZE_OF_LONGLONG;
+/*
+__builtin_va_list1 __my_va_list;
+    long long_last; \n\
+    long float_first; \n\
+    long float_last; \n\
+    long stack_top; \n\
+ */
+        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;
+        NMTBL *n = def(lsearch("__my_va_list",0),0);
+        mode = smode;
+        // long_last
+	g_expr_u(assign_expr0( list3n(LVAR,n->dsp,n),list2(ADDRESS,list3(LVAR,long_last,0)),LONGLONG,LONGLONG));
+        // float_last
+	g_expr_u(assign_expr0( list3n(LVAR,n->dsp+16,n),list2(ADDRESS,list3(LVAR,float_last,0)),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;
 }
@@ -1248,17 +1313,17 @@
         args = cadr(args);
     }
     if (is_function(fnptr)) {
-#ifndef __APPLE__
         if (dots) {
 		//  %al の値によって float を適切にloadする必要がある  sigh...
                 arg_offset_v =
-                    MAX_INPUT_REGISTER_VAR*SIZE_OF_INT +
+                    MAX_INPUT_REGISTER_VAR*SIZE_OF_LONGLONG +
                     MAX_INPUT_DREGISTER_VAR*SIZE_OF_DOUBLE;
-        }
+#ifndef __APPLE__
         printf(".set %s%d, %d\n",lpfx, arg_offset_label,
             arg_offset_v+ arg_offset);
 #endif
-        code_save_input_registers(dots, arg_offset_v);
+	}
+	code_save_input_registers(dots, arg_offset_v);
     }
 }
 
--- a/mc-macro.c	Sun Nov 21 23:03:37 2010 +0900
+++ b/mc-macro.c	Mon Nov 22 13:34:27 2010 +0900
@@ -987,8 +987,11 @@
 		macro = scaddr(nptrm->dsp);
 	    else
 		macro="";
-	    if (check_recurse(nptrm->nm,history)) 
+	    if (check_recurse(nptrm->nm,history)) {
+		// should return the most original one, but how?
+		// save_cheap/reset_cheap and return here?
 		goto skip;
+	    }
 	    switch(nptrm->sc) {
 	    case FMACRO:
 		if (c==' '||c=='\t') {
--- a/mc-parse.c	Sun Nov 21 23:03:37 2010 +0900
+++ b/mc-parse.c	Mon Nov 22 13:34:27 2010 +0900
@@ -194,6 +194,7 @@
 static void macro_convert();
 extern void sym_print(int,FILE *);
 static void copy_attributes(NMTBL *n) ;
+int types_compatible(int t, int t1);
 
 // current value of constant symbol
 
@@ -644,6 +645,7 @@
     reserve("__builtin_inf",BUILTIN_INF,RESERVE);
     reserve("__builtin_inff",BUILTIN_INFF,RESERVE);
     reserve("__builtin_infl",BUILTIN_INFL,RESERVE);
+    reserve("__builtin_types_compatible_p",BUILTIN_TYPES_COMPATIBLE_P,RESERVE);
     reserve("__attribute__",ATTRIBUTE,RESERVE);
     reserve("__attribute",ATTRIBUTE,RESERVE);
     reserve("__label__",LABEL,RESERVE);
@@ -1164,7 +1166,7 @@
 	smode = mode; mode = STAT;
 	checksym(LPAR);
 	mode = LDECL;  // typespec required this
-	if((t=typespec())==0) {
+	if((t=typename())==0) {
 	    mode = STAT;   // too late for expression 
 	    expr(0); 
 	    t = type;
@@ -3801,6 +3803,27 @@
 	    return list2(BUILTINP,rvalue(e));  /* evalue it later */
 	else 
 	    return list2(CONST,is_const(e));
+    case BUILTIN_TYPES_COMPATIBLE_P:
+	{
+         int t, t1;
+	getsym(0);
+	int slfree=lfree; int stype=type;
+	int smode = mode; mode = STAT;
+	checksym(LPAR);
+	mode = LDECL;  // typespec required this
+	if((t=typename())==0) {
+	    error(TYERR);
+	}
+	checksym(COMMA);
+	mode = LDECL;  // typespec required this
+	if((t1=typename())==0) {
+	    error(TYERR);
+	}
+	set_lfree(slfree); type=stype;
+	mode = smode;
+	checksym(RPAR);
+	return types_compatible(t,t1);
+        }
     case BUILTIN_EXPECT:
 	/* builtin_expect(x,c) used in branch. x is expectet to be c */
 	conv->prefix_(sym);
@@ -4545,6 +4568,15 @@
     }
 }
 
+int
+types_compatible(int t, int t1)
+{
+    int eq = 0;
+    if (t==t1) eq = 1;
+    type = INT;
+    return list2(CONST,eq);
+}
+
 /*
     string cheap management
 
--- a/mc.h	Sun Nov 21 23:03:37 2010 +0900
+++ b/mc.h	Mon Nov 22 13:34:27 2010 +0900
@@ -456,31 +456,33 @@
 #define ULL2LL  (LOP+U2LL)
 #define ULL2ULL (LOP+U2ULL)
 
+#define BUILTIN_TYPES_COMPATIBLE_P	127
+
 /* tree node tags end */
 
 /* statement start */
 
-#define ST_DECL		127
-#define ST_IF		128
-#define ST_DO		129
-#define ST_WHILE	130
-#define ST_FOR		131
-#define ST_SWITCH	132
-#define ST_COMP		133
-#define ST_BREAK	134
-#define ST_CONTINUE	135
-#define ST_CASE		136
-#define ST_DEFAULT	137
-#define ST_RETURN	138
-#define ST_GOTO		139
-#define ST_ASM		140
-#define ST_LABEL	141
-#define ST_OP		142
-#define ST_COMMENT	143
+#define ST_DECL		128
+#define ST_IF		129
+#define ST_DO		130
+#define ST_WHILE	131
+#define ST_FOR		132
+#define ST_SWITCH	133
+#define ST_COMP		134
+#define ST_BREAK	135
+#define ST_CONTINUE	136
+#define ST_CASE		137
+#define ST_DEFAULT	138
+#define ST_RETURN	139
+#define ST_GOTO		140
+#define ST_ASM		141
+#define ST_LABEL	142
+#define ST_OP		143
+#define ST_COMMENT	144
 
 #define IS_STATEMENT(i) (i==INLINE||(ST_DECL<=i&&i<=ST_COMMENT))
 
-#define HAS_ADDRESS	144
+#define HAS_ADDRESS	145
 
 /* statement end */