Mercurial > hg > CbC > old > device
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 */