Mercurial > hg > CbC > old > device
comparison mc-code-powerpc.c @ 257:e2f5671c413d
*** empty log message ***
author | kono |
---|---|
date | Sat, 15 May 2004 12:05:17 +0900 |
parents | d80e6387c539 |
children | 22949117768f |
comparison
equal
deleted
inserted
replaced
256:d80e6387c539 | 257:e2f5671c413d |
---|---|
124 "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", | 124 "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", |
125 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", | 125 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", |
126 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", | 126 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", |
127 "f30","f31" | 127 "f30","f31" |
128 }; | 128 }; |
129 | |
130 #define round4(i) ((i+3)&~3) | |
131 | 129 |
132 #define register_name(i) reg_name[i] | 130 #define register_name(i) reg_name[i] |
133 #define fregister_name(i) reg_name[i] | 131 #define fregister_name(i) reg_name[i] |
134 #define lregister_name_low(i) reg_name[regv_l(i)] | 132 #define lregister_name_low(i) reg_name[regv_l(i)] |
135 #define lregister_name_high(i) reg_name[regv_h(i)] | 133 #define lregister_name_high(i) reg_name[regv_h(i)] |
1648 return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| | 1646 return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| |
1649 e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| | 1647 e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| |
1650 e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD; | 1648 e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD; |
1651 } | 1649 } |
1652 | 1650 |
1653 static int | 1651 int |
1654 simple_arg(int e3) | 1652 simple_args(int e3) |
1655 { | 1653 { |
1656 return !contains_p(e3,not_simple_p); | 1654 return !contains_in_list_p(e3,not_simple_p); |
1657 } | 1655 } |
1658 | 1656 |
1659 int | 1657 int |
1660 caller_arg_offset_v(int arg) | 1658 caller_arg_offset_v(int arg) |
1661 { | 1659 { |
1697 } | 1695 } |
1698 } | 1696 } |
1699 if (mode) use_reg(reg); | 1697 if (mode) use_reg(reg); |
1700 } | 1698 } |
1701 | 1699 |
1702 static void | |
1703 compute_complex_arg(int e3,int reg_arg_list,int arg,int stack) { | |
1704 int t=caddr(e3); | |
1705 int e4 = car(e3); | |
1706 reg_arg_list = list2(arg,reg_arg_list); | |
1707 g_expr_u(assign_expr0(arg,e4,t,t)); | |
1708 if (stack) { | |
1709 car(e3) = 0; | |
1710 } else { | |
1711 if (car(arg)==REGISTER||car(arg)==DREGISTER|| | |
1712 car(arg)==FREGISTER||car(arg)==LREGISTER) | |
1713 use_input_reg(cadr(arg),1); | |
1714 car(e3) = arg; | |
1715 } | |
1716 } | |
1717 | |
1718 static void | |
1719 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { | |
1720 int nargs=0,reg_arg=0,freg_arg=0; | |
1721 int t=caddr(e3); | |
1722 if(scalar(t)) { | |
1723 nargs ++ ; reg_arg++; | |
1724 } else if (t==LONGLONG||t==ULONGLONG) { | |
1725 nargs ++ ; reg_arg++; | |
1726 nargs ++ ; reg_arg++; | |
1727 } else if (t==DOUBLE||t==FLOAT) { | |
1728 if (*preg_arg<MAX_INPUT_REGISTER_VAR) { | |
1729 reg_arg += 2; | |
1730 } | |
1731 freg_arg++; | |
1732 nargs += size(t)/SIZE_OF_INT; | |
1733 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | |
1734 nargs += round4(size(t)); | |
1735 } else { | |
1736 error(TYERR); | |
1737 } | |
1738 ++nargs; | |
1739 *pnargs += nargs; | |
1740 *preg_arg += reg_arg; | |
1741 *pfreg_arg += freg_arg; | |
1742 } | |
1743 | |
1744 static int | |
1745 get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg,int *stack) | |
1746 { | |
1747 *stack = 0; | |
1748 if(scalar(t)) { | |
1749 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | |
1750 *stack = 1; | |
1751 return list2(LVAR,caller_arg_offset_v(nargs)); | |
1752 } | |
1753 return mode?get_register_var(0):get_input_register_var(reg_arg,0,0); | |
1754 } else if (t==LONGLONG||t==ULONGLONG) { | |
1755 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | |
1756 *stack = 1; | |
1757 return list2(LVAR,caller_arg_offset_v(nargs)); | |
1758 } | |
1759 return mode?get_lregister_var(0):get_input_lregister_var(reg_arg,0,0); | |
1760 } else if (t==FLOAT) { | |
1761 if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { | |
1762 *stack = 1; | |
1763 return list2(LVAR,caller_arg_offset_v(nargs)); | |
1764 } | |
1765 return mode?get_dregister_var(0,0): | |
1766 get_input_dregister_var(freg_arg,0,0,0); | |
1767 } else if (t==DOUBLE) { | |
1768 if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { | |
1769 *stack = 1; | |
1770 return list2(LVAR,caller_arg_offset_v(nargs)); | |
1771 } | |
1772 return mode?get_dregister_var(0,1): | |
1773 get_input_dregister_var(freg_arg,0,0,1); | |
1774 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | |
1775 *stack = 1; | |
1776 return list2(LVAR,caller_arg_offset_v(nargs)); | |
1777 } else { | |
1778 error(-1); | |
1779 *stack = 1; | |
1780 return list2(LVAR,caller_arg_offset_v(nargs)); | |
1781 } | |
1782 } | |
1783 | |
1784 int | 1700 int |
1785 function(int e1) | 1701 function(int e1) |
1786 { | 1702 { |
1787 int e2,e3,e4,e5,nargs,t,r0,r1; | 1703 int e2,e3,e4,e5,nargs,t,r0,r1; |
1788 int arg,reg_arg,freg_arg,arg_assign; | 1704 int arg,reg_arg,freg_arg,arg_assign; |
1789 int dots; | 1705 int dots; |
1790 int reg_arg_list=0,ret_type,special_lvar; | 1706 int reg_arg_list=0,ret_type,special_lvar; |
1791 NMTBL *fn = 0; | 1707 NMTBL *fn = 0; |
1792 int jmp = 0; | 1708 int jmp = 0; |
1793 char *jrn; | 1709 char *jrn; |
1794 int complex; | |
1795 int pnargs,preg_arg,pfreg_arg; | |
1796 int stack; | |
1797 | 1710 |
1798 special_lvar = -1; | 1711 special_lvar = -1; |
1799 ret_type = cadr(cadddr(e1)); | 1712 ret_type = cadr(cadddr(e1)); |
1800 if (ret_type==CHAR) ret_type=INT; | 1713 if (ret_type==CHAR) ret_type=INT; |
1801 | 1714 |
1819 g_expr(e2); | 1732 g_expr(e2); |
1820 if (!is_int_reg(creg)) error(-1); | 1733 if (!is_int_reg(creg)) error(-1); |
1821 code_register(creg,cadr(jmp)); | 1734 code_register(creg,cadr(jmp)); |
1822 /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */ | 1735 /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */ |
1823 } | 1736 } |
1824 /* first we execute complex argument to avoid interaction with | |
1825 input variables */ | |
1826 complex = 0; | |
1827 nargs = reg_arg = freg_arg = arg_assign = 0; | |
1828 for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { | |
1829 t=caddr(e3); | |
1830 if (complex) { | |
1831 arg = get_input_arg(t,1,pnargs,preg_arg,pfreg_arg,&stack); | |
1832 compute_complex_arg(complex,reg_arg_list,arg,stack); | |
1833 } | |
1834 if (simple_arg(car(complex=e3))) complex=0; | |
1835 pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; | |
1836 increment_function_arg(e3,&nargs,®_arg,&freg_arg); | |
1837 } | |
1838 | 1737 |
1839 /* now all input register vars are free */ | 1738 /* now all input register vars are free */ |
1840 code_save_stacks(); | 1739 code_save_stacks(); |
1841 // set_lreg(LREG_LREGISTER,0); | 1740 // set_lreg(LREG_LREGISTER,0); |
1842 set_freg(FREG_FREGISTER,0); | 1741 set_freg(FREG_FREGISTER,0); |
1843 set_ireg(CREG_REGISTER,0); | 1742 set_ireg(CREG_REGISTER,0); |
1844 | 1743 |
1845 if (complex) { | |
1846 arg = get_input_arg(caddr(complex),0,pnargs,preg_arg,pfreg_arg,&stack); | |
1847 compute_complex_arg(complex,reg_arg_list,arg,stack); | |
1848 } | |
1849 | |
1850 nargs = reg_arg = freg_arg = arg_assign = 0; | 1744 nargs = reg_arg = freg_arg = arg_assign = 0; |
1851 for (e3 = reverse0(caddr(e1)); e3; | 1745 for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { |
1852 increment_function_arg(e3,&nargs,®_arg,&freg_arg), | |
1853 e3 = cadr(e3)) { | |
1854 if (!(e4=car(e3))) continue; | |
1855 t=caddr(e3); | 1746 t=caddr(e3); |
1856 arg = get_input_arg(t,0,nargs,reg_arg,freg_arg,&stack); | 1747 e4 = car(e3); |
1857 if(scalar(t)) { | 1748 if(scalar(t)) { |
1749 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | |
1750 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1751 } else if (!simple_args(e3) && cadr(e3)) { | |
1752 arg = get_register_var(0); | |
1753 arg_assign = list2( | |
1754 assign_expr0(get_input_register_var(reg_arg,0,0), | |
1755 arg,t,t), | |
1756 arg_assign); | |
1757 } else { | |
1758 arg = get_input_register_var(reg_arg,0,0); | |
1759 } | |
1858 reg_arg_list = list2(arg,reg_arg_list); | 1760 reg_arg_list = list2(arg,reg_arg_list); |
1859 /* protect from input register free */ | 1761 /* protect from input register free */ |
1860 if (car(arg)==REGISTER) | 1762 if (car(arg)==REGISTER) |
1861 use_input_reg(cadr(arg),1); | 1763 use_input_reg(cadr(arg),1); |
1862 g_expr_u(assign_expr0(arg,e4,t,t)); | 1764 g_expr_u(assign_expr0(arg,e4,t,t)); |
1765 nargs ++ ; reg_arg++; | |
1863 continue; | 1766 continue; |
1864 } else if (t==LONGLONG||t==ULONGLONG) { | 1767 } else if (t==LONGLONG||t==ULONGLONG) { |
1865 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | 1768 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { |
1769 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1866 } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { | 1770 } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { |
1867 // half register, half memory case | 1771 // half register, half memory case |
1868 // put whole long long anyway | 1772 // put whole long long anyway |
1773 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1869 arg_assign = list2( | 1774 arg_assign = list2( |
1870 assign_expr0(r0=get_input_register_var(reg_arg,0,0), | 1775 assign_expr0(r0=get_input_register_var(reg_arg,0,0), |
1871 arg,INT,INT), | 1776 arg,INT,INT), |
1872 arg_assign); | 1777 arg_assign); |
1873 use_input_reg(cadr(r0),1); | 1778 use_input_reg(cadr(r0),1); |
1779 } else if (!simple_args(e3) && cadr(e3)) { | |
1780 arg = get_lregister_var(0); | |
1781 if (car(arg)==LREGISTER) { | |
1782 // r0=get_input_lregiste... is not preserved | |
1783 // we cannot mark r0 used, it consumes unused register | |
1784 // but get_input_register is preserved. | |
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 } | |
1874 } else { | 1801 } else { |
1875 if (car(arg)==LREGISTER) | 1802 arg = get_input_lregister_var(reg_arg,0,0); |
1876 use_input_reg(cadr(arg),1); | 1803 use_input_reg(cadr(arg),1); |
1877 } | 1804 } |
1878 reg_arg_list = list2(arg,reg_arg_list); | 1805 reg_arg_list = list2(arg,reg_arg_list); |
1879 g_expr_u(assign_expr0(arg,e4,t,t)); | 1806 g_expr_u(assign_expr0(arg,e4,t,t)); |
1807 nargs ++ ; reg_arg++; | |
1808 nargs ++ ; reg_arg++; | |
1880 continue; | 1809 continue; |
1881 } else if (t==DOUBLE||t==FLOAT) { | 1810 } else if (t==DOUBLE||t==FLOAT) { |
1882 if (reg_arg<MAX_INPUT_REGISTER_VAR) { | 1811 if (reg_arg<MAX_INPUT_REGISTER_VAR) { |
1883 /* sigh... | 1812 /* sigh... |
1884 printf requies floating value in integer registers | 1813 printf requies floating value in integer registers |
1908 arg_assign = list2( assign_expr0(r0,e5,INT,INT), arg_assign); | 1837 arg_assign = list2( assign_expr0(r0,e5,INT,INT), arg_assign); |
1909 arg_assign = list2( assign_expr0(r1, | 1838 arg_assign = list2( assign_expr0(r1, |
1910 list2(LVAR,special_lvar+SIZE_OF_INT), | 1839 list2(LVAR,special_lvar+SIZE_OF_INT), |
1911 INT,INT), arg_assign); | 1840 INT,INT), arg_assign); |
1912 } | 1841 } |
1842 reg_arg += 2; | |
1913 } | 1843 } |
1914 if (dots && freg_arg>=4 && freg_arg<MAX_INPUT_DREGISTER_VAR) { | 1844 if (dots && freg_arg>=4 && freg_arg<MAX_INPUT_DREGISTER_VAR) { |
1915 /* oh my god! | 1845 /* oh my god! |
1916 it requies integer register and floating register and | 1846 it requies integer register and floating register and |
1917 stack value. You are crazy. | 1847 stack value. You are crazy. |
1919 arg_assign = list2( | 1849 arg_assign = list2( |
1920 assign_expr0(list2(LVAR,caller_arg_offset_v(nargs)), | 1850 assign_expr0(list2(LVAR,caller_arg_offset_v(nargs)), |
1921 get_input_dregister_var(freg_arg,0,0,1),t,t), | 1851 get_input_dregister_var(freg_arg,0,0,1),t,t), |
1922 arg_assign); | 1852 arg_assign); |
1923 } | 1853 } |
1854 if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { | |
1855 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1856 } else if (!simple_args(e3) && cadr(e3)) { | |
1857 arg = get_dregister_var(0,1); | |
1858 arg_assign = list2( | |
1859 assign_expr0(get_input_dregister_var(freg_arg,0,0,1), | |
1860 arg,t,t), | |
1861 arg_assign); | |
1862 } else { | |
1863 arg = get_input_dregister_var(freg_arg,0,0,1); | |
1864 } | |
1924 reg_arg_list = list2(arg,reg_arg_list); | 1865 reg_arg_list = list2(arg,reg_arg_list); |
1925 if (car(arg)==DREGISTER) | 1866 if (car(arg)==DREGISTER) |
1926 use_input_reg(cadr(arg),1); /* protect from input register free */ | 1867 use_input_reg(cadr(arg),1); /* protect from input register free */ |
1927 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ | 1868 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ |
1869 freg_arg++; | |
1870 nargs += size(t)/SIZE_OF_INT; | |
1928 continue; | 1871 continue; |
1929 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | 1872 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { |
1930 struct_push(e4,t,arg); | 1873 arg = list2(LVAR,caller_arg_offset_v(nargs)); |
1874 nargs += struct_push(e4,t,arg); | |
1931 continue; | 1875 continue; |
1932 } else { | 1876 } else { |
1933 error(TYERR); | 1877 error(TYERR); |
1934 } | 1878 } |
1879 ++nargs; | |
1935 } | 1880 } |
1936 if (max_func_args<nargs) max_func_args=nargs; | 1881 if (max_func_args<nargs) max_func_args=nargs; |
1937 for(;arg_assign;arg_assign=cadr(arg_assign)) { | 1882 for(;arg_assign;arg_assign=cadr(arg_assign)) { |
1938 g_expr_u(car(arg_assign)); | 1883 g_expr_u(car(arg_assign)); |
1939 } | 1884 } |