Mercurial > hg > CbC > old > device
changeset 256:d80e6387c539
powerpc function call complex arugment pre computation.
(incomplete)
author | kono |
---|---|
date | Sat, 15 May 2004 12:04:56 +0900 |
parents | 8cd8d72286ae |
children | e2f5671c413d |
files | Changes mc-code-powerpc.c mc-codegen.c |
diffstat | 3 files changed, 121 insertions(+), 62 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Fri May 14 20:57:52 2004 +0900 +++ b/Changes Sat May 15 12:04:56 2004 +0900 @@ -4207,3 +4207,5 @@ その部分はcodegen でやってもいいんだけど... ia32 のような場合は むしろ不要なのか。 +でも、やっぱり、意外に複雑だよ。struct をどうするかとかさ。 +
--- a/mc-code-powerpc.c Fri May 14 20:57:52 2004 +0900 +++ b/mc-code-powerpc.c Sat May 15 12:04:56 2004 +0900 @@ -127,6 +127,8 @@ "f30","f31" }; +#define round4(i) ((i+3)&~3) + #define register_name(i) reg_name[i] #define fregister_name(i) reg_name[i] #define lregister_name_low(i) reg_name[regv_l(i)] @@ -1648,10 +1650,10 @@ e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD; } -int -simple_args(int e3) +static int +simple_arg(int e3) { - return !contains_in_list_p(e3,not_simple_p); + return !contains_p(e3,not_simple_p); } int @@ -1697,6 +1699,88 @@ if (mode) use_reg(reg); } +static void +compute_complex_arg(int e3,int reg_arg_list,int arg,int stack) { + int t=caddr(e3); + int e4 = car(e3); + reg_arg_list = list2(arg,reg_arg_list); + g_expr_u(assign_expr0(arg,e4,t,t)); + if (stack) { + car(e3) = 0; + } else { + if (car(arg)==REGISTER||car(arg)==DREGISTER|| + car(arg)==FREGISTER||car(arg)==LREGISTER) + use_input_reg(cadr(arg),1); + car(e3) = arg; + } +} + +static void +increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { + int nargs=0,reg_arg=0,freg_arg=0; + int t=caddr(e3); + if(scalar(t)) { + nargs ++ ; reg_arg++; + } else if (t==LONGLONG||t==ULONGLONG) { + nargs ++ ; reg_arg++; + nargs ++ ; reg_arg++; + } else if (t==DOUBLE||t==FLOAT) { + if (*preg_arg<MAX_INPUT_REGISTER_VAR) { + reg_arg += 2; + } + freg_arg++; + nargs += size(t)/SIZE_OF_INT; + } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { + nargs += round4(size(t)); + } else { + error(TYERR); + } + ++nargs; + *pnargs += nargs; + *preg_arg += reg_arg; + *pfreg_arg += freg_arg; +} + +static int +get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg,int *stack) +{ + *stack = 0; + if(scalar(t)) { + if (reg_arg>=MAX_INPUT_REGISTER_VAR) { + *stack = 1; + return list2(LVAR,caller_arg_offset_v(nargs)); + } + return mode?get_register_var(0):get_input_register_var(reg_arg,0,0); + } else if (t==LONGLONG||t==ULONGLONG) { + if (reg_arg>=MAX_INPUT_REGISTER_VAR) { + *stack = 1; + return list2(LVAR,caller_arg_offset_v(nargs)); + } + return mode?get_lregister_var(0):get_input_lregister_var(reg_arg,0,0); + } else if (t==FLOAT) { + if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { + *stack = 1; + return list2(LVAR,caller_arg_offset_v(nargs)); + } + return mode?get_dregister_var(0,0): + get_input_dregister_var(freg_arg,0,0,0); + } else if (t==DOUBLE) { + if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { + *stack = 1; + return list2(LVAR,caller_arg_offset_v(nargs)); + } + return mode?get_dregister_var(0,1): + get_input_dregister_var(freg_arg,0,0,1); + } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { + *stack = 1; + return list2(LVAR,caller_arg_offset_v(nargs)); + } else { + error(-1); + *stack = 1; + return list2(LVAR,caller_arg_offset_v(nargs)); + } +} + int function(int e1) { @@ -1707,6 +1791,9 @@ NMTBL *fn = 0; int jmp = 0; char *jrn; + int complex; + int pnargs,preg_arg,pfreg_arg; + int stack; special_lvar = -1; ret_type = cadr(cadddr(e1)); @@ -1734,6 +1821,20 @@ code_register(creg,cadr(jmp)); /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */ } + /* first we execute complex argument to avoid interaction with + input variables */ + complex = 0; + nargs = reg_arg = freg_arg = arg_assign = 0; + for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { + t=caddr(e3); + if (complex) { + arg = get_input_arg(t,1,pnargs,preg_arg,pfreg_arg,&stack); + compute_complex_arg(complex,reg_arg_list,arg,stack); + } + if (simple_arg(car(complex=e3))) complex=0; + pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; + increment_function_arg(e3,&nargs,®_arg,&freg_arg); + } /* now all input register vars are free */ code_save_stacks(); @@ -1741,71 +1842,41 @@ set_freg(FREG_FREGISTER,0); set_ireg(CREG_REGISTER,0); + if (complex) { + arg = get_input_arg(caddr(complex),0,pnargs,preg_arg,pfreg_arg,&stack); + compute_complex_arg(complex,reg_arg_list,arg,stack); + } + nargs = reg_arg = freg_arg = arg_assign = 0; - for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { + for (e3 = reverse0(caddr(e1)); e3; + increment_function_arg(e3,&nargs,®_arg,&freg_arg), + e3 = cadr(e3)) { + if (!(e4=car(e3))) continue; t=caddr(e3); - e4 = car(e3); + arg = get_input_arg(t,0,nargs,reg_arg,freg_arg,&stack); if(scalar(t)) { - if (reg_arg>=MAX_INPUT_REGISTER_VAR) { - arg = list2(LVAR,caller_arg_offset_v(nargs)); - } else if (!simple_args(e3) && cadr(e3)) { - arg = get_register_var(0); - arg_assign = list2( - assign_expr0(get_input_register_var(reg_arg,0,0), - arg,t,t), - arg_assign); - } else { - arg = get_input_register_var(reg_arg,0,0); - } reg_arg_list = list2(arg,reg_arg_list); /* protect from input register free */ if (car(arg)==REGISTER) use_input_reg(cadr(arg),1); g_expr_u(assign_expr0(arg,e4,t,t)); - nargs ++ ; reg_arg++; continue; } else if (t==LONGLONG||t==ULONGLONG) { if (reg_arg>=MAX_INPUT_REGISTER_VAR) { - arg = list2(LVAR,caller_arg_offset_v(nargs)); } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { // half register, half memory case // put whole long long anyway - arg = list2(LVAR,caller_arg_offset_v(nargs)); arg_assign = list2( assign_expr0(r0=get_input_register_var(reg_arg,0,0), arg,INT,INT), arg_assign); use_input_reg(cadr(r0),1); - } else if (!simple_args(e3) && cadr(e3)) { - arg = get_lregister_var(0); - if (car(arg)==LREGISTER) { - // r0=get_input_lregiste... is not preserved - // we cannot mark r0 used, it consumes unused register - // but get_input_register is preserved. - arg_assign = list2( - assign_expr0(get_input_register_var(reg_arg,0,0), - list2(REGISTER,regv_h(cadr(arg))),INT,INT), - list2( - assign_expr0(get_input_register_var(reg_arg+1,0,0), - list2(REGISTER,regv_l(cadr(arg))),INT,INT), - arg_assign)); - } else { - arg_assign = list2( - assign_expr0(get_input_register_var(reg_arg,0,0), - list2(LVAR,cadr(arg)+SIZE_OF_INT),INT,INT), - list2( - assign_expr0(get_input_register_var(reg_arg+1,0,0), - list2(LVAR,cadr(arg)),INT,INT), - arg_assign)); - } } else { - arg = get_input_lregister_var(reg_arg,0,0); - use_input_reg(cadr(arg),1); + if (car(arg)==LREGISTER) + use_input_reg(cadr(arg),1); } reg_arg_list = list2(arg,reg_arg_list); g_expr_u(assign_expr0(arg,e4,t,t)); - nargs ++ ; reg_arg++; - nargs ++ ; reg_arg++; continue; } else if (t==DOUBLE||t==FLOAT) { if (reg_arg<MAX_INPUT_REGISTER_VAR) { @@ -1839,7 +1910,6 @@ list2(LVAR,special_lvar+SIZE_OF_INT), INT,INT), arg_assign); } - reg_arg += 2; } if (dots && freg_arg>=4 && freg_arg<MAX_INPUT_DREGISTER_VAR) { /* oh my god! @@ -1851,32 +1921,17 @@ get_input_dregister_var(freg_arg,0,0,1),t,t), arg_assign); } - if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { - arg = list2(LVAR,caller_arg_offset_v(nargs)); - } else if (!simple_args(e3) && cadr(e3)) { - arg = get_dregister_var(0,1); - arg_assign = list2( - assign_expr0(get_input_dregister_var(freg_arg,0,0,1), - arg,t,t), - arg_assign); - } else { - arg = get_input_dregister_var(freg_arg,0,0,1); - } reg_arg_list = list2(arg,reg_arg_list); if (car(arg)==DREGISTER) use_input_reg(cadr(arg),1); /* protect from input register free */ g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ - freg_arg++; - nargs += size(t)/SIZE_OF_INT; continue; } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { - arg = list2(LVAR,caller_arg_offset_v(nargs)); - nargs += struct_push(e4,t,arg); + struct_push(e4,t,arg); continue; } else { error(TYERR); } - ++nargs; } if (max_func_args<nargs) max_func_args=nargs; for(;arg_assign;arg_assign=cadr(arg_assign)) {
--- a/mc-codegen.c Fri May 14 20:57:52 2004 +0900 +++ b/mc-codegen.c Sat May 15 12:04:56 2004 +0900 @@ -1636,6 +1636,7 @@ { while(e) { if (car(e)==type) return 1; + if (!car(e)) return 0; if (LIST_ARGS(car(e))){ /* list arguments */ return contains_in_list(caddr(e),type); @@ -1680,6 +1681,7 @@ contains_p(int e,int (*p)(int)) { while(e) { + if (!car(e)) return 0; if (p(car(e))) return 1; if (LIST_ARGS(car(e))){ /* list arguments */