Mercurial > hg > CbC > old > device
changeset 741:ebf5ae3f3863
i64 continue...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 09 Nov 2010 17:56:33 +0900 |
parents | 8cd40338aee6 |
children | bdae6a221174 |
files | .gdbinit mc-code-i64.c test/tstdarg.c |
diffstat | 3 files changed, 159 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Mon Nov 08 22:30:10 2010 +0900 +++ b/.gdbinit Tue Nov 09 17:56:33 2010 +0900 @@ -20,7 +20,8 @@ # r -s test/tmpa.c # r -s test/code-gen-all.c # r -s mc-code-powerpc.c -r -s test/macro.c +# r -s test/macro.c +r -s test/basic.c # r -s test/strinit.c # r -s test/arg.c # r -s -DINLINE=inline test/strinit.c
--- a/mc-code-i64.c Mon Nov 08 22:30:10 2010 +0900 +++ b/mc-code-i64.c Tue Nov 09 17:56:33 2010 +0900 @@ -305,7 +305,7 @@ %rdi arg1 see enter/enter1/leave see code_enter */ -// static int arg_offset; +static int arg_offset_v; static int code_disp_label; @@ -371,7 +371,7 @@ #define REG_EAX 7 #define REG_EBX 8 #define is_int_reg(reg) (1<=reg&®<MAX_REGISTER) -#define is_float_reg(reg) (RET_FREGISTER<=reg&®<REAL_MAX_REGISTER) +#define is_float_reg(reg) (RET_FREGISTER<=reg&®<FREG_OFFSET+REAL_MAX_DREGISTER) // return value register #define RET_FREGISTER 18 @@ -1083,6 +1083,75 @@ printf("\n"); } +/* + store input argument into stack + we need this always because of one path compiler + */ +static void +code_save_input_registers(int dots) +{ + int args; + NMTBL *n; + int reg; + int tag; + int t; + int offset = 0; + int reg_var = 0; + int freg_var = 0; + + for(args = fnptr->dsp;args;args = cadr(args)) { + n = ncadddr(args); + tag = n->sc; + reg = n->dsp; + if (!n||n==&null_nptr) error(REG_ERR); + if (tag==REGISTER) { + n->dsp = offset; + offset+=SIZE_OF_INT; + t = INT; + reg_var++; + } else if (tag==FREGISTER) { + n->dsp = offset; + t = n->ty; + offset+=SIZE_OF_FLOAT; + freg_var++; + } else if (tag==DREGISTER) { + n->dsp = offset; + t = n->ty; + offset+=SIZE_OF_DOUBLE; + freg_var++; + } else if (tag==LREGISTER) { + n->dsp = offset; + t = n->ty; + offset+=SIZE_OF_LONGLONG; + reg_var++; + } else { + offset += size(n->ty); + continue; + } + n->sc = LVAR; + g_expr_u(assign_expr0(list3n(LVAR,n->dsp,0),list3n(tag,reg,n),t,t)); + if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) { + free_register(reg); + } + } + 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; + reg_var++; + } + // Intel64 keeps number of double value in %al + while ((reg = get_input_dregister_var(freg_var,0,0,0))) { + g_expr_u(assign_expr0( + list3n(LVAR,offset,0),reg,DOUBLE,DOUBLE)); + offset+=SIZE_OF_DOUBLE; + freg_var++; + } + } + // my_func_args = offset; +} + void code_arg_register(NMTBL *fnptr) { @@ -1092,39 +1161,65 @@ int freg_var = 0; int type; int reg; - int offset = 0; int is_code0 = is_code(fnptr); - + int dots; + arg_offset_v = 0; + + function_type(fnptr->ty,&dots); while (args) { /* process in reverse order */ n = ncadddr(args); type = n->ty; - // n->dsp = offset; -// printf("### %s %d %d\n",n->nm,n->dsp,n->ty); if (scalar(type)) { - int sz =size(type)<=SIZE_OF_INT?SIZE_OF_INT:size(type); if ((reg = get_input_register_var(reg_var,n,is_code0))) { n->sc = REGISTER; n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; reg_var++; - caddr(args)=sz; + arg_offset_v += (caddr(args)=SIZE_OF_INT); } - offset+=sz; - } else if (type==FLOAT||type==DOUBLE) { + } else if (type==FLOAT) { + if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { + n->sc = DREGISTER; + n->dsp = cadr(reg); + regs[n->dsp]= INPUT_REG; + freg_var++; + arg_offset_v += (caddr(args)=size(type)); + } + } else if (type==DOUBLE) { if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { n->sc = DREGISTER; n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; freg_var++; - caddr(args)=size(type); /* why we need this? */ + arg_offset_v += (caddr(args)=size(type)); } - offset+=size(type); - } else - offset+=size(type); + } else if (type==LONGLONG||type==ULONGLONG) { + if ((reg = get_input_lregister_var(reg_var,n,is_code0))) { + n->sc = LREGISTER; + n->dsp = cadr(reg); + regs[n->dsp]= INPUT_REG; + reg_var+=1; + arg_offset_v += (caddr(args)=size(type)); + } + } 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_DREGISTER_VAR*SIZE_OF_DOUBLE; + } + printf(".set %s%d, %d\n",lpfx, arg_offset_label, + arg_offset_v+ arg_offset); +#endif + code_save_input_registers(dots); + } +} + void gexpr_init(void) @@ -1863,10 +1958,9 @@ } if(scalar(t)) { nargs ++ ; reg_arg++; - if (size(t)>SIZE_OF_INT) nargs++; } else if (t==LONGLONG||t==ULONGLONG) { + nargs ++ ; reg_arg++; nargs ++ ; - nargs ++ ; reg_arg++; } else if (t==FLOAT) { freg_arg++; nargs += size(t)/SIZE_OF_INT; @@ -1885,52 +1979,61 @@ } + #define AS_SAVE 1 #define AS_ARG 0 +/* + set storage type of caller's arguments + register or stack + this muse corprate with code_arg_register(); + if AS_SAVE is set, register variable (or temporary local variable) + is used. + */ + static int -get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) +get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) { + t = type_value(t); + if (t>=0&&(car(t)==BIT_FIELD)) { + t = type_value(cadr(t)); + } if(scalar(t)) { if (mode==AS_SAVE) { - if (parse_mode) - return get_register_var(0); - return list3n(LVAR,new_lvar(size(t)),0); - } else + return get_register_var(0); + } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { return list3n(LVAR,caller_arg_offset_v(nargs),0); + } else + return get_input_register_var(reg_arg,0,0); } else if (t==LONGLONG||t==ULONGLONG) { if (mode==AS_SAVE) { - if (parse_mode) - return get_lregister_var(0); - return list3n(LVAR,new_lvar(size(t)),0); - } else + return get_lregister_var(0); + } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { return list3n(LVAR,caller_arg_offset_v(nargs),0); + } else + return get_input_lregister_var(reg_arg,0,0); } else if (t==FLOAT) { if (mode==AS_SAVE) { - if (parse_mode) - return get_dregister_var(0,0); - return list3n(LVAR,new_lvar(size(t)),0); + return get_dregister_var(0,0); + } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { + return list3n(LVAR,caller_arg_offset_v(nargs),0); } else - return list3n(LVAR,caller_arg_offset_v(nargs),0); + return get_input_dregister_var(freg_arg,0,0,0); } else if (t==DOUBLE) { if (mode==AS_SAVE) { - if (parse_mode) - return get_dregister_var(0,1); - return list3n(LVAR,new_lvar(size(t)),0); + return get_dregister_var(0,1); + } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { + return list3n(LVAR,caller_arg_offset_v(nargs),0); } else - return list3n(LVAR,caller_arg_offset_v(nargs),0); + return get_input_dregister_var(freg_arg,0,0,1); } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { if (mode==AS_SAVE) { - if (parse_mode) - return get_register_var(0); - return list3n(LVAR,new_lvar(size(t)),0); + return get_register_var(0); } else return list3n(LVAR,caller_arg_offset_v(nargs),0); } else { error(-1); - if (parse_mode) - return get_register_var(0); - return list3n(LVAR,new_lvar(size(t)),0); + return get_register_var(0); } } @@ -2097,7 +2200,6 @@ } #endif } - nargs = reg_arg = freg_arg = 0; // calc stack arguments first, it may requires extra registers, // and we can still use input registers now. @@ -2116,6 +2218,10 @@ g_expr_u(car(arg_assign)); } clear_ptr_cache(); + if (dots) { + // needs number of fregister in double + printf("\tmovl $%d,%%eax\n", freg_arg); + } code_call(e2,fn,jmp); free_register_var(reg_arg_list); if (ret_type==DOUBLE||ret_type==FLOAT) { @@ -3211,10 +3317,10 @@ printf("\t%s %s,",fstore(d),fregister_name(freg)); lvar(e2); printf("\n"); } -void code_dassign_dregister(int e,int d,int freg) +void code_dassign_dregister(int e,int d,int f) { - int reg = cadr(e); - printf("\tmovapd %s,%s",fregister_name(freg),register_name(reg,0)); + use_float(d,f); + printf("\tmovapd %s,%s",fregister_name(f),fregister_name(e)); } void code_dassign(int e2,int freg,int d) @@ -3409,7 +3515,7 @@ void code_drlvar(int e2,int d,int freg) { - printf("\t%s ",fload(d)); lvar(e2); printf(",%s\n", register_name(freg,0)); + printf("\t%s ",fload(d)); lvar(e2); printf(",%s\n", fregister_name(freg)); } void code_cmp_drgvar(int e2,int reg,int d,int label,int cond) @@ -3707,7 +3813,11 @@ void code_dregister(int e2,int freg,int d) { - error(-1); + use_float(d,freg); + if (freg!=e2) { + if (is_int_reg(e2)) error(-1); + printf("\ttmovap%s %s,%s\n",d?"d":"s",fregister_name(freg),fregister_name(e2)); + } } void
--- a/test/tstdarg.c Mon Nov 08 22:30:10 2010 +0900 +++ b/test/tstdarg.c Tue Nov 09 17:56:33 2010 +0900 @@ -20,7 +20,7 @@ if (t=='i') { i = va_arg(ap,int); printf("#0021:int arg: %d\n",i); -#if 0 +#if 0 /* ‘float’ is promoted to ‘double’ when passed through ‘...’ */ } else if (t=='f') { f = va_arg(ap,float); printf("#0025:float arg: %g\n",f);