Mercurial > hg > CbC > old > device
changeset 260:9843979a270e
mips fix
author | kono |
---|---|
date | Sat, 15 May 2004 21:36:16 +0900 |
parents | 18837238e306 |
children | 31d7f050ec0d |
files | mc-code-mips.c mc-code-powerpc.c mc-parse.c stdio.h |
diffstat | 4 files changed, 202 insertions(+), 104 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-mips.c Sat May 15 21:11:01 2004 +0900 +++ b/mc-code-mips.c Sat May 15 21:36:16 2004 +0900 @@ -1677,9 +1677,9 @@ } int -simple_args(int e3) +simple_arg(int e3) { - return !contains_in_list_p(e3,not_simple_p); + return !contains_p(e3,not_simple_p); } int @@ -1765,20 +1765,105 @@ } } +static void +compute_complex_arg(int e3,int reg_arg_list,int arg) { + 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 (car(arg)==REGISTER||car(arg)==DREGISTER|| + car(arg)==FREGISTER||car(arg)==LREGISTER) + use_input_reg(cadr(arg),1); + car(e3) = arg; +} + +#define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) + +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||DOUBLE) { + nargs ++ ; reg_arg++; + nargs ++ ; reg_arg++; + } else if (t==FLOAT) { + nargs ++ ; reg_arg ++ ; 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; + } else { + error(TYERR); + nargs ++ ; + } + *pnargs += nargs; + *preg_arg += reg_arg; + *pfreg_arg += freg_arg; +} + +#define AS_SAVE 1 +#define AS_ARG 0 + +static int +get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) +{ + if(scalar(t)) { + if (mode==AS_SAVE) { + return get_register_var(0); + } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { + return list2(LVAR,caller_arg_offset_v(nargs)); + } else + return get_input_register_var(reg_arg,0,0); + } else if (t==LONGLONG||t==ULONGLONG) { + if (mode==AS_SAVE) { + return get_lregister_var(0); + } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { + return list2(LVAR,caller_arg_offset_v(nargs)); + } else + return get_input_lregister_var(reg_arg,0,0); + } else if (t==FLOAT) { + if (mode==AS_SAVE) { + return get_dregister_var(0,0); + } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { + return list2(LVAR,caller_arg_offset_v(nargs)); + } else + return get_input_dregister_var(freg_arg,0,0,0); + } else if (t==DOUBLE) { + if (mode==AS_SAVE) { + return get_dregister_var(0,1); + } else if (reg_arg+1>=MAX_INPUT_DREGISTER_VAR) { + return list2(LVAR,caller_arg_offset_v(nargs)); + } else + return get_input_dregister_var(freg_arg,0,0,1); + } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { + if (mode==AS_SAVE) { + return get_register_var(0); + } else + return list2(LVAR,caller_arg_offset_v(nargs)); + } else { + error(-1); + return get_register_var(0); + } +} + int function(int e1) { - int e2,e3,e4,nargs,t,r0; + int e2,e3,e4,e5,nargs,t,r0; int arg,reg_arg,freg_arg,arg_assign; int dots; int reg_arg_list=0,ret_type,special_lvar; NMTBL *fn = 0; int jmp = 0; char *jrn; + int complex_; + int pnargs,preg_arg,pfreg_arg; + int stargs; special_lvar = -1; ret_type = cadr(cadddr(e1)); - if (ret_type==CHAR) ret_type=INT; + if (ret_type==CHAR) ret_type=INT; // ??? /* check argments type is DOTS? */ t = caddr(cadddr(e1)); @@ -1802,6 +1887,42 @@ 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 */ + stargs = 0; + complex_ = 0; + nargs = reg_arg = freg_arg = 0; + for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { + t=caddr(e3); + if ((e5= !simple_arg(car(e3)))) { + if (complex_) { + arg = get_input_arg(caddr(complex_),AS_SAVE, + pnargs,preg_arg,pfreg_arg); + compute_complex_arg(complex_,reg_arg_list,arg); + } + pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; + complex_ = e3; + } + if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { + // The struct should be pushed after complex arguments. + if (e5) { // compute address only, complex_ is me now. Clear it. + complex_ = 0; + e4 = car(e3); + if (car(e4)!=RSTRUCT) error(-1); + if (!simple_arg(cadr(e4))) { + // Calculate complex struct address here. + // If simple, leave it. + arg = get_register_var(0); + g_expr_u(assign_expr0(arg,list2(ADDRESS,car(e3)),INT,INT)); + car(e3)=arg; + reg_arg_list = list2(arg,reg_arg_list); + if (car(arg)==REGISTER) use_input_reg(cadr(arg),1); + } + } + stargs = list4(e3,stargs,nargs,reg_arg); + } + increment_function_arg(e3,&nargs,®_arg,&freg_arg); + } /* now all input register vars are free */ code_save_stacks(); @@ -1809,117 +1930,94 @@ set_freg(FREG_FREGISTER,0); set_ireg(CREG_REGISTER,0); + if (complex_) { + arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); + compute_complex_arg(complex_,reg_arg_list,arg); + } + for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { + e3 = car(stargs); + e4 = car(e3); + t = caddr(e3); + arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); + struct_push(e4,t,arg); + car(e3)=0; // done + } + nargs = reg_arg = freg_arg = arg_assign = 0; - for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { + // calc stack arguments first + for (e3 = 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,AS_ARG,nargs,reg_arg,freg_arg); + if (car(arg)!=LVAR) continue; + g_expr_u(assign_expr0(arg,e4,t,t)); + if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) { + if (reg_arg+1==MAX_INPUT_REGISTER_VAR) { + // half register, half memory case + 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); + } + } + car(e3)=0; // done + } + nargs = reg_arg = freg_arg = 0; + for (e3 = e1; e3; + increment_function_arg(e3,&nargs,®_arg,&freg_arg), + e3 = cadr(e3)) { + if (!(e4=car(e3))) continue; + t=caddr(e3); + arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); 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||t==DOUBLE) { - if (reg_arg>=MAX_INPUT_REGISTER_VAR) { - arg = list2(LVAR,caller_arg_offset_v(nargs)); - } else if (!simple_args(e3) && cadr(e3)) { - arg = t==DOUBLE?get_dregister_var(0,1):get_lregister_var(0); - if (car(arg)==LREGISTER||car(arg)==DREGISTER) { - // r0=get_input_lregiste... is not preserved - // we cannot mark r0 used, it consumes unused register - // but get_input_register is preserved. - // Beware endian. - arg_assign = list2( - assign_expr0(get_input_register_var(reg_arg,0,0), - list2(REGISTER,regv_l(cadr(arg))),INT,INT), - list2( - assign_expr0(get_input_register_var(reg_arg+1,0,0), - list2(REGISTER,regv_h(cadr(arg))),INT,INT), - arg_assign)); - } else { - arg_assign = list2( - assign_expr0(get_input_register_var(reg_arg,0,0), - list2(LVAR,cadr(arg)),INT,INT), - list2( - assign_expr0(get_input_register_var(reg_arg+1,0,0), - list2(LVAR,cadr(arg)+SIZE_OF_INT),INT,INT), - arg_assign)); - } - + } else if (t==LONGLONG||t==ULONGLONG) { + if (reg_arg+1==MAX_INPUT_REGISTER_VAR) { + // half register, half memory case + // put whole long long anyway + 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 { - arg = t==DOUBLE?get_input_dregister_var(reg_arg,0,0,1): - 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) { + reg_arg_list = list2(arg,reg_arg_list); + if (car(arg)==DREGISTER) + use_input_reg(cadr(arg),1); } else if (t==FLOAT) { - if (freg_arg>=MAX_INPUT_FREGISTER_VAR) { - arg = list2(LVAR,caller_arg_offset_v(nargs)); - } else if (!simple_args(e3) && cadr(e3)) { - arg = get_dregister_var(0,0); - if (freg_arg<2) { - arg_assign = list2( - list3(FASS_INPUT, - get_input_dregister_var(freg_arg,0,0,0),arg), - arg_assign); - } else { - arg_assign = list2( - assign_expr0(get_input_dregister_var(freg_arg,0,0,0), - arg,t,t), - arg_assign); - } - } else { - arg = get_input_dregister_var(freg_arg,0,0,0); - } reg_arg_list = list2(arg,reg_arg_list); - if (car(arg)==FREGISTER) { + if (car(arg)==FREGISTER) { + use_input_reg(cadr(arg),1);/* protect from input register free */ + g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ + } else if (car(arg)==REGISTER) { use_input_reg(cadr(arg),1);/* protect from input register free */ - g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ - } else if (car(arg)==REGISTER) { - code_assign_input_float_int(list3(FASS_INPUT, arg, e4)); - } else { - 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); - continue; - } else { - error(TYERR); + code_assign_input_float_int(list3(FASS_INPUT, arg, e4)); + } else { + g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ + } } - ++nargs; + // structs are finished } if (max_func_args<nargs) max_func_args=nargs; for(;arg_assign;arg_assign=cadr(arg_assign)) { - if (car(car(arg_assign))==FASS_INPUT) { - code_assign_input_float_int(car(arg_assign)); - } else { - g_expr_u(car(arg_assign)); - } + g_expr_u(car(arg_assign)); } clear_ptr_cache(); - if (car(e2) == FNAME) { - printf("\tjal\t%s\n",fn->nm); + if (car(e2) == FNAME) { + printf("\tjal\t%s\n",fn->nm); } else { jrn = register_name(cadr(jmp)); printf("\tj %s\n",jrn); @@ -1932,16 +2030,16 @@ else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); } if (ret_type==DOUBLE) { - set_dreg(RET_DREGISTER,0); - use_reg(RET_DREGISTER); - } else if (ret_type==DOUBLE||ret_type==FLOAT) { - set_freg(RET_FREGISTER,0); + set_dreg(RET_DREGISTER,0); + use_reg(RET_DREGISTER); + } else if (ret_type==FLOAT) { + set_freg(RET_FREGISTER,0); } else if (ret_type==ULONGLONG||ret_type==LONGLONG) { - set_lreg(RET_LREGISTER,0); - use_reg(RET_LREGISTER); + set_lreg(RET_LREGISTER,0); + use_reg(RET_LREGISTER); } else if (ret_type==VOID) { } else { - set_ireg(RET_REGISTER,0); + set_ireg(RET_REGISTER,0); } return ret_type; }
--- a/mc-code-powerpc.c Sat May 15 21:11:01 2004 +0900 +++ b/mc-code-powerpc.c Sat May 15 21:36:16 2004 +0900 @@ -127,7 +127,7 @@ "f30","f31" }; -#define round4(i) ((i+3)&~3) +#define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) #define register_name(i) reg_name[i] #define fregister_name(i) reg_name[i]
--- a/mc-parse.c Sat May 15 21:11:01 2004 +0900 +++ b/mc-parse.c Sat May 15 21:36:16 2004 +0900 @@ -1024,7 +1024,7 @@ args += size_of_int; } else if(type>0&&(type==UNION||type==STRUCT)) { n->dsp = args; - args += ((sz+(size_of_int-1))&~size_of_int); + args += ((sz+(size_of_int-1))&~(size_of_int-1)); } else { /* if (n->dsp==0) (argument list in ADECL is useless, type list can be found in type ) */