OLD | NEW |
---|---|
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 1830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1841 // Ddst = MEM(Rbase + offset). | 1841 // Ddst = MEM(Rbase + offset). |
1842 // Instruction details available in ARM DDI 0406A, A8-628. | 1842 // Instruction details available in ARM DDI 0406A, A8-628. |
1843 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1843 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
1844 // Vdst(15-12) | 1011(11-8) | offset | 1844 // Vdst(15-12) | 1011(11-8) | offset |
1845 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1845 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
1846 int u = 1; | 1846 int u = 1; |
1847 if (offset < 0) { | 1847 if (offset < 0) { |
1848 offset = -offset; | 1848 offset = -offset; |
1849 u = 0; | 1849 u = 0; |
1850 } | 1850 } |
1851 ASSERT(offset % 4 == 0); | 1851 |
1852 ASSERT((offset / 4) < 256); | |
1853 ASSERT(offset >= 0); | 1852 ASSERT(offset >= 0); |
1854 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | | 1853 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1855 0xB*B8 | ((offset / 4) & 255)); | 1854 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | |
1855 0xB*B8 | ((offset / 4) & 255)); | |
1856 } else { | |
1857 // Larger offsets must be handled by computing the correct address | |
1858 // in the ip register. | |
1859 ASSERT(!base.is(ip)); | |
1860 mov(ip, Operand(offset)); | |
Rodolph Perfetta
2011/02/16 16:48:54
The offset may be encodable in an add/sub immediat
William Hesse
2011/02/17 11:27:29
Done.
| |
1861 if (u == 1) { | |
1862 add(ip, base, ip); | |
1863 } else { | |
1864 sub(ip, base, ip); | |
1865 } | |
1866 emit(cond | 0xD1*B20 | ip.code()*B16 | dst.code()*B12 | 0xB*B8); | |
1867 } | |
1868 } | |
1869 | |
1870 | |
1871 void Assembler::vldr(const DwVfpRegister dst, | |
1872 const MemOperand& operand, | |
1873 const Condition cond) { | |
1874 ASSERT(!operand.rm().is_valid()); | |
1875 ASSERT(operand.am_ == Offset); | |
1876 vldr(dst, operand.rn(), operand.offset(), cond); | |
1856 } | 1877 } |
1857 | 1878 |
1858 | 1879 |
1859 void Assembler::vldr(const SwVfpRegister dst, | 1880 void Assembler::vldr(const SwVfpRegister dst, |
1860 const Register base, | 1881 const Register base, |
1861 int offset, | 1882 int offset, |
1862 const Condition cond) { | 1883 const Condition cond) { |
1863 // Sdst = MEM(Rbase + offset). | 1884 // Sdst = MEM(Rbase + offset). |
1864 // Instruction details available in ARM DDI 0406A, A8-628. | 1885 // Instruction details available in ARM DDI 0406A, A8-628. |
1865 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1886 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
1866 // Vdst(15-12) | 1010(11-8) | offset | 1887 // Vdst(15-12) | 1010(11-8) | offset |
1867 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1888 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
1868 int u = 1; | 1889 int u = 1; |
1869 if (offset < 0) { | 1890 if (offset < 0) { |
1870 offset = -offset; | 1891 offset = -offset; |
1871 u = 0; | 1892 u = 0; |
1872 } | 1893 } |
1873 ASSERT(offset % 4 == 0); | |
1874 ASSERT((offset / 4) < 256); | |
1875 ASSERT(offset >= 0); | |
1876 int sd, d; | 1894 int sd, d; |
1877 dst.split_code(&sd, &d); | 1895 dst.split_code(&sd, &d); |
1896 ASSERT(offset >= 0); | |
1897 | |
1898 if ((offset % 4) == 0 && (offset / 4) < 256) { | |
1878 emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 | | 1899 emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 | |
1879 0xA*B8 | ((offset / 4) & 255)); | 1900 0xA*B8 | ((offset / 4) & 255)); |
1901 } else { | |
1902 // Larger offsets must be handled by computing the correct address | |
1903 // in the ip register. | |
1904 ASSERT(!base.is(ip)); | |
1905 mov(ip, Operand(offset)); | |
Rodolph Perfetta
2011/02/16 16:48:54
ditto.
| |
1906 if (u == 1) { | |
1907 add(ip, ip, base); | |
1908 } else { | |
1909 sub(ip, base, ip); | |
1910 } | |
1911 emit(cond | d*B22 | 0xD1*B20 | ip.code()*B16 | sd*B12 | 0xA*B8); | |
1912 } | |
1913 } | |
1914 | |
1915 | |
1916 void Assembler::vldr(const SwVfpRegister dst, | |
1917 const MemOperand& operand, | |
1918 const Condition cond) { | |
1919 ASSERT(!operand.rm().is_valid()); | |
1920 ASSERT(operand.am_ == Offset); | |
1921 vldr(dst, operand.rn(), operand.offset(), cond); | |
1880 } | 1922 } |
1881 | 1923 |
1882 | 1924 |
1883 void Assembler::vstr(const DwVfpRegister src, | 1925 void Assembler::vstr(const DwVfpRegister src, |
1884 const Register base, | 1926 const Register base, |
1885 int offset, | 1927 int offset, |
1886 const Condition cond) { | 1928 const Condition cond) { |
1887 // MEM(Rbase + offset) = Dsrc. | 1929 // MEM(Rbase + offset) = Dsrc. |
1888 // Instruction details available in ARM DDI 0406A, A8-786. | 1930 // Instruction details available in ARM DDI 0406A, A8-786. |
1889 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | | 1931 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | |
1890 // Vsrc(15-12) | 1011(11-8) | (offset/4) | 1932 // Vsrc(15-12) | 1011(11-8) | (offset/4) |
1891 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1933 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
1892 int u = 1; | 1934 int u = 1; |
1893 if (offset < 0) { | 1935 if (offset < 0) { |
1894 offset = -offset; | 1936 offset = -offset; |
1895 u = 0; | 1937 u = 0; |
1896 } | 1938 } |
1897 ASSERT(offset % 4 == 0); | |
1898 ASSERT((offset / 4) < 256); | |
1899 ASSERT(offset >= 0); | 1939 ASSERT(offset >= 0); |
1900 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | | 1940 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1901 0xB*B8 | ((offset / 4) & 255)); | 1941 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | |
1942 0xB*B8 | ((offset / 4) & 255)); | |
1943 } else { | |
1944 // Larger offsets must be handled by computing the correct address | |
1945 // in the ip register. | |
1946 ASSERT(!base.is(ip)); | |
1947 mov(ip, Operand(offset)); | |
Rodolph Perfetta
2011/02/16 16:48:54
ditto.
| |
1948 if (u == 1) { | |
1949 add(ip, ip, base); | |
1950 } else { | |
1951 sub(ip, base, ip); | |
1952 } | |
1953 emit(cond | 0xD0*B20 | ip.code()*B16 | src.code()*B12 | 0xB*B8); | |
1954 } | |
1955 } | |
1956 | |
1957 | |
1958 void Assembler::vstr(const DwVfpRegister src, | |
1959 const MemOperand& operand, | |
1960 const Condition cond) { | |
1961 ASSERT(!operand.rm().is_valid()); | |
1962 ASSERT(operand.am_ == Offset); | |
1963 vldr(src, operand.rn(), operand.offset(), cond); | |
1902 } | 1964 } |
1903 | 1965 |
1904 | 1966 |
1905 void Assembler::vstr(const SwVfpRegister src, | 1967 void Assembler::vstr(const SwVfpRegister src, |
1906 const Register base, | 1968 const Register base, |
1907 int offset, | 1969 int offset, |
1908 const Condition cond) { | 1970 const Condition cond) { |
1909 // MEM(Rbase + offset) = SSrc. | 1971 // MEM(Rbase + offset) = SSrc. |
1910 // Instruction details available in ARM DDI 0406A, A8-786. | 1972 // Instruction details available in ARM DDI 0406A, A8-786. |
1911 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | | 1973 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | |
1912 // Vdst(15-12) | 1010(11-8) | (offset/4) | 1974 // Vdst(15-12) | 1010(11-8) | (offset/4) |
1913 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1975 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
1914 int u = 1; | 1976 int u = 1; |
1915 if (offset < 0) { | 1977 if (offset < 0) { |
1916 offset = -offset; | 1978 offset = -offset; |
1917 u = 0; | 1979 u = 0; |
1918 } | 1980 } |
1919 ASSERT(offset % 4 == 0); | |
1920 ASSERT((offset / 4) < 256); | |
1921 ASSERT(offset >= 0); | |
1922 int sd, d; | 1981 int sd, d; |
1923 src.split_code(&sd, &d); | 1982 src.split_code(&sd, &d); |
1924 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | | 1983 ASSERT(offset >= 0); |
1925 0xA*B8 | ((offset / 4) & 255)); | 1984 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1985 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | | |
1986 0xA*B8 | ((offset / 4) & 255)); | |
1987 } else { | |
1988 // Larger offsets must be handled by computing the correct address | |
1989 // in the ip register. | |
1990 ASSERT(!base.is(ip)); | |
1991 mov(ip, Operand(offset)); | |
Rodolph Perfetta
2011/02/16 16:48:54
ditto.
| |
1992 if (u == 1) { | |
1993 add(ip, ip, base); | |
1994 } else { | |
1995 sub(ip, base, ip); | |
1996 } | |
1997 emit(cond | d*B22 | 0xD0*B20 | ip.code()*B16 | sd*B12 | 0xA*B8); | |
1998 } | |
1999 } | |
2000 | |
2001 | |
2002 void Assembler::vstr(const SwVfpRegister src, | |
2003 const MemOperand& operand, | |
2004 const Condition cond) { | |
2005 ASSERT(!operand.rm().is_valid()); | |
2006 ASSERT(operand.am_ == Offset); | |
2007 vldr(src, operand.rn(), operand.offset(), cond); | |
1926 } | 2008 } |
1927 | 2009 |
1928 | 2010 |
1929 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { | 2011 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
1930 uint64_t i; | 2012 uint64_t i; |
1931 memcpy(&i, &d, 8); | 2013 memcpy(&i, &d, 8); |
1932 | 2014 |
1933 *lo = i & 0xffffffff; | 2015 *lo = i & 0xffffffff; |
1934 *hi = i >> 32; | 2016 *hi = i >> 32; |
1935 } | 2017 } |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2669 | 2751 |
2670 // Since a constant pool was just emitted, move the check offset forward by | 2752 // Since a constant pool was just emitted, move the check offset forward by |
2671 // the standard interval. | 2753 // the standard interval. |
2672 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 2754 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
2673 } | 2755 } |
2674 | 2756 |
2675 | 2757 |
2676 } } // namespace v8::internal | 2758 } } // namespace v8::internal |
2677 | 2759 |
2678 #endif // V8_TARGET_ARCH_ARM | 2760 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |