Mercurial > hg > CbC > old > device
comparison 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 |
comparison
equal
deleted
inserted
replaced
254:5aaca4f9d96b | 255:8cd8d72286ae |
---|---|
634 get_lregister_var(NMTBL *n) | 634 get_lregister_var(NMTBL *n) |
635 { | 635 { |
636 int i,j,ll; | 636 int i,j,ll; |
637 int max_reg_var_save=max_reg_var; | 637 int max_reg_var_save=max_reg_var; |
638 ll = get_lregister0(); | 638 ll = get_lregister0(); |
639 if (ll==-1) return -1; | 639 if (ll==-1) goto not_found; |
640 if (regs[ll]==0) { | 640 if (regs[ll]==0) { |
641 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 641 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { |
642 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ | 642 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ |
643 /* そのレジスタを使うことを宣言し */ | 643 /* そのレジスタを使うことを宣言し */ |
644 regs[REG_VAR_BASE-i]=USING_REG; | 644 regs[REG_VAR_BASE-i]=USING_REG; |
1552 set_lreg_operand(int reg,int mode) | 1552 set_lreg_operand(int reg,int mode) |
1553 { | 1553 { |
1554 // save_stack,clear_ptr_cache is assmued | 1554 // save_stack,clear_ptr_cache is assmued |
1555 if (!is_longlong_reg(reg)) { error(-1); return; } | 1555 if (!is_longlong_reg(reg)) { error(-1); return; } |
1556 if (mode) { | 1556 if (mode) { |
1557 if (regv_l(reg)!=3) | |
1558 printf("\tmr r3,%s\n", lregister_name_high(reg)); | |
1559 if (regv_l(reg)!=4) | |
1560 printf("\tmr r4,%s\n", lregister_name_low(reg)); | |
1561 } | |
1562 } | |
1563 | |
1564 void | |
1565 set_lreg_operand1(int reg,int mode) | |
1566 { | |
1567 // save_stack,clear_ptr_cache is assmued | |
1568 if (!is_longlong_reg(reg)) { error(-1); return; } | |
1569 if (mode) { | |
1557 if (regv_l(reg)!=5) | 1570 if (regv_l(reg)!=5) |
1558 printf("\tmr r5,%s\n", lregister_name_high(reg)); | 1571 printf("\tmr r5,%s\n", lregister_name_high(reg)); |
1559 if (regv_l(reg)!=6) | 1572 if (regv_l(reg)!=6) |
1560 printf("\tmr r6,%s\n", lregister_name_low(reg)); | 1573 printf("\tmr r6,%s\n", lregister_name_low(reg)); |
1561 } | 1574 } |
1628 } | 1641 } |
1629 | 1642 |
1630 static int | 1643 static int |
1631 not_simple_p(int e3) | 1644 not_simple_p(int e3) |
1632 { | 1645 { |
1633 return (e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| | 1646 return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| |
1634 (((e3/100)==LOP)&&(e3!=LREGISTER||e3!=LADD||e3!=LSUB))); | 1647 e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| |
1648 e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD; | |
1635 } | 1649 } |
1636 | 1650 |
1637 int | 1651 int |
1638 simple_args(int e3) | 1652 simple_args(int e3) |
1639 { | 1653 { |
1762 arg,INT,INT), | 1776 arg,INT,INT), |
1763 arg_assign); | 1777 arg_assign); |
1764 use_input_reg(cadr(r0),1); | 1778 use_input_reg(cadr(r0),1); |
1765 } else if (!simple_args(e3) && cadr(e3)) { | 1779 } else if (!simple_args(e3) && cadr(e3)) { |
1766 arg = get_lregister_var(0); | 1780 arg = get_lregister_var(0); |
1767 arg_assign = list2( | 1781 if (car(arg)==LREGISTER) { |
1768 assign_expr0(r0=get_input_lregister_var(reg_arg,0,0), | 1782 // r0=get_input_lregiste... is not preserved |
1769 arg,t,t), | 1783 // we cannot mark r0 used, it consumes unused register |
1770 arg_assign); | 1784 // but get_input_register is preserved. |
1771 use_input_reg(cadr(r0),1); | 1785 arg_assign = list2( |
1786 assign_expr0(get_input_register_var(reg_arg,0,0), | |
1787 list2(REGISTER,regv_h(cadr(arg))),INT,INT), | |
1788 list2( | |
1789 assign_expr0(get_input_register_var(reg_arg+1,0,0), | |
1790 list2(REGISTER,regv_l(cadr(arg))),INT,INT), | |
1791 arg_assign)); | |
1792 } else { | |
1793 arg_assign = list2( | |
1794 assign_expr0(get_input_register_var(reg_arg,0,0), | |
1795 list2(LVAR,cadr(arg)+SIZE_OF_INT),INT,INT), | |
1796 list2( | |
1797 assign_expr0(get_input_register_var(reg_arg+1,0,0), | |
1798 list2(LVAR,cadr(arg)),INT,INT), | |
1799 arg_assign)); | |
1800 } | |
1772 } else { | 1801 } else { |
1773 arg = get_input_lregister_var(reg_arg,0,0); | 1802 arg = get_input_lregister_var(reg_arg,0,0); |
1774 use_input_reg(cadr(arg),1); | 1803 use_input_reg(cadr(arg),1); |
1775 } | 1804 } |
1776 reg_arg_list = list2(arg,reg_arg_list); | 1805 reg_arg_list = list2(arg,reg_arg_list); |
3722 #endif | 3751 #endif |
3723 | 3752 |
3724 #endif | 3753 #endif |
3725 | 3754 |
3726 static void | 3755 static void |
3727 code_asld_lib(int oreg) | 3756 code_asld_lib(int reg,int oreg) |
3728 { | 3757 { |
3729 code_save_stacks(); | 3758 code_save_stacks(); |
3730 clear_ptr_cache(); | 3759 clear_ptr_cache(); |
3731 asld_lib_used = 1; | 3760 asld_lib_used = 1; |
3732 set_lreg(RET_LREGISTER,1); | 3761 set_lreg_operand(reg,1); |
3762 set_lreg(RET_LREGISTER,0); | |
3733 if (regv_l(oreg)!=5) { | 3763 if (regv_l(oreg)!=5) { |
3734 printf("\tmr r5,%s\n", lregister_name_low(oreg)); | 3764 printf("\tmr r5,%s\n", lregister_name_low(oreg)); |
3735 } | 3765 } |
3736 printf("\tbl asld__\n"); | 3766 printf("\tbl asld__\n"); |
3737 } | 3767 } |
3738 | 3768 |
3739 static void | 3769 static void |
3740 code_asrd_lib(int oreg) // ___ashrdi3$stub | 3770 code_asrd_lib(int reg,int oreg) // ___ashrdi3$stub |
3741 { | 3771 { |
3742 code_save_stacks(); | 3772 code_save_stacks(); |
3743 clear_ptr_cache(); | 3773 clear_ptr_cache(); |
3744 asrd_lib_used = 1; | 3774 asrd_lib_used = 1; |
3745 set_lreg(RET_LREGISTER,1); | 3775 set_lreg_operand(reg,1); |
3776 set_lreg(RET_LREGISTER,0); | |
3746 if (regv_l(oreg)!=5) { | 3777 if (regv_l(oreg)!=5) { |
3747 printf("\tmr r5,%s\n", lregister_name_low(oreg)); | 3778 printf("\tmr r5,%s\n", lregister_name_low(oreg)); |
3748 } | 3779 } |
3749 printf("\tbl asrd__\n"); | 3780 printf("\tbl asrd__\n"); |
3750 } | 3781 } |
3751 | 3782 |
3752 static void | 3783 static void |
3753 code_lsrd_lib(int oreg) // ___lshrdi3$stub | 3784 code_lsrd_lib(int reg,int oreg) // ___lshrdi3$stub |
3754 { | 3785 { |
3755 code_save_stacks(); | 3786 code_save_stacks(); |
3756 clear_ptr_cache(); | 3787 clear_ptr_cache(); |
3757 lsrd_lib_used = 1; | 3788 lsrd_lib_used = 1; |
3758 set_lreg(RET_LREGISTER,1); | 3789 set_lreg_operand(reg,1); |
3790 set_lreg(RET_LREGISTER,0); | |
3759 if (regv_l(oreg)!=5) { | 3791 if (regv_l(oreg)!=5) { |
3760 printf("\tmr r5,%s\n", lregister_name_low(oreg)); | 3792 printf("\tmr r5,%s\n", lregister_name_low(oreg)); |
3761 } | 3793 } |
3762 printf("\tbl lsrd__\n"); | 3794 printf("\tbl lsrd__\n"); |
3763 } | 3795 } |
3764 | 3796 |
3765 static void | 3797 static void |
3766 code_ldiv_lib(int oreg) // ___divdi3$stub | 3798 code_ldiv_lib(int reg,int oreg) // ___divdi3$stub |
3767 { | 3799 { |
3768 code_save_stacks(); | 3800 code_save_stacks(); |
3769 clear_ptr_cache(); | 3801 clear_ptr_cache(); |
3770 set_lreg(RET_LREGISTER,1); | 3802 set_lreg_operand(reg,1); |
3771 set_lreg_operand(oreg,1); | 3803 set_lreg(RET_LREGISTER,0); |
3804 set_lreg_operand1(oreg,1); | |
3772 extern_conv("__divdi3"); | 3805 extern_conv("__divdi3"); |
3773 } | 3806 } |
3774 | 3807 |
3775 static void | 3808 static void |
3776 code_ludiv_lib(int oreg) // ___udivdi3$stub | 3809 code_ludiv_lib(int reg,int oreg) // ___udivdi3$stub |
3777 { | 3810 { |
3778 code_save_stacks(); | 3811 code_save_stacks(); |
3779 clear_ptr_cache(); | 3812 clear_ptr_cache(); |
3780 set_lreg(RET_LREGISTER,1); | 3813 set_lreg_operand(reg,1); |
3781 set_lreg_operand(oreg,1); | 3814 set_lreg(RET_LREGISTER,0); |
3815 set_lreg_operand1(oreg,1); | |
3782 extern_conv("__udivdi3"); | 3816 extern_conv("__udivdi3"); |
3783 } | 3817 } |
3784 | 3818 |
3785 static void | 3819 static void |
3786 code_lmod_lib(int oreg) // ___moddi3$stub | 3820 code_lmod_lib(int reg,int oreg) // ___moddi3$stub |
3787 { | 3821 { |
3788 code_save_stacks(); | 3822 code_save_stacks(); |
3789 clear_ptr_cache(); | 3823 clear_ptr_cache(); |
3790 set_lreg(RET_LREGISTER,1); | 3824 set_lreg_operand(reg,1); |
3791 set_lreg_operand(oreg,1); | 3825 set_lreg(RET_LREGISTER,0); |
3826 set_lreg_operand1(oreg,1); | |
3792 extern_conv("__moddi3"); | 3827 extern_conv("__moddi3"); |
3793 } | 3828 } |
3794 | 3829 |
3795 static void | 3830 static void |
3796 code_lumod_lib(int oreg) // ___umoddi3$stub | 3831 code_lumod_lib(int reg,int oreg) // ___umoddi3$stub |
3797 { | 3832 { |
3798 code_save_stacks(); | 3833 code_save_stacks(); |
3799 clear_ptr_cache(); | 3834 clear_ptr_cache(); |
3800 set_lreg(RET_LREGISTER,1); | 3835 set_lreg(RET_LREGISTER,0); |
3801 set_lreg_operand(oreg,1); | 3836 set_lreg_operand(reg,1); |
3837 set_lreg_operand1(oreg,1); | |
3802 extern_conv("__umoddi3"); | 3838 extern_conv("__umoddi3"); |
3803 } | 3839 } |
3804 | 3840 |
3805 #define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); } | 3841 #define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); } |
3806 | 3842 |
3824 } | 3860 } |
3825 | 3861 |
3826 switch(op) { | 3862 switch(op) { |
3827 case LLSHIFT: | 3863 case LLSHIFT: |
3828 case LULSHIFT: | 3864 case LULSHIFT: |
3829 code_asld_lib(oreg); // ___ashldi3$stub | 3865 code_asld_lib(reg,oreg); // ___ashldi3$stub |
3830 check_lreg(reg); | 3866 check_lreg(reg); |
3831 if(ox!=-1) free_register(ox); | 3867 if(ox!=-1) free_register(ox); |
3832 return; | 3868 return; |
3833 case LRSHIFT: | 3869 case LRSHIFT: |
3834 code_asrd_lib(oreg); // ___ashrdi3$stub | 3870 code_asrd_lib(reg,oreg); // ___ashrdi3$stub |
3835 check_lreg(reg); | 3871 check_lreg(reg); |
3836 if(ox!=-1) free_register(ox); | 3872 if(ox!=-1) free_register(ox); |
3837 return; | 3873 return; |
3838 case LURSHIFT: | 3874 case LURSHIFT: |
3839 code_lsrd_lib(oreg); // ___lshrdi3$stub | 3875 code_lsrd_lib(reg,oreg); // ___lshrdi3$stub |
3840 check_lreg(reg); | 3876 check_lreg(reg); |
3841 if(ox!=-1) free_register(ox); | 3877 if(ox!=-1) free_register(ox); |
3842 return; | 3878 return; |
3843 } | 3879 } |
3844 orn_h = lregister_name_high(oreg); | 3880 orn_h = lregister_name_high(oreg); |
3893 printf("\tmullw %s,%s,%s\n", crn_l,orn_h,crn_l); | 3929 printf("\tmullw %s,%s,%s\n", crn_l,orn_h,crn_l); |
3894 printf("\tadd %s,%s,%s\n", crn_h,drn_h,crn_l); | 3930 printf("\tadd %s,%s,%s\n", crn_h,drn_h,crn_l); |
3895 printf("\tmr %s,%s\n", crn_l,drn_l); | 3931 printf("\tmr %s,%s\n", crn_l,drn_l); |
3896 break; | 3932 break; |
3897 case LDIV: | 3933 case LDIV: |
3898 code_ldiv_lib(oreg); // ___divdi3$stub | 3934 code_ldiv_lib(reg,oreg); // ___divdi3$stub |
3899 check_lreg(reg); | 3935 check_lreg(reg); |
3900 break; | 3936 break; |
3901 case LUDIV: | 3937 case LUDIV: |
3902 code_ludiv_lib(oreg); // ___udivdi3$stub | 3938 code_ludiv_lib(reg,oreg); // ___udivdi3$stub |
3903 check_lreg(reg); | 3939 check_lreg(reg); |
3904 break; | 3940 break; |
3905 case LMOD: | 3941 case LMOD: |
3906 code_lmod_lib(oreg); // ___moddi3$stub | 3942 code_lmod_lib(reg,oreg); // ___moddi3$stub |
3907 check_lreg(reg); | 3943 check_lreg(reg); |
3908 break; | 3944 break; |
3909 case LUMOD: | 3945 case LUMOD: |
3910 code_lumod_lib(oreg); // ___umoddi3$stub | 3946 code_lumod_lib(reg,oreg); // ___umoddi3$stub |
3911 check_lreg(reg); | 3947 check_lreg(reg); |
3912 break; | 3948 break; |
3913 default: | 3949 default: |
3914 error(-1); | 3950 error(-1); |
3915 } | 3951 } |