Mercurial > hg > CbC > old > device
changeset 400:a9427845ca4c
ARM test/basic test pass.
author | kono |
---|---|
date | Sat, 16 Oct 2004 16:08:41 +0900 |
parents | 9d0015a1fa54 |
children | d621a113b0ca |
files | Makefile mc-code-arm.c |
diffstat | 2 files changed, 33 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat Oct 16 10:29:51 2004 +0900 +++ b/Makefile Sat Oct 16 16:08:41 2004 +0900 @@ -83,6 +83,7 @@ make check TARGET=test/bitfield make check TARGET=test/bitfield1 make check TARGET=test/cext + make check TARGET=test/const # make check TARGET=test/scope STDFLAG="-std=gnu99" #MK =-make MK=
--- a/mc-code-arm.c Sat Oct 16 10:29:51 2004 +0900 +++ b/mc-code-arm.c Sat Oct 16 16:08:41 2004 +0900 @@ -39,6 +39,7 @@ static int search_const(int tag,int value,int *label); static char * cstore(int sz); static void code_int_lib(char *lib,int reg,int oreg); +static int caller_arg_offset_v(int arg); #if FLOAT_CODE static int code_d1(double d); static int code_d2(double d); @@ -2131,18 +2132,27 @@ if (!n||n==&null_nptr) error(REG_ERR); if (tag==REGISTER) { /* regs[reg]==INPUT_REG case should be considered */ - n->dsp = new_lvar(SIZE_OF_INT); + n->dsp = new_lvar(SIZE_OF_INT); n->sc = LVAR; offset+=SIZE_OF_INT; t = INT; reg_var++; } else if (tag==LREGISTER) { /* regs[reg]==INPUT_REG case should be considered */ - n->dsp = new_lvar(SIZE_OF_LONGLONG); + n->dsp = new_lvar(SIZE_OF_LONGLONG); n->sc = LVAR; // t = n->ty; t = LONGLONG; offset+=SIZE_OF_LONGLONG; reg_offset+=2; reg_var += 2; } else { + if (reg_var==3 && (n->ty==DOUBLE||n->ty==LONGLONG||n->ty==ULONGLONG)) { + // half register, half stack case + n->dsp = new_lvar(SIZE_OF_LONGLONG); n->sc = LVAR; + g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(REGISTER,4,0),INT,INT)); + g_expr_u(assign_expr0(list2(LVAR,n->dsp+SIZE_OF_INT), + list2(LVAR,caller_arg_offset_v(offset)),INT,INT)); + free_register(4); + offset -= SIZE_OF_INT; + } offset += size(n->ty); continue; } @@ -2181,7 +2191,7 @@ return !contains_p(e3,not_simple_p); } -int +static int caller_arg_offset_v(int arg) { return ARG_LVAR_OFFSET+arg*SIZE_OF_INT; @@ -2317,8 +2327,14 @@ if(scalar(t)) { nargs ++ ; reg_arg++; } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) { - if (*preg_arg%2==1) reg_arg++; // alignment - if (*pnargs%2==1) nargs++; // alignment +#if 0 + if (*preg_arg>3 && *preg_arg%2==1) reg_arg++; // alignment + if (*preg_arg>3 && *pnargs%2==1) nargs++; // alignment + if (*preg_arg==3) { + // half register, half stack case + nargs --; + } +#endif nargs ++ ; reg_arg++; nargs ++ ; reg_arg++; } else if (t==FLOAT) { @@ -2349,8 +2365,6 @@ } else return get_input_register_var(reg_arg,0,0); } else if (t==LONGLONG||t==ULONGLONG) { - if (reg_arg%2==1) reg_arg++; // alignment - if (nargs%2==1) nargs++; // alignment if (mode==AS_SAVE) { return get_lregister_var(0); } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { @@ -2408,6 +2422,7 @@ int complex_; int pnargs,preg_arg,pfreg_arg; int stargs; + int half_register = 0; special_lvar = -1; ret_type = cadr(cadddr(e1)); @@ -2446,12 +2461,16 @@ nargs = reg_arg = freg_arg = 0; for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { t=caddr(e3); + if (reg_arg==3 && (t==DOUBLE||t==LONGLONG||t==ULONGLONG)) { + half_register=1; + } if ((e5= !simple_arg(car(e3)))) { if (complex_) { arg = get_input_arg(caddr(complex_),AS_SAVE, pnargs,preg_arg,pfreg_arg); reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); } + // memorise last complex arg parameter pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; complex_ = e3; } @@ -2566,6 +2585,12 @@ for(;arg_assign;arg_assign=cadr(arg_assign)) { g_expr_u(car(arg_assign)); } + if (half_register) { + // half register case writes *(sp-1) but it will be Ok. + if (max_func_args<4) max_func_args=4; + g_expr_u(assign_expr0(list3(REGISTER,4,0), + list2(LVAR,caller_arg_offset_v(3)),INT,INT)); + } clear_ptr_cache(); code_call(e2,fn,jmp); for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {