Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 255:8cd8d72286ae
PowerPC long long complex function call fix.
MIPS entry frame calc.
author | kono |
---|---|
date | Fri, 14 May 2004 20:57:52 +0900 |
parents | 1452eb0eab20 |
children | d80e6387c539 |
line wrap: on
line diff
--- a/mc-code-powerpc.c Wed May 12 21:44:45 2004 +0900 +++ b/mc-code-powerpc.c Fri May 14 20:57:52 2004 +0900 @@ -636,7 +636,7 @@ int i,j,ll; int max_reg_var_save=max_reg_var; ll = get_lregister0(); - if (ll==-1) return -1; + if (ll==-1) goto not_found; if (regs[ll]==0) { for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ @@ -1554,6 +1554,19 @@ // save_stack,clear_ptr_cache is assmued if (!is_longlong_reg(reg)) { error(-1); return; } if (mode) { + if (regv_l(reg)!=3) + printf("\tmr r3,%s\n", lregister_name_high(reg)); + if (regv_l(reg)!=4) + printf("\tmr r4,%s\n", lregister_name_low(reg)); + } +} + +void +set_lreg_operand1(int reg,int mode) +{ + // save_stack,clear_ptr_cache is assmued + if (!is_longlong_reg(reg)) { error(-1); return; } + if (mode) { if (regv_l(reg)!=5) printf("\tmr r5,%s\n", lregister_name_high(reg)); if (regv_l(reg)!=6) @@ -1630,8 +1643,9 @@ static int not_simple_p(int e3) { - return (e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| - (((e3/100)==LOP)&&(e3!=LREGISTER||e3!=LADD||e3!=LSUB))); + return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| + e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| + e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD; } int @@ -1764,11 +1778,26 @@ use_input_reg(cadr(r0),1); } else if (!simple_args(e3) && cadr(e3)) { arg = get_lregister_var(0); - arg_assign = list2( - assign_expr0(r0=get_input_lregister_var(reg_arg,0,0), - arg,t,t), - arg_assign); - use_input_reg(cadr(r0),1); + 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); @@ -3724,12 +3753,13 @@ #endif static void -code_asld_lib(int oreg) +code_asld_lib(int reg,int oreg) { code_save_stacks(); clear_ptr_cache(); asld_lib_used = 1; - set_lreg(RET_LREGISTER,1); + set_lreg_operand(reg,1); + set_lreg(RET_LREGISTER,0); if (regv_l(oreg)!=5) { printf("\tmr r5,%s\n", lregister_name_low(oreg)); } @@ -3737,12 +3767,13 @@ } static void -code_asrd_lib(int oreg) // ___ashrdi3$stub +code_asrd_lib(int reg,int oreg) // ___ashrdi3$stub { code_save_stacks(); clear_ptr_cache(); asrd_lib_used = 1; - set_lreg(RET_LREGISTER,1); + set_lreg_operand(reg,1); + set_lreg(RET_LREGISTER,0); if (regv_l(oreg)!=5) { printf("\tmr r5,%s\n", lregister_name_low(oreg)); } @@ -3750,12 +3781,13 @@ } static void -code_lsrd_lib(int oreg) // ___lshrdi3$stub +code_lsrd_lib(int reg,int oreg) // ___lshrdi3$stub { code_save_stacks(); clear_ptr_cache(); lsrd_lib_used = 1; - set_lreg(RET_LREGISTER,1); + set_lreg_operand(reg,1); + set_lreg(RET_LREGISTER,0); if (regv_l(oreg)!=5) { printf("\tmr r5,%s\n", lregister_name_low(oreg)); } @@ -3763,42 +3795,46 @@ } static void -code_ldiv_lib(int oreg) // ___divdi3$stub +code_ldiv_lib(int reg,int oreg) // ___divdi3$stub { code_save_stacks(); clear_ptr_cache(); - set_lreg(RET_LREGISTER,1); - set_lreg_operand(oreg,1); + set_lreg_operand(reg,1); + set_lreg(RET_LREGISTER,0); + set_lreg_operand1(oreg,1); extern_conv("__divdi3"); } static void -code_ludiv_lib(int oreg) // ___udivdi3$stub +code_ludiv_lib(int reg,int oreg) // ___udivdi3$stub { code_save_stacks(); clear_ptr_cache(); - set_lreg(RET_LREGISTER,1); - set_lreg_operand(oreg,1); + set_lreg_operand(reg,1); + set_lreg(RET_LREGISTER,0); + set_lreg_operand1(oreg,1); extern_conv("__udivdi3"); } static void -code_lmod_lib(int oreg) // ___moddi3$stub +code_lmod_lib(int reg,int oreg) // ___moddi3$stub { code_save_stacks(); clear_ptr_cache(); - set_lreg(RET_LREGISTER,1); - set_lreg_operand(oreg,1); + set_lreg_operand(reg,1); + set_lreg(RET_LREGISTER,0); + set_lreg_operand1(oreg,1); extern_conv("__moddi3"); } static void -code_lumod_lib(int oreg) // ___umoddi3$stub +code_lumod_lib(int reg,int oreg) // ___umoddi3$stub { code_save_stacks(); clear_ptr_cache(); - set_lreg(RET_LREGISTER,1); - set_lreg_operand(oreg,1); + set_lreg(RET_LREGISTER,0); + set_lreg_operand(reg,1); + set_lreg_operand1(oreg,1); extern_conv("__umoddi3"); } @@ -3826,17 +3862,17 @@ switch(op) { case LLSHIFT: case LULSHIFT: - code_asld_lib(oreg); // ___ashldi3$stub + code_asld_lib(reg,oreg); // ___ashldi3$stub check_lreg(reg); if(ox!=-1) free_register(ox); return; case LRSHIFT: - code_asrd_lib(oreg); // ___ashrdi3$stub + code_asrd_lib(reg,oreg); // ___ashrdi3$stub check_lreg(reg); if(ox!=-1) free_register(ox); return; case LURSHIFT: - code_lsrd_lib(oreg); // ___lshrdi3$stub + code_lsrd_lib(reg,oreg); // ___lshrdi3$stub check_lreg(reg); if(ox!=-1) free_register(ox); return; @@ -3895,19 +3931,19 @@ printf("\tmr %s,%s\n", crn_l,drn_l); break; case LDIV: - code_ldiv_lib(oreg); // ___divdi3$stub + code_ldiv_lib(reg,oreg); // ___divdi3$stub check_lreg(reg); break; case LUDIV: - code_ludiv_lib(oreg); // ___udivdi3$stub + code_ludiv_lib(reg,oreg); // ___udivdi3$stub check_lreg(reg); break; case LMOD: - code_lmod_lib(oreg); // ___moddi3$stub + code_lmod_lib(reg,oreg); // ___moddi3$stub check_lreg(reg); break; case LUMOD: - code_lumod_lib(oreg); // ___umoddi3$stub + code_lumod_lib(reg,oreg); // ___umoddi3$stub check_lreg(reg); break; default: