OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/os.h" | 10 #include "vm/os.h" |
(...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 } | 1810 } |
1811 | 1811 |
1812 | 1812 |
1813 ASSEMBLER_TEST_RUN(Vaddqi64, test) { | 1813 ASSEMBLER_TEST_RUN(Vaddqi64, test) { |
1814 EXPECT(test != NULL); | 1814 EXPECT(test != NULL); |
1815 typedef int (*Tst)(); | 1815 typedef int (*Tst)(); |
1816 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1816 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
1817 } | 1817 } |
1818 | 1818 |
1819 | 1819 |
| 1820 ASSEMBLER_TEST_GENERATE(Vshlqu64, assembler) { |
| 1821 if (TargetCPUFeatures::neon_supported()) { |
| 1822 Label fail; |
| 1823 __ LoadImmediate(R1, 21); |
| 1824 __ LoadImmediate(R0, 1); |
| 1825 __ vmovsr(S0, R1); |
| 1826 __ vmovsr(S2, R1); |
| 1827 __ vmovsr(S4, R0); |
| 1828 __ vmovsr(S6, R0); |
| 1829 |
| 1830 __ vshlqu(kWordPair, Q2, Q0, Q1); |
| 1831 |
| 1832 __ vmovrs(R0, S8); |
| 1833 __ vmovrs(R1, S10); |
| 1834 __ CompareImmediate(R0, 42); |
| 1835 __ LoadImmediate(R0, 0); |
| 1836 __ b(&fail, NE); |
| 1837 __ CompareImmediate(R1, 42); |
| 1838 __ LoadImmediate(R0, 0); |
| 1839 __ b(&fail, NE); |
| 1840 |
| 1841 __ LoadImmediate(R0, 1); |
| 1842 __ Bind(&fail); |
| 1843 __ bx(LR); |
| 1844 } else { |
| 1845 __ LoadImmediate(R0, 1); |
| 1846 __ bx(LR); |
| 1847 } |
| 1848 } |
| 1849 |
| 1850 |
| 1851 ASSEMBLER_TEST_RUN(Vshlqu64, test) { |
| 1852 EXPECT(test != NULL); |
| 1853 typedef int (*Tst)(); |
| 1854 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 1855 } |
| 1856 |
| 1857 |
| 1858 ASSEMBLER_TEST_GENERATE(Vshlqi64, assembler) { |
| 1859 if (TargetCPUFeatures::neon_supported()) { |
| 1860 Label fail; |
| 1861 __ LoadImmediate(R1, -84); |
| 1862 __ LoadImmediate(R0, -1); |
| 1863 __ vmovdrr(D0, R1, R0); |
| 1864 __ vmovdrr(D1, R1, R0); |
| 1865 __ vmovsr(S4, R0); |
| 1866 __ vmovsr(S6, R0); |
| 1867 |
| 1868 __ vshlqi(kWordPair, Q2, Q0, Q1); |
| 1869 |
| 1870 __ vmovrs(R0, S8); |
| 1871 __ vmovrs(R1, S10); |
| 1872 __ CompareImmediate(R0, -42); |
| 1873 __ LoadImmediate(R0, 0); |
| 1874 __ b(&fail, NE); |
| 1875 __ CompareImmediate(R1, -42); |
| 1876 __ LoadImmediate(R0, 0); |
| 1877 __ b(&fail, NE); |
| 1878 |
| 1879 __ LoadImmediate(R0, 1); |
| 1880 __ Bind(&fail); |
| 1881 __ bx(LR); |
| 1882 } else { |
| 1883 __ LoadImmediate(R0, 1); |
| 1884 __ bx(LR); |
| 1885 } |
| 1886 } |
| 1887 |
| 1888 |
| 1889 ASSEMBLER_TEST_RUN(Vshlqi64, test) { |
| 1890 EXPECT(test != NULL); |
| 1891 typedef int (*Tst)(); |
| 1892 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 1893 } |
| 1894 |
| 1895 |
| 1896 ASSEMBLER_TEST_GENERATE(Mint_shl_ok, assembler) { |
| 1897 const QRegister value = Q0; |
| 1898 const QRegister temp = Q1; |
| 1899 const QRegister out = Q2; |
| 1900 const Register shift = R1; |
| 1901 const DRegister dtemp0 = EvenDRegisterOf(temp); |
| 1902 const SRegister stemp0 = EvenSRegisterOf(dtemp0); |
| 1903 const DRegister dout0 = EvenDRegisterOf(out); |
| 1904 const SRegister sout0 = EvenSRegisterOf(dout0); |
| 1905 const SRegister sout1 = OddSRegisterOf(dout0); |
| 1906 Label fail; |
| 1907 |
| 1908 // Initialize. |
| 1909 __ veorq(value, value, value); |
| 1910 __ veorq(temp, temp, temp); |
| 1911 __ veorq(out, out, out); |
| 1912 __ LoadImmediate(shift, 32); |
| 1913 __ LoadImmediate(R2, 1 << 7); |
| 1914 __ vmovsr(S0, R2); |
| 1915 |
| 1916 __ vmovsr(stemp0, shift); // Move the shift into the low S register. |
| 1917 __ vshlqu(kWordPair, out, value, temp); |
| 1918 |
| 1919 // check for overflow by shifting back and comparing. |
| 1920 __ rsb(shift, shift, ShifterOperand(0)); |
| 1921 __ vmovsr(stemp0, shift); |
| 1922 __ vshlqi(kWordPair, temp, out, temp); |
| 1923 __ vceqqi(kWord, out, temp, value); |
| 1924 // Low 64 bits of temp should be all 1's, otherwise temp != value and |
| 1925 // we deopt. |
| 1926 __ vmovrs(shift, sout0); |
| 1927 __ CompareImmediate(shift, -1); |
| 1928 __ b(&fail, NE); |
| 1929 __ vmovrs(shift, sout1); |
| 1930 __ CompareImmediate(shift, -1); |
| 1931 __ b(&fail, NE); |
| 1932 |
| 1933 __ LoadImmediate(R0, 1); |
| 1934 __ bx(LR); |
| 1935 |
| 1936 __ Bind(&fail); |
| 1937 __ LoadImmediate(R0, 0); |
| 1938 __ bx(LR); |
| 1939 } |
| 1940 |
| 1941 |
| 1942 ASSEMBLER_TEST_RUN(Mint_shl_ok, test) { |
| 1943 EXPECT(test != NULL); |
| 1944 typedef int (*Tst)(); |
| 1945 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 1946 } |
| 1947 |
| 1948 |
| 1949 ASSEMBLER_TEST_GENERATE(Mint_shl_overflow, assembler) { |
| 1950 const QRegister value = Q0; |
| 1951 const QRegister temp = Q1; |
| 1952 const QRegister out = Q2; |
| 1953 const Register shift = R1; |
| 1954 const DRegister dtemp0 = EvenDRegisterOf(temp); |
| 1955 const SRegister stemp0 = EvenSRegisterOf(dtemp0); |
| 1956 const DRegister dout0 = EvenDRegisterOf(out); |
| 1957 const SRegister sout0 = EvenSRegisterOf(dout0); |
| 1958 const SRegister sout1 = OddSRegisterOf(dout0); |
| 1959 Label fail; |
| 1960 |
| 1961 // Initialize. |
| 1962 __ veorq(value, value, value); |
| 1963 __ veorq(temp, temp, temp); |
| 1964 __ veorq(out, out, out); |
| 1965 __ LoadImmediate(shift, 60); |
| 1966 __ LoadImmediate(R2, 1 << 7); |
| 1967 __ vmovsr(S0, R2); |
| 1968 |
| 1969 __ vmovsr(stemp0, shift); // Move the shift into the low S register. |
| 1970 __ vshlqu(kWordPair, out, value, temp); |
| 1971 |
| 1972 // check for overflow by shifting back and comparing. |
| 1973 __ rsb(shift, shift, ShifterOperand(0)); |
| 1974 __ vmovsr(stemp0, shift); |
| 1975 __ vshlqi(kWordPair, temp, out, temp); |
| 1976 __ vceqqi(kWord, out, temp, value); |
| 1977 // Low 64 bits of temp should be all 1's, otherwise temp != value and |
| 1978 // we deopt. |
| 1979 __ vmovrs(shift, sout0); |
| 1980 __ CompareImmediate(shift, -1); |
| 1981 __ b(&fail, NE); |
| 1982 __ vmovrs(shift, sout1); |
| 1983 __ CompareImmediate(shift, -1); |
| 1984 __ b(&fail, NE); |
| 1985 |
| 1986 __ LoadImmediate(R0, 0); |
| 1987 __ bx(LR); |
| 1988 |
| 1989 __ Bind(&fail); |
| 1990 __ LoadImmediate(R0, 1); |
| 1991 __ bx(LR); |
| 1992 } |
| 1993 |
| 1994 |
| 1995 ASSEMBLER_TEST_RUN(Mint_shl_overflow, test) { |
| 1996 EXPECT(test != NULL); |
| 1997 typedef int (*Tst)(); |
| 1998 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 1999 } |
| 2000 |
| 2001 |
1820 ASSEMBLER_TEST_GENERATE(Vsubqi8, assembler) { | 2002 ASSEMBLER_TEST_GENERATE(Vsubqi8, assembler) { |
1821 if (TargetCPUFeatures::neon_supported()) { | 2003 if (TargetCPUFeatures::neon_supported()) { |
1822 __ mov(R0, ShifterOperand(1)); | 2004 __ mov(R0, ShifterOperand(1)); |
1823 __ vmovsr(S0, R0); | 2005 __ vmovsr(S0, R0); |
1824 __ mov(R0, ShifterOperand(2)); | 2006 __ mov(R0, ShifterOperand(2)); |
1825 __ vmovsr(S1, R0); | 2007 __ vmovsr(S1, R0); |
1826 __ mov(R0, ShifterOperand(3)); | 2008 __ mov(R0, ShifterOperand(3)); |
1827 __ vmovsr(S2, R0); | 2009 __ vmovsr(S2, R0); |
1828 __ mov(R0, ShifterOperand(4)); | 2010 __ mov(R0, ShifterOperand(4)); |
1829 __ vmovsr(S3, R0); | 2011 __ vmovsr(S3, R0); |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 } | 2771 } |
2590 | 2772 |
2591 | 2773 |
2592 ASSEMBLER_TEST_RUN(Vmovq, test) { | 2774 ASSEMBLER_TEST_RUN(Vmovq, test) { |
2593 EXPECT(test != NULL); | 2775 EXPECT(test != NULL); |
2594 typedef int (*Tst)(); | 2776 typedef int (*Tst)(); |
2595 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 2777 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
2596 } | 2778 } |
2597 | 2779 |
2598 | 2780 |
| 2781 ASSEMBLER_TEST_GENERATE(Vmvnq, assembler) { |
| 2782 if (TargetCPUFeatures::neon_supported()) { |
| 2783 __ LoadImmediate(R1, 42); // R1 <- 42. |
| 2784 __ vmovsr(S2, R1); // S2 <- R1. |
| 2785 __ vmvnq(Q1, Q0); // Q1 <- ~Q0. |
| 2786 __ vmvnq(Q2, Q1); // Q2 <- ~Q1. |
| 2787 __ vmovrs(R0, S10); // Now R0 should be 42 again. |
| 2788 __ bx(LR); |
| 2789 } else { |
| 2790 __ LoadImmediate(R0, 42); |
| 2791 __ bx(LR); |
| 2792 } |
| 2793 } |
| 2794 |
| 2795 |
| 2796 ASSEMBLER_TEST_RUN(Vmvnq, test) { |
| 2797 EXPECT(test != NULL); |
| 2798 typedef int (*Tst)(); |
| 2799 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 2800 } |
| 2801 |
| 2802 |
2599 ASSEMBLER_TEST_GENERATE(Vdupb, assembler) { | 2803 ASSEMBLER_TEST_GENERATE(Vdupb, assembler) { |
2600 if (TargetCPUFeatures::neon_supported()) { | 2804 if (TargetCPUFeatures::neon_supported()) { |
2601 __ LoadImmediate(R0, 0x00000000); | 2805 __ LoadImmediate(R0, 0x00000000); |
2602 __ LoadImmediate(R1, 0x00ff0000); | 2806 __ LoadImmediate(R1, 0x00ff0000); |
2603 __ vmovsr(S4, R0); | 2807 __ vmovsr(S4, R0); |
2604 __ vmovsr(S5, R1); | 2808 __ vmovsr(S5, R1); |
2605 | 2809 |
2606 // Should copy 0xff to each byte of Q0. | 2810 // Should copy 0xff to each byte of Q0. |
2607 __ vdup(kByte, Q0, D2, 6); | 2811 __ vdup(kByte, Q0, D2, 6); |
2608 | 2812 |
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3593 __ StoreIntoObject(R2, | 3797 __ StoreIntoObject(R2, |
3594 FieldAddress(R2, GrowableObjectArray::data_offset()), | 3798 FieldAddress(R2, GrowableObjectArray::data_offset()), |
3595 R1); | 3799 R1); |
3596 __ PopList((1 << CTX) | (1 << LR)); | 3800 __ PopList((1 << CTX) | (1 << LR)); |
3597 __ Ret(); | 3801 __ Ret(); |
3598 } | 3802 } |
3599 | 3803 |
3600 } // namespace dart | 3804 } // namespace dart |
3601 | 3805 |
3602 #endif // defined TARGET_ARCH_ARM | 3806 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |