Mercurial > hg > CbC > old > device
diff mc-codegen.c @ 782:003067098032
code argument offset in caller and callee
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 20 Nov 2010 10:55:31 +0900 |
parents | b8cb4e1ac922 |
children | feeb9b9f8236 |
line wrap: on
line diff
--- a/mc-codegen.c Fri Nov 19 18:57:36 2010 +0900 +++ b/mc-codegen.c Sat Nov 20 10:55:31 2010 +0900 @@ -108,6 +108,11 @@ init_free_lvar_list(); } +/** + make register argments + and save it into memory (sigh...) + we should postpone code_save_argument_register + */ extern void arg_register(NMTBL *fnptr) { @@ -1472,6 +1477,7 @@ // maximum size of struct divide (don't make it large) #define ASSIGN_STRUCT_DIVIDE 40 +#define ARG_OFFSET_CODE 1 extern void jump(int e1, int env) @@ -1488,6 +1494,7 @@ /* e1 = list4(FUNCTION,code_segment,arglist,ftype); */ if (env) { + error(-1); // not supported envreg = get_register_var(0); g_expr_u(assign_expr0(envreg,env,int_type,int_type)); } @@ -1526,9 +1533,12 @@ target=list5(list3n(LVAR,0,0), target,ty,e2,0); } /* keep arg space for register variables */ - // NMTBL n; - // arg_size = code_arg_alignment(arg_size, &n, ty, sz); +#if ARG_OFFSET_CODE + NMTBL n; + arg_size = code_arg_alignment(arg_size, &n, ty, sz,1); +#else arg_size += sz; +#endif #if DEBUG_PARALLEL_ASSIGN if (lsrc)printf("## target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz); #endif @@ -1549,19 +1559,27 @@ /* 複雑な式を前もって計算しておく */ /* 必要なら局所変数を用いる。 */ /* 局所変数へのオフセットを覚えておく */ - // int arg_offset = 0; +#if ARG_OFFSET_CODE + NMTBL n; + n.dsp = 0; + int arg_offset = 0; + target = reverse0(target); +#endif for (e2 = target; e2; e2 = cadr(e2)) { t0=car(e2); s0=cadddr(e2); sz=size(ty=caddr(e2)); +#if ARG_OFFSET_CODE + /* ここで、書込先アドレスを決める */ + arg_offset = code_arg_alignment(arg_offset, &n, ty, sz,1); if(car(t0)==LVAR) { - /* ここで、書込先アドレスを決める */ - if (envreg) error(-1); - // NMTBL n; - // arg_offset = code_arg_alignment(arg_offset, &n, ty, sz); - // cadr(t0) = arg_offset - n.dsp; + cadr(t0) = n.dsp; + } +#else + if(car(t0)==LVAR) { cadr(t0)=-arg_size; // disp_offset?! } arg_size-=sz; +#endif #ifdef SAVE_ALL_NON_MEMORY if (!is_simple(car(s0))) { #else @@ -1576,7 +1594,7 @@ } else if (is_same_type(t0,s0)) { if(cadr(t0)==cadr(s0)) { if(is_writable(s0)) { - caddddr(e2)=list3(s0,0,sz); + caddddr(e2)=list3(s0,0,sz); // これなんだっけ? continue; } else error(-1); @@ -1607,8 +1625,7 @@ case 2: case 3: caddr(e2) = USHORT; r = size_of_short; break; case 4: if (lp64) { caddr(e2) = UNSIGNED; r = size_of_int; break; } - default: if (lp64) { caddr(e2) = ULONGLONG; r = int_size; break; } - caddr(e2) = UNSIGNED; r = size_of_int; + default: caddr(e2) = int_unsigned; r = size_of_int; } if (e4==int_size) e3=cadr(e2); car(e2) = list3n(LVAR,cadr(t0)+e4,0); @@ -3499,7 +3516,7 @@ n->dsp = args++; n->sc = IVAR; } else { - args = code_arg_alignment(args,n,type0,sz); + args = code_arg_alignment(args,n,type0,sz, is_code(fnptr)); } caddr(fnptr->dsp)=sz; @@ -3555,34 +3572,68 @@ // standard 32bit alignment +// for code extern int -code_arg_alignment0(int args,NMTBL *n, int type0,int sz) +code_arg_alignment1(int offset,NMTBL *n, int type0,int sz, int is_code) { if(type0==CHAR||type0==UCHAR) { if (n->dsp==0) { - n->dsp = args; + n->dsp = -offset; if (endian) n->dsp += size_of_int-1; } - args += size_of_int; + offset += size_of_int; } else if(type0==SHORT||type0==USHORT) { if (n->dsp==0) { - n->dsp = args; + n->dsp = -offset; if (endian) n->dsp += size_of_int-size_of_short; } - args += size_of_int; + offset += size_of_int; } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) { /* alignment in struct in argument */ /* should be GCD of member alignment */ /* __attribute(alignment(16)) is ignored in argments */ - n->dsp = args; - args += align(sz,size_of_int); + n->dsp = -offset; + offset += align(sz,size_of_int); } else { /* if (n->dsp==0) (argument list in ADECL is useless, type list can be found in type ) */ - n->dsp = args; - args += sz; - } - return args; + n->dsp = -offset; + offset += sz; + } + return offset; +} + +// for function +extern int +code_arg_alignment0(int offset,NMTBL *n, int type0,int sz, int is_code) +{ + if (is_code) return code_arg_alignment1(offset,n,type0,sz,is_code); + + if(type0==CHAR||type0==UCHAR) { + if (n->dsp==0) { + n->dsp = offset; + if (endian) n->dsp += size_of_int-1; + } + offset += size_of_int; + } else if(type0==SHORT||type0==USHORT) { + if (n->dsp==0) { + n->dsp = offset; + if (endian) n->dsp += size_of_int-size_of_short; + } + offset += size_of_int; + } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) { + /* alignment in struct in argument */ + /* should be GCD of member alignment */ + /* __attribute(alignment(16)) is ignored in argments */ + n->dsp = offset; + offset += align(sz,size_of_int); + } else { + /* if (n->dsp==0) (argument list in ADECL is useless, type + list can be found in type ) */ + n->dsp = offset; + offset += sz; + } + return offset; } // standard 32bit alignment for local variable @@ -3605,9 +3656,9 @@ // for mc-parse.c extern int -arg_alignment(int args,NMTBL *n, int type0,int sz) +arg_alignment(int args,NMTBL *n, int type0,int sz, int is_code) { - return code_arg_alignment(args,n, type0,sz); + return code_arg_alignment(args,n, type0,sz, is_code); } extern char *