Mercurial > hg > CbC > old > device
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); } } }