changeset 809:476b53b61630 ps3-ppu-worked

PS3 PPU stdarg
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 24 Nov 2010 04:22:49 +0900
parents 2a4a40168fa4
children dc7995497552
files Changes mc-code-powerpc.c mc-codegen.c mc-parse.c test/switch.c test/tstdarg.c
diffstat 6 files changed, 123 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Nov 23 23:39:41 2010 +0900
+++ b/Changes	Wed Nov 24 04:22:49 2010 +0900
@@ -9926,10 +9926,13 @@
 
 らしい。そのせいで、いろいろ一致しない。
 
-
-
-
-
-
-
-
+Wed Nov 24 02:34:43 JST 2010
+
+variadic の最初の引数のアドレスを固定した名前(その関数に局所的な)で覚えておけば、
+stdarg の実装に便利なんじゃないか?
+
+
+
+
+
+
--- a/mc-code-powerpc.c	Tue Nov 23 23:39:41 2010 +0900
+++ b/mc-code-powerpc.c	Wed Nov 24 04:22:49 2010 +0900
@@ -57,10 +57,57 @@
 #define __extension__\n\
 #define __const const\n\
 #define __inline__ inline\n\
-#define __builtin_va_list int\n\
-#define __builtin_va_start(ap,arg) ap=(((int)(&arg))+sizeof(arg))\n\
-#define __builtin_va_arg(ap,type)  (*((type *)ap)++)\n\
-// #define __builtin_va_arg(ap,type)  (*((type *)__builtin_va_next((type),&ap)))\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\
+    long top; \\\n\
+} __builtin_va_list; \\\n\
+ \\\n\
+#define __builtin_va_start(__ap0,v) \\\n\
+{ \\\n\
+    __builtin_va_list *__ap = &__ap0; \\\n\
+    long __top = __ap->top = (long)&__my_va_list; \\\n\
+    __ap->long_last = __top +32; \\\n\
+    __ap->float_first = __ap->long_last; \\\n\
+    __ap->stack_top = __top+32+64+8; \\\n\
+    long __adr = (long)(&v) + sizeof(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\
+    __ap->arg = __adr; \\\n\
+} \\\n\
+\n\
+#define __builtin_va_arg(__ap0,type) ({ \\\n\
+    __builtin_va_list *__ap = &__ap0; \\\n\
+    long __arg; \\\n\
+    if (__builtin_types_compatible_p(type,double)  \\\n\
+            && __ap->float_first < __ap->stack_top) { \\\n\
+        __arg = __ap->float_first; \\\n\
+        __ap->float_first = __ap->float_first+8; \\\n\
+        if (__ap->float_first==__ap->float_last) \\\n\
+            __ap->float_first = __ap->stack_top;\\\n\
+    } else { \\\n\
+	if (__builtin_types_compatible_p(type,long long)) {  \\\n\
+            if (__ap->arg==__ap->top+4) __ap->arg += 4; \\\n\
+	    __arg = __ap->arg; \\\n\
+	    __ap->arg += 8; \\\n\
+            if (__ap->arg==__ap->top+16+16) \\\n\
+		__ap->arg = __ap->stack_top; \\\n\
+	} else { \\\n\
+	    __arg = __ap->arg; \\\n\
+	    __ap->arg = __ap->arg+sizeof(type); \\\n\
+	    if (__ap->arg==__ap->long_last) \\\n\
+		__ap->arg = __ap->stack_top; \\\n\
+	} \\\n\
+    } \\\n\
+    *((type *)(__arg)); \\\n\
+}) \\\n\
+\n"
+
+"// #define __builtin_va_arg(ap,type)  (*((type *)__builtin_va_next((type),&ap)))\n\
 #define alloca __builtin_alloca\n\
 #define __DBL_MIN_EXP__ (-1021)\n\
 #define __FLT_MIN__ 1.17549435e-38F\n\
@@ -792,9 +839,17 @@
     int dots;
     arg_offset_v = 0;
 
+    function_type(fnptr->ty,&dots);
+
+    if (dots && (in || !parse_mode)) {
+        type = INT;
+        mode = LDECL;
+        stmode = 0;
+        n = def(lsearch("__my_va_list",0),0);
+	n->dsp = 0; // first argument
+    }
     if (in) return;
 
-    function_type(fnptr->ty,&dots);
     while (args) {
         /* process in reverse order */
         n = ncadddr(args);
@@ -4054,22 +4109,24 @@
     int align = 1;
     if ((align=attr_value(n,ALIGNED))) {
 	align = ilog(caddr(align));
-    } else if (size(n->ty)>4)
-	align = 2;
-    else if (size(n->ty)>4)
-	align = 0;
-    switch(n->ty) {
-    case DOUBLE:
-    case LONGLONG:
-    case ULONGLONG:
-	align = 8; break;
-    case INT:
-    case UNSIGNED:
-    case FLOAT:
-	align = 4; break;
-    case SHORT:
-    case USHORT:
-	align = 2; break;
+    } else  {
+	if (size(n->ty)>4)
+	    align = 2;
+	else if (size(n->ty)>4)
+	    align = 0;
+	switch(n->ty) {
+	case DOUBLE:
+	case LONGLONG:
+	case ULONGLONG:
+	    align = 8; break;
+	case INT:
+	case UNSIGNED:
+	case FLOAT:
+	    align = 4; break;
+	case SHORT:
+	case USHORT:
+	    align = 2; break;
+	}
     }
     printf("\t.comm %s,%d,%d\n",n->nm,size(n->ty),align);
 }
@@ -4080,6 +4137,7 @@
     NMTBL *n;
     int init;
     init=0;
+    global_list = reversen(global_list);
     for(n=global_list;n;n=n->next) {
         if ((n->sc == GVAR) && n->dsp != -1) {
             /* n->dsp = -1 means initialized global */
--- a/mc-codegen.c	Tue Nov 23 23:39:41 2010 +0900
+++ b/mc-codegen.c	Wed Nov 24 04:22:49 2010 +0900
@@ -4255,7 +4255,7 @@
     t = type_value(t);
     return(t==INT||t==SIGNED||t==CHAR||t==UNSIGNED||
         t==UCHAR||t==SHORT||t==USHORT||t==ENUM || 
-		(lp64 && (t==LONGLONG||t==ULONGLONG)));
+		(lp64&&(t==LONGLONG||t==ULONGLONG)));
 }
 
 /*
--- a/mc-parse.c	Tue Nov 23 23:39:41 2010 +0900
+++ b/mc-parse.c	Wed Nov 24 04:22:49 2010 +0900
@@ -1082,9 +1082,10 @@
 
     qualifiers();
     switch(sym) {
+    case CHAR:
+	if ((char)-1 == 255) { t = UCHAR; getsym(0); break; }
     case VOID:
     case INT:
-    case CHAR:
     case CODE:
     case FLOAT:
     case DOUBLE:
@@ -1830,7 +1831,7 @@
 		}
 	    }
 	    /* NOT REACHED */
-	} else if (type_value(cadr(t0))==CHAR) {
+	} else if ((t=type_value(cadr(t0)))==CHAR||t==UCHAR) {
 	    e=expr1();
 	    mode = mode_save;
 	    if(car(e)!=STRING && car(e)!=STRINGS)
@@ -1839,7 +1840,7 @@
 		offset = list3(DECL_DATA,e,type);
 		return offset;
 	    }
-	    offset=assign_data(e,list3(ARRAY,CHAR,size(type)),v,offset);
+	    offset=assign_data(e,list3(ARRAY,t,size(type)),v,offset);
 	    if (caddr(t0)==0) {                  /* size not defined      */
 		caddr(t0)=size(type);           /* define array size     */
 	    } else if (caddr(t0)!=size(type)) {  /* size match?           */
@@ -3805,6 +3806,7 @@
 #endif
 	if (car(e)==CONST) return list2(CONST,!cadr(e));
 	if (scalar(type)) return list2(LNOT,e);
+	if (type==LONGLONG||type==ULONGLONG) return binop(EQ,e,llist2(LCONST,0),type,LONGLONG);
 	if (type==FLOAT||type==DOUBLE) return binop(EQ,e,dlist2(FCONST,0),type,FLOAT);
 	error(TYERR);
 	return list2(CONST,1);
--- a/test/switch.c	Tue Nov 23 23:39:41 2010 +0900
+++ b/test/switch.c	Wed Nov 24 04:22:49 2010 +0900
@@ -1250,7 +1250,7 @@
 	main4(19);
 	main5(19);
     for(i=-1000;i<3000;i++) {
-	main1(i);
+	// main1(i);
 	main2(i);
 	main3(i);
 	main4(i);
--- a/test/tstdarg.c	Tue Nov 23 23:39:41 2010 +0900
+++ b/test/tstdarg.c	Wed Nov 24 04:22:49 2010 +0900
@@ -3,6 +3,27 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+
+void
+print(__builtin_va_list *ap)
+{
+#if 0
+printf(
+"    long long_last    %0lx; \n"
+"    long float_first  %0lx; \n"
+"    long float_last   %0lx; \n"
+"    long stack_top    %0lx; \n"
+"    long arg          %0lx; \n"
+"    long top          %0lx; \n",
+ap->long_last    ,
+ap->float_first  ,
+ap->float_last   ,
+ap->stack_top    ,
+ap->arg          ,
+ap->top         ); 
+#endif
+}
+
 void
 var_args(char *numtypes, ...)
 {
@@ -15,10 +36,12 @@
     va_list ap;
 
     va_start(ap,numtypes);
+print(&ap);
     while((t= *numtypes++)) {
 	if (t=='i') {
 	    i = va_arg(ap,int);
 	    printf("#0020:int arg: %d\n",i);
+print(&ap);
 
 #if 0        /*  ‘float’ is promoted to ‘double’ when passed through ‘...’ */
 	} else if (t=='f') {
@@ -28,15 +51,19 @@
 	} else if (t=='d') {
 	    d = va_arg(ap,double);
 	    printf("#0029:double arg: %g\n",d);
+print(&ap);
 	} else if (t=='l') {
 	    l = va_arg(ap,long long);
 	    printf("#0032:long long arg: %lld\n",l);
+print(&ap);
 	} else if (t=='s') {
 	    s = va_arg(ap,char *);
 	    printf("#0035:char *arg: %s\n",s);
+print(&ap);
 	} else {
 	    s = va_arg(ap,char *);
 	    printf("#0038:arg: error\n");
+print(&ap);
 	}
     }
 }