Mercurial > hg > CbC > old > device
changeset 762:236d49777503
i64 continue integer pass
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 17 Nov 2010 16:22:51 +0900 |
parents | 684dcbd0e170 |
children | 3c09f0b8b377 |
files | mc-code-i64.c |
diffstat | 1 files changed, 46 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-i64.c Wed Nov 17 12:16:08 2010 +0900 +++ b/mc-code-i64.c Wed Nov 17 16:22:51 2010 +0900 @@ -509,6 +509,7 @@ #define round16(i) align(i,16) #define round4(i) align(i,4) +#define round8(i) align(i,8) #define func_disp_offset (16) @@ -529,7 +530,8 @@ #define CALLEE_ARG(l) ((l)+arg_offset) static int r1_offset_label; static const char lpfx[] = "_"; -// static int lvar_offset_label; +static int lvar_offset_label; +static int reg_in_arg; static int max_func_args,max_func_arg_label; /* @@ -571,7 +573,6 @@ printf("\t.set _%d,%d\n",code_disp_label,r1_offsetv); } else { // +8 makes esp alignment 16 - // printf(".set %s%d,%d\n",lpfx,lvar_offset_label,lvar_offsetv); if (r1_offsetv-lvar_offsetv > 65000) error(-1); // too large function arguments? // printf(".set %s%d,%d\n",lpfx,r1_offset_label,r1_offsetv); @@ -618,7 +619,7 @@ } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ printf("%d(%%rsp)",CALLER_ARG(l-ARG_LVAR_OFFSET)); } else { /* callee's arguments */ - printf("%d(%%rbp)",CALLEE_ARG(l)); + printf("%d-_%d(%%rbp)",CALLEE_ARG(l), lvar_offset_label); } } @@ -1094,7 +1095,7 @@ we need this always because of one path compiler */ static void -code_save_input_registers(int dots) +code_save_input_registers(int dots, int arg_size) { int args; NMTBL *n; @@ -1105,6 +1106,11 @@ int reg_var = 0; int freg_var = 0; + disp -= arg_size; + offset = disp; + reg_in_arg = arg_size; + printf("\t.set %s%d,%d\n",lpfx,lvar_offset_label,reg_in_arg); + for(args = fnptr->dsp;args;args = cadr(args)) { n = ncadddr(args); tag = n->sc; @@ -1112,13 +1118,13 @@ if (!n||n==&null_nptr) error(REG_ERR); if (tag==REGISTER) { n->dsp = offset; - offset+=SIZE_OF_INT; + offset+=SIZE_OF_LONGLONG; t = INT; reg_var++; } else if (tag==FREGISTER) { n->dsp = offset; t = n->ty; - offset+=SIZE_OF_FLOAT; + offset+=SIZE_OF_DOUBLE; freg_var++; } else if (tag==DREGISTER) { n->dsp = offset; @@ -1131,7 +1137,7 @@ offset+=SIZE_OF_LONGLONG; reg_var++; } else { - offset += size(n->ty); + offset += SIZE_OF_LONGLONG; // size(n->ty); continue; } n->sc = LVAR; @@ -1173,6 +1179,7 @@ function_type(fnptr->ty,&dots); while (args) { + // we should use increment_arg /* process in reverse order */ n = ncadddr(args); type = n->ty; @@ -1182,7 +1189,7 @@ n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; reg_var++; - arg_offset_v += (caddr(args)=size(type)); + arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type)); } } else if (type==FLOAT) { if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { @@ -1190,7 +1197,7 @@ n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; freg_var++; - arg_offset_v += (caddr(args)=size(type)); + arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type)); } } else if (type==DOUBLE) { if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { @@ -1198,7 +1205,7 @@ n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; freg_var++; - arg_offset_v += (caddr(args)=size(type)); + arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type)); } } else if (type==LONGLONG||type==ULONGLONG) { if ((reg = get_input_lregister_var(reg_var,n,is_code0))) { @@ -1206,7 +1213,7 @@ n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; reg_var+=1; - arg_offset_v += (caddr(args)=size(type)); + arg_offset_v += SIZE_OF_LONGLONG; // (caddr(args)=size(type)); } } args = cadr(args); @@ -1222,7 +1229,7 @@ printf(".set %s%d, %d\n",lpfx, arg_offset_label, arg_offset_v+ arg_offset); #endif - code_save_input_registers(dots); + code_save_input_registers(dots, arg_offset_v); } } @@ -2014,7 +2021,7 @@ freg_arg++; nargs += size(t)/SIZE_OF_INT; } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { - nargs += round4(size(t))/SIZE_OF_INT; + nargs += round8(size(t))/SIZE_OF_INT; } else { error(TYERR); nargs ++ ; @@ -2903,7 +2910,7 @@ printf(".globl _%s\n",name); printf("_%s:\n",name); #endif -// lvar_offset_label = fwdlabel(); + lvar_offset_label = fwdlabel(); r1_offset_label = fwdlabel(); max_func_args = 0; printf("\tpushq %%rbp\n"); @@ -5070,7 +5077,31 @@ extern int code_arg_alignment(int args,NMTBL *n, int type0,int sz) { - return code_arg_alignment0(args,n, type0,sz); + if(type0==CHAR||type0==UCHAR) { + if (n->dsp==0) { + n->dsp = args; + if (endian) n->dsp += size_of_longlong-1; + } + args += size_of_longlong; + } else if(type0==SHORT||type0==USHORT) { + if (n->dsp==0) { + n->dsp = args; + if (endian) n->dsp += size_of_longlong-size_of_short; + } + args += size_of_longlong; + } 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_longlong); + } else { + /* if (n->dsp==0) (argument list in ADECL is useless, type + list can be found in type ) */ + n->dsp = args; + args += align(sz,size_of_longlong); + } + return args; }