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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 namespace internal { | 45 namespace internal { |
46 | 46 |
47 #ifdef DEBUG | 47 #ifdef DEBUG |
48 bool CpuFeatures::initialized_ = false; | 48 bool CpuFeatures::initialized_ = false; |
49 #endif | 49 #endif |
50 unsigned CpuFeatures::supported_ = 0; | 50 unsigned CpuFeatures::supported_ = 0; |
51 unsigned CpuFeatures::found_by_runtime_probing_ = 0; | 51 unsigned CpuFeatures::found_by_runtime_probing_ = 0; |
52 | 52 |
53 | 53 |
54 // Get the CPU features enabled by the build. For cross compilation the | 54 // Get the CPU features enabled by the build. For cross compilation the |
55 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP_INSTRUCTIONS | 55 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS |
56 // can be defined to enable ARMv7 and VFPv3 instructions when building the | 56 // can be defined to enable ARMv7 and VFPv3 instructions when building the |
57 // snapshot. | 57 // snapshot. |
58 static uint64_t CpuFeaturesImpliedByCompiler() { | 58 static unsigned CpuFeaturesImpliedByCompiler() { |
59 uint64_t answer = 0; | 59 unsigned answer = 0; |
60 #ifdef CAN_USE_ARMV7_INSTRUCTIONS | 60 #ifdef CAN_USE_ARMV7_INSTRUCTIONS |
61 answer |= 1u << ARMv7; | 61 answer |= 1u << ARMv7; |
62 #endif // def CAN_USE_ARMV7_INSTRUCTIONS | 62 #endif // CAN_USE_ARMV7_INSTRUCTIONS |
63 #ifdef CAN_USE_VFP_INSTRUCTIONS | 63 #ifdef CAN_USE_VFP3_INSTRUCTIONS |
64 answer |= 1u << VFP3 | 1u << ARMv7; | 64 answer |= 1u << VFP3 | 1u << VFP2 | 1u << ARMv7; |
65 #endif // def CAN_USE_VFP_INSTRUCTIONS | 65 #endif // CAN_USE_VFP3_INSTRUCTIONS |
66 #ifdef CAN_USE_VFP2_INSTRUCTIONS | |
67 answer |= 1u << VFP2; | |
68 #endif // CAN_USE_VFP2_INSTRUCTIONS | |
66 | 69 |
67 #ifdef __arm__ | 70 #ifdef __arm__ |
68 // If the compiler is allowed to use VFP then we can use VFP too in our code | 71 // If the compiler is allowed to use VFP then we can use VFP too in our code |
69 // generation even when generating snapshots. ARMv7 and hardware floating | 72 // generation even when generating snapshots. ARMv7 and hardware floating |
70 // point support implies VFPv3, see ARM DDI 0406B, page A1-6. | 73 // point support implies VFPv3, see ARM DDI 0406B, page A1-6. |
71 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \ | 74 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \ |
72 && !defined(__SOFTFP__) | 75 && !defined(__SOFTFP__) |
73 answer |= 1u << VFP3 | 1u << ARMv7; | 76 answer |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; |
74 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) | 77 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) |
75 // && !defined(__SOFTFP__) | 78 // && !defined(__SOFTFP__) |
76 #endif // def __arm__ | 79 #endif // _arm__ |
77 | 80 |
78 return answer; | 81 return answer; |
79 } | 82 } |
80 | 83 |
81 | 84 |
82 void CpuFeatures::Probe() { | 85 void CpuFeatures::Probe() { |
83 unsigned standard_features = static_cast<unsigned>( | 86 unsigned standard_features = static_cast<unsigned>( |
84 OS::CpuFeaturesImpliedByPlatform() | CpuFeaturesImpliedByCompiler()); | 87 OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler(); |
85 ASSERT(supported_ == 0 || supported_ == standard_features); | 88 ASSERT(supported_ == 0 || supported_ == standard_features); |
86 #ifdef DEBUG | 89 #ifdef DEBUG |
87 initialized_ = true; | 90 initialized_ = true; |
88 #endif | 91 #endif |
89 | 92 |
90 // Get the features implied by the OS and the compiler settings. This is the | 93 // Get the features implied by the OS and the compiler settings. This is the |
91 // minimal set of features which is also alowed for generated code in the | 94 // minimal set of features which is also alowed for generated code in the |
92 // snapshot. | 95 // snapshot. |
93 supported_ |= standard_features; | 96 supported_ |= standard_features; |
94 | 97 |
95 if (Serializer::enabled()) { | 98 if (Serializer::enabled()) { |
96 // No probing for features if we might serialize (generate snapshot). | 99 // No probing for features if we might serialize (generate snapshot). |
97 return; | 100 return; |
98 } | 101 } |
99 | 102 |
100 #ifndef __arm__ | 103 #ifndef __arm__ |
101 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is | 104 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is |
102 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. | 105 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. |
103 if (FLAG_enable_vfp3) { | 106 if (FLAG_enable_vfp3) { |
104 supported_ |= 1u << VFP3 | 1u << ARMv7; | 107 supported_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; |
105 } | 108 } |
106 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled | 109 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled |
107 if (FLAG_enable_armv7) { | 110 if (FLAG_enable_armv7) { |
108 supported_ |= 1u << ARMv7; | 111 supported_ |= 1u << ARMv7; |
109 } | 112 } |
110 #else // def __arm__ | 113 #else // __arm__ |
111 // Probe for additional features not already known to be available. | 114 // Probe for additional features not already known to be available. |
112 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { | 115 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { |
113 // This implementation also sets the VFP flags if runtime | 116 // This implementation also sets the VFP flags if runtime |
114 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI | 117 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI |
115 // 0406B, page A1-6. | 118 // 0406B, page A1-6. |
116 supported_ |= 1u << VFP3 | 1u << ARMv7; | 119 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; |
117 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7; | 120 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { |
121 found_by_runtime_probing_ |= 1u << VFP2; | |
118 } | 122 } |
119 | 123 |
120 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { | 124 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { |
121 supported_ |= 1u << ARMv7; | |
122 found_by_runtime_probing_ |= 1u << ARMv7; | 125 found_by_runtime_probing_ |= 1u << ARMv7; |
123 } | 126 } |
127 | |
128 supported_ |= found_by_runtime_probing_; | |
124 #endif | 129 #endif |
130 | |
131 // Assert that VFP3 implies VFP2 and ARMv7. | |
132 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); | |
Rodolph Perfetta
2012/07/25 10:59:54
It is possible to have an ARMv7 core without VFP a
Yang
2012/07/25 12:09:32
This only tests that VFP3 -> (VFP2 && ARMv7)
if AR
| |
125 } | 133 } |
126 | 134 |
127 | 135 |
128 // ----------------------------------------------------------------------------- | 136 // ----------------------------------------------------------------------------- |
129 // Implementation of RelocInfo | 137 // Implementation of RelocInfo |
130 | 138 |
131 const int RelocInfo::kApplyMask = 0; | 139 const int RelocInfo::kApplyMask = 0; |
132 | 140 |
133 | 141 |
134 bool RelocInfo::IsCodedSpecially() { | 142 bool RelocInfo::IsCodedSpecially() { |
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1649 // Support for VFP. | 1657 // Support for VFP. |
1650 | 1658 |
1651 void Assembler::vldr(const DwVfpRegister dst, | 1659 void Assembler::vldr(const DwVfpRegister dst, |
1652 const Register base, | 1660 const Register base, |
1653 int offset, | 1661 int offset, |
1654 const Condition cond) { | 1662 const Condition cond) { |
1655 // Ddst = MEM(Rbase + offset). | 1663 // Ddst = MEM(Rbase + offset). |
1656 // Instruction details available in ARM DDI 0406A, A8-628. | 1664 // Instruction details available in ARM DDI 0406A, A8-628. |
1657 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1665 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
1658 // Vdst(15-12) | 1011(11-8) | offset | 1666 // Vdst(15-12) | 1011(11-8) | offset |
1659 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1667 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1660 int u = 1; | 1668 int u = 1; |
1661 if (offset < 0) { | 1669 if (offset < 0) { |
1662 offset = -offset; | 1670 offset = -offset; |
1663 u = 0; | 1671 u = 0; |
1664 } | 1672 } |
1665 | 1673 |
1666 ASSERT(offset >= 0); | 1674 ASSERT(offset >= 0); |
1667 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1675 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1668 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | | 1676 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | |
1669 0xB*B8 | ((offset / 4) & 255)); | 1677 0xB*B8 | ((offset / 4) & 255)); |
(...skipping 21 matching lines...) Expand all Loading... | |
1691 | 1699 |
1692 | 1700 |
1693 void Assembler::vldr(const SwVfpRegister dst, | 1701 void Assembler::vldr(const SwVfpRegister dst, |
1694 const Register base, | 1702 const Register base, |
1695 int offset, | 1703 int offset, |
1696 const Condition cond) { | 1704 const Condition cond) { |
1697 // Sdst = MEM(Rbase + offset). | 1705 // Sdst = MEM(Rbase + offset). |
1698 // Instruction details available in ARM DDI 0406A, A8-628. | 1706 // Instruction details available in ARM DDI 0406A, A8-628. |
1699 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1707 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
1700 // Vdst(15-12) | 1010(11-8) | offset | 1708 // Vdst(15-12) | 1010(11-8) | offset |
1701 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1709 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1702 int u = 1; | 1710 int u = 1; |
1703 if (offset < 0) { | 1711 if (offset < 0) { |
1704 offset = -offset; | 1712 offset = -offset; |
1705 u = 0; | 1713 u = 0; |
1706 } | 1714 } |
1707 int sd, d; | 1715 int sd, d; |
1708 dst.split_code(&sd, &d); | 1716 dst.split_code(&sd, &d); |
1709 ASSERT(offset >= 0); | 1717 ASSERT(offset >= 0); |
1710 | 1718 |
1711 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1719 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... | |
1735 | 1743 |
1736 | 1744 |
1737 void Assembler::vstr(const DwVfpRegister src, | 1745 void Assembler::vstr(const DwVfpRegister src, |
1738 const Register base, | 1746 const Register base, |
1739 int offset, | 1747 int offset, |
1740 const Condition cond) { | 1748 const Condition cond) { |
1741 // MEM(Rbase + offset) = Dsrc. | 1749 // MEM(Rbase + offset) = Dsrc. |
1742 // Instruction details available in ARM DDI 0406A, A8-786. | 1750 // Instruction details available in ARM DDI 0406A, A8-786. |
1743 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | | 1751 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | |
1744 // Vsrc(15-12) | 1011(11-8) | (offset/4) | 1752 // Vsrc(15-12) | 1011(11-8) | (offset/4) |
1745 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1753 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1746 int u = 1; | 1754 int u = 1; |
1747 if (offset < 0) { | 1755 if (offset < 0) { |
1748 offset = -offset; | 1756 offset = -offset; |
1749 u = 0; | 1757 u = 0; |
1750 } | 1758 } |
1751 ASSERT(offset >= 0); | 1759 ASSERT(offset >= 0); |
1752 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1760 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1753 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | | 1761 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | |
1754 0xB*B8 | ((offset / 4) & 255)); | 1762 0xB*B8 | ((offset / 4) & 255)); |
1755 } else { | 1763 } else { |
(...skipping 20 matching lines...) Expand all Loading... | |
1776 | 1784 |
1777 | 1785 |
1778 void Assembler::vstr(const SwVfpRegister src, | 1786 void Assembler::vstr(const SwVfpRegister src, |
1779 const Register base, | 1787 const Register base, |
1780 int offset, | 1788 int offset, |
1781 const Condition cond) { | 1789 const Condition cond) { |
1782 // MEM(Rbase + offset) = SSrc. | 1790 // MEM(Rbase + offset) = SSrc. |
1783 // Instruction details available in ARM DDI 0406A, A8-786. | 1791 // Instruction details available in ARM DDI 0406A, A8-786. |
1784 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | | 1792 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | |
1785 // Vdst(15-12) | 1010(11-8) | (offset/4) | 1793 // Vdst(15-12) | 1010(11-8) | (offset/4) |
1786 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1794 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1787 int u = 1; | 1795 int u = 1; |
1788 if (offset < 0) { | 1796 if (offset < 0) { |
1789 offset = -offset; | 1797 offset = -offset; |
1790 u = 0; | 1798 u = 0; |
1791 } | 1799 } |
1792 int sd, d; | 1800 int sd, d; |
1793 src.split_code(&sd, &d); | 1801 src.split_code(&sd, &d); |
1794 ASSERT(offset >= 0); | 1802 ASSERT(offset >= 0); |
1795 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1803 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1796 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | | 1804 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | |
(...skipping 22 matching lines...) Expand all Loading... | |
1819 | 1827 |
1820 | 1828 |
1821 void Assembler::vldm(BlockAddrMode am, | 1829 void Assembler::vldm(BlockAddrMode am, |
1822 Register base, | 1830 Register base, |
1823 DwVfpRegister first, | 1831 DwVfpRegister first, |
1824 DwVfpRegister last, | 1832 DwVfpRegister last, |
1825 Condition cond) { | 1833 Condition cond) { |
1826 // Instruction details available in ARM DDI 0406A, A8-626. | 1834 // Instruction details available in ARM DDI 0406A, A8-626. |
1827 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1835 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
1828 // first(15-12) | 1010(11-8) | (count * 2) | 1836 // first(15-12) | 1010(11-8) | (count * 2) |
1829 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1837 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1830 ASSERT_LE(first.code(), last.code()); | 1838 ASSERT_LE(first.code(), last.code()); |
1831 ASSERT(am == ia || am == ia_w || am == db_w); | 1839 ASSERT(am == ia || am == ia_w || am == db_w); |
1832 ASSERT(!base.is(pc)); | 1840 ASSERT(!base.is(pc)); |
1833 | 1841 |
1834 int sd, d; | 1842 int sd, d; |
1835 first.split_code(&sd, &d); | 1843 first.split_code(&sd, &d); |
1836 int count = last.code() - first.code() + 1; | 1844 int count = last.code() - first.code() + 1; |
1837 ASSERT(count <= 16); | 1845 ASSERT(count <= 16); |
1838 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1846 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
1839 0xB*B8 | count*2); | 1847 0xB*B8 | count*2); |
1840 } | 1848 } |
1841 | 1849 |
1842 | 1850 |
1843 void Assembler::vstm(BlockAddrMode am, | 1851 void Assembler::vstm(BlockAddrMode am, |
1844 Register base, | 1852 Register base, |
1845 DwVfpRegister first, | 1853 DwVfpRegister first, |
1846 DwVfpRegister last, | 1854 DwVfpRegister last, |
1847 Condition cond) { | 1855 Condition cond) { |
1848 // Instruction details available in ARM DDI 0406A, A8-784. | 1856 // Instruction details available in ARM DDI 0406A, A8-784. |
1849 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 1857 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
1850 // first(15-12) | 1011(11-8) | (count * 2) | 1858 // first(15-12) | 1011(11-8) | (count * 2) |
1851 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1859 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1852 ASSERT_LE(first.code(), last.code()); | 1860 ASSERT_LE(first.code(), last.code()); |
1853 ASSERT(am == ia || am == ia_w || am == db_w); | 1861 ASSERT(am == ia || am == ia_w || am == db_w); |
1854 ASSERT(!base.is(pc)); | 1862 ASSERT(!base.is(pc)); |
1855 | 1863 |
1856 int sd, d; | 1864 int sd, d; |
1857 first.split_code(&sd, &d); | 1865 first.split_code(&sd, &d); |
1858 int count = last.code() - first.code() + 1; | 1866 int count = last.code() - first.code() + 1; |
1859 ASSERT(count <= 16); | 1867 ASSERT(count <= 16); |
1860 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 1868 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
1861 0xB*B8 | count*2); | 1869 0xB*B8 | count*2); |
1862 } | 1870 } |
1863 | 1871 |
1864 void Assembler::vldm(BlockAddrMode am, | 1872 void Assembler::vldm(BlockAddrMode am, |
1865 Register base, | 1873 Register base, |
1866 SwVfpRegister first, | 1874 SwVfpRegister first, |
1867 SwVfpRegister last, | 1875 SwVfpRegister last, |
1868 Condition cond) { | 1876 Condition cond) { |
1869 // Instruction details available in ARM DDI 0406A, A8-626. | 1877 // Instruction details available in ARM DDI 0406A, A8-626. |
1870 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1878 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
1871 // first(15-12) | 1010(11-8) | (count/2) | 1879 // first(15-12) | 1010(11-8) | (count/2) |
1872 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1880 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1873 ASSERT_LE(first.code(), last.code()); | 1881 ASSERT_LE(first.code(), last.code()); |
1874 ASSERT(am == ia || am == ia_w || am == db_w); | 1882 ASSERT(am == ia || am == ia_w || am == db_w); |
1875 ASSERT(!base.is(pc)); | 1883 ASSERT(!base.is(pc)); |
1876 | 1884 |
1877 int sd, d; | 1885 int sd, d; |
1878 first.split_code(&sd, &d); | 1886 first.split_code(&sd, &d); |
1879 int count = last.code() - first.code() + 1; | 1887 int count = last.code() - first.code() + 1; |
1880 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1888 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
1881 0xA*B8 | count); | 1889 0xA*B8 | count); |
1882 } | 1890 } |
1883 | 1891 |
1884 | 1892 |
1885 void Assembler::vstm(BlockAddrMode am, | 1893 void Assembler::vstm(BlockAddrMode am, |
1886 Register base, | 1894 Register base, |
1887 SwVfpRegister first, | 1895 SwVfpRegister first, |
1888 SwVfpRegister last, | 1896 SwVfpRegister last, |
1889 Condition cond) { | 1897 Condition cond) { |
1890 // Instruction details available in ARM DDI 0406A, A8-784. | 1898 // Instruction details available in ARM DDI 0406A, A8-784. |
1891 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 1899 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
1892 // first(15-12) | 1011(11-8) | (count/2) | 1900 // first(15-12) | 1011(11-8) | (count/2) |
1893 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1901 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1894 ASSERT_LE(first.code(), last.code()); | 1902 ASSERT_LE(first.code(), last.code()); |
1895 ASSERT(am == ia || am == ia_w || am == db_w); | 1903 ASSERT(am == ia || am == ia_w || am == db_w); |
1896 ASSERT(!base.is(pc)); | 1904 ASSERT(!base.is(pc)); |
1897 | 1905 |
1898 int sd, d; | 1906 int sd, d; |
1899 first.split_code(&sd, &d); | 1907 first.split_code(&sd, &d); |
1900 int count = last.code() - first.code() + 1; | 1908 int count = last.code() - first.code() + 1; |
1901 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 1909 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
1902 0xA*B8 | count); | 1910 0xA*B8 | count); |
1903 } | 1911 } |
1904 | 1912 |
1905 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { | 1913 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
1906 uint64_t i; | 1914 uint64_t i; |
1907 memcpy(&i, &d, 8); | 1915 memcpy(&i, &d, 8); |
1908 | 1916 |
1909 *lo = i & 0xffffffff; | 1917 *lo = i & 0xffffffff; |
1910 *hi = i >> 32; | 1918 *hi = i >> 32; |
1911 } | 1919 } |
1912 | 1920 |
1913 // Only works for little endian floating point formats. | 1921 // Only works for little endian floating point formats. |
1914 // We don't support VFP on the mixed endian floating point platform. | 1922 // We don't support VFP on the mixed endian floating point platform. |
1915 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { | 1923 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { |
1916 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1924 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
Rodolph Perfetta
2012/07/25 10:59:54
I would leave VFP3 as a requirement as this functi
Yang
2012/07/25 12:09:32
Done.
| |
1917 | 1925 |
1918 // VMOV can accept an immediate of the form: | 1926 // VMOV can accept an immediate of the form: |
1919 // | 1927 // |
1920 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 | 1928 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 |
1921 // | 1929 // |
1922 // The immediate is encoded using an 8-bit quantity, comprised of two | 1930 // The immediate is encoded using an 8-bit quantity, comprised of two |
1923 // 4-bit fields. For an 8-bit immediate of the form: | 1931 // 4-bit fields. For an 8-bit immediate of the form: |
1924 // | 1932 // |
1925 // [abcdefgh] | 1933 // [abcdefgh] |
1926 // | 1934 // |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1959 | 1967 |
1960 return true; | 1968 return true; |
1961 } | 1969 } |
1962 | 1970 |
1963 | 1971 |
1964 void Assembler::vmov(const DwVfpRegister dst, | 1972 void Assembler::vmov(const DwVfpRegister dst, |
1965 double imm, | 1973 double imm, |
1966 const Condition cond) { | 1974 const Condition cond) { |
1967 // Dd = immediate | 1975 // Dd = immediate |
1968 // Instruction details available in ARM DDI 0406B, A8-640. | 1976 // Instruction details available in ARM DDI 0406B, A8-640. |
1969 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1977 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
1970 | 1978 |
1971 uint32_t enc; | 1979 uint32_t enc; |
1972 if (FitsVMOVDoubleImmediate(imm, &enc)) { | 1980 if (FitsVMOVDoubleImmediate(imm, &enc) && |
1981 CpuFeatures::IsSupported(VFP3)) { | |
Rodolph Perfetta
2012/07/25 10:59:54
Reverse the order of the test, then FitsVMOVDouble
Yang
2012/07/25 12:09:32
Done.
| |
1973 // The double can be encoded in the instruction. | 1982 // The double can be encoded in the instruction. |
1974 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); | 1983 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); |
1975 } else { | 1984 } else { |
1976 // Synthesise the double from ARM immediates. This could be implemented | 1985 // Synthesise the double from ARM immediates. This could be implemented |
1977 // using vldr from a constant pool. | 1986 // using vldr from a constant pool. |
1978 uint32_t lo, hi; | 1987 uint32_t lo, hi; |
1979 DoubleAsTwoUInt32(imm, &lo, &hi); | 1988 DoubleAsTwoUInt32(imm, &lo, &hi); |
1980 | 1989 |
1981 if (lo == hi) { | 1990 if (lo == hi) { |
1982 // If the lo and hi parts of the double are equal, the literal is easier | 1991 // If the lo and hi parts of the double are equal, the literal is easier |
(...skipping 13 matching lines...) Expand all Loading... | |
1996 } | 2005 } |
1997 } | 2006 } |
1998 } | 2007 } |
1999 | 2008 |
2000 | 2009 |
2001 void Assembler::vmov(const SwVfpRegister dst, | 2010 void Assembler::vmov(const SwVfpRegister dst, |
2002 const SwVfpRegister src, | 2011 const SwVfpRegister src, |
2003 const Condition cond) { | 2012 const Condition cond) { |
2004 // Sd = Sm | 2013 // Sd = Sm |
2005 // Instruction details available in ARM DDI 0406B, A8-642. | 2014 // Instruction details available in ARM DDI 0406B, A8-642. |
2006 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2015 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2007 int sd, d, sm, m; | 2016 int sd, d, sm, m; |
2008 dst.split_code(&sd, &d); | 2017 dst.split_code(&sd, &d); |
2009 src.split_code(&sm, &m); | 2018 src.split_code(&sm, &m); |
2010 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); | 2019 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); |
2011 } | 2020 } |
2012 | 2021 |
2013 | 2022 |
2014 void Assembler::vmov(const DwVfpRegister dst, | 2023 void Assembler::vmov(const DwVfpRegister dst, |
2015 const DwVfpRegister src, | 2024 const DwVfpRegister src, |
2016 const Condition cond) { | 2025 const Condition cond) { |
2017 // Dd = Dm | 2026 // Dd = Dm |
2018 // Instruction details available in ARM DDI 0406B, A8-642. | 2027 // Instruction details available in ARM DDI 0406B, A8-642. |
2019 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2028 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2020 emit(cond | 0xE*B24 | 0xB*B20 | | 2029 emit(cond | 0xE*B24 | 0xB*B20 | |
2021 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); | 2030 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); |
2022 } | 2031 } |
2023 | 2032 |
2024 | 2033 |
2025 void Assembler::vmov(const DwVfpRegister dst, | 2034 void Assembler::vmov(const DwVfpRegister dst, |
2026 const Register src1, | 2035 const Register src1, |
2027 const Register src2, | 2036 const Register src2, |
2028 const Condition cond) { | 2037 const Condition cond) { |
2029 // Dm = <Rt,Rt2>. | 2038 // Dm = <Rt,Rt2>. |
2030 // Instruction details available in ARM DDI 0406A, A8-646. | 2039 // Instruction details available in ARM DDI 0406A, A8-646. |
2031 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | | 2040 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
2032 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2041 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2033 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2042 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2034 ASSERT(!src1.is(pc) && !src2.is(pc)); | 2043 ASSERT(!src1.is(pc) && !src2.is(pc)); |
2035 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2044 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
2036 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); | 2045 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); |
2037 } | 2046 } |
2038 | 2047 |
2039 | 2048 |
2040 void Assembler::vmov(const Register dst1, | 2049 void Assembler::vmov(const Register dst1, |
2041 const Register dst2, | 2050 const Register dst2, |
2042 const DwVfpRegister src, | 2051 const DwVfpRegister src, |
2043 const Condition cond) { | 2052 const Condition cond) { |
2044 // <Rt,Rt2> = Dm. | 2053 // <Rt,Rt2> = Dm. |
2045 // Instruction details available in ARM DDI 0406A, A8-646. | 2054 // Instruction details available in ARM DDI 0406A, A8-646. |
2046 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | | 2055 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
2047 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2056 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2048 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2057 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2049 ASSERT(!dst1.is(pc) && !dst2.is(pc)); | 2058 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
2050 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2059 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
2051 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); | 2060 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); |
2052 } | 2061 } |
2053 | 2062 |
2054 | 2063 |
2055 void Assembler::vmov(const SwVfpRegister dst, | 2064 void Assembler::vmov(const SwVfpRegister dst, |
2056 const Register src, | 2065 const Register src, |
2057 const Condition cond) { | 2066 const Condition cond) { |
2058 // Sn = Rt. | 2067 // Sn = Rt. |
2059 // Instruction details available in ARM DDI 0406A, A8-642. | 2068 // Instruction details available in ARM DDI 0406A, A8-642. |
2060 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | | 2069 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
2061 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2070 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2062 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2071 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2063 ASSERT(!src.is(pc)); | 2072 ASSERT(!src.is(pc)); |
2064 int sn, n; | 2073 int sn, n; |
2065 dst.split_code(&sn, &n); | 2074 dst.split_code(&sn, &n); |
2066 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); | 2075 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); |
2067 } | 2076 } |
2068 | 2077 |
2069 | 2078 |
2070 void Assembler::vmov(const Register dst, | 2079 void Assembler::vmov(const Register dst, |
2071 const SwVfpRegister src, | 2080 const SwVfpRegister src, |
2072 const Condition cond) { | 2081 const Condition cond) { |
2073 // Rt = Sn. | 2082 // Rt = Sn. |
2074 // Instruction details available in ARM DDI 0406A, A8-642. | 2083 // Instruction details available in ARM DDI 0406A, A8-642. |
2075 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | | 2084 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
2076 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2085 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2077 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2086 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2078 ASSERT(!dst.is(pc)); | 2087 ASSERT(!dst.is(pc)); |
2079 int sn, n; | 2088 int sn, n; |
2080 src.split_code(&sn, &n); | 2089 src.split_code(&sn, &n); |
2081 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); | 2090 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); |
2082 } | 2091 } |
2083 | 2092 |
2084 | 2093 |
2085 // Type of data to read from or write to VFP register. | 2094 // Type of data to read from or write to VFP register. |
2086 // Used as specifier in generic vcvt instruction. | 2095 // Used as specifier in generic vcvt instruction. |
2087 enum VFPType { S32, U32, F32, F64 }; | 2096 enum VFPType { S32, U32, F32, F64 }; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2192 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | | 2201 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
2193 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 2202 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
2194 } | 2203 } |
2195 } | 2204 } |
2196 | 2205 |
2197 | 2206 |
2198 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 2207 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
2199 const SwVfpRegister src, | 2208 const SwVfpRegister src, |
2200 VFPConversionMode mode, | 2209 VFPConversionMode mode, |
2201 const Condition cond) { | 2210 const Condition cond) { |
2202 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2211 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2203 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); | 2212 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); |
2204 } | 2213 } |
2205 | 2214 |
2206 | 2215 |
2207 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, | 2216 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, |
2208 const SwVfpRegister src, | 2217 const SwVfpRegister src, |
2209 VFPConversionMode mode, | 2218 VFPConversionMode mode, |
2210 const Condition cond) { | 2219 const Condition cond) { |
2211 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2220 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2212 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); | 2221 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); |
2213 } | 2222 } |
2214 | 2223 |
2215 | 2224 |
2216 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, | 2225 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, |
2217 const SwVfpRegister src, | 2226 const SwVfpRegister src, |
2218 VFPConversionMode mode, | 2227 VFPConversionMode mode, |
2219 const Condition cond) { | 2228 const Condition cond) { |
2220 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2229 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2221 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); | 2230 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); |
2222 } | 2231 } |
2223 | 2232 |
2224 | 2233 |
2225 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, | 2234 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, |
2226 const DwVfpRegister src, | 2235 const DwVfpRegister src, |
2227 VFPConversionMode mode, | 2236 VFPConversionMode mode, |
2228 const Condition cond) { | 2237 const Condition cond) { |
2229 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2238 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2230 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); | 2239 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); |
2231 } | 2240 } |
2232 | 2241 |
2233 | 2242 |
2234 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, | 2243 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, |
2235 const DwVfpRegister src, | 2244 const DwVfpRegister src, |
2236 VFPConversionMode mode, | 2245 VFPConversionMode mode, |
2237 const Condition cond) { | 2246 const Condition cond) { |
2238 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2247 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2239 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); | 2248 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); |
2240 } | 2249 } |
2241 | 2250 |
2242 | 2251 |
2243 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, | 2252 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, |
2244 const SwVfpRegister src, | 2253 const SwVfpRegister src, |
2245 VFPConversionMode mode, | 2254 VFPConversionMode mode, |
2246 const Condition cond) { | 2255 const Condition cond) { |
2247 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2256 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2248 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); | 2257 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); |
2249 } | 2258 } |
2250 | 2259 |
2251 | 2260 |
2252 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, | 2261 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
2253 const DwVfpRegister src, | 2262 const DwVfpRegister src, |
2254 VFPConversionMode mode, | 2263 VFPConversionMode mode, |
2255 const Condition cond) { | 2264 const Condition cond) { |
2256 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2265 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2257 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 2266 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
2258 } | 2267 } |
2259 | 2268 |
2260 | 2269 |
2261 void Assembler::vneg(const DwVfpRegister dst, | 2270 void Assembler::vneg(const DwVfpRegister dst, |
2262 const DwVfpRegister src, | 2271 const DwVfpRegister src, |
2263 const Condition cond) { | 2272 const Condition cond) { |
2273 ASSERT(CpuFeatures::IsEnabled(VFP2)); | |
2264 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | | 2274 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | |
2265 0x5*B9 | B8 | B6 | src.code()); | 2275 0x5*B9 | B8 | B6 | src.code()); |
2266 } | 2276 } |
2267 | 2277 |
2268 | 2278 |
2269 void Assembler::vabs(const DwVfpRegister dst, | 2279 void Assembler::vabs(const DwVfpRegister dst, |
2270 const DwVfpRegister src, | 2280 const DwVfpRegister src, |
2271 const Condition cond) { | 2281 const Condition cond) { |
2282 ASSERT(CpuFeatures::IsEnabled(VFP2)); | |
2272 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | | 2283 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | |
2273 0x5*B9 | B8 | 0x3*B6 | src.code()); | 2284 0x5*B9 | B8 | 0x3*B6 | src.code()); |
2274 } | 2285 } |
2275 | 2286 |
2276 | 2287 |
2277 void Assembler::vadd(const DwVfpRegister dst, | 2288 void Assembler::vadd(const DwVfpRegister dst, |
2278 const DwVfpRegister src1, | 2289 const DwVfpRegister src1, |
2279 const DwVfpRegister src2, | 2290 const DwVfpRegister src2, |
2280 const Condition cond) { | 2291 const Condition cond) { |
2281 // Dd = vadd(Dn, Dm) double precision floating point addition. | 2292 // Dd = vadd(Dn, Dm) double precision floating point addition. |
2282 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2293 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2283 // Instruction details available in ARM DDI 0406A, A8-536. | 2294 // Instruction details available in ARM DDI 0406A, A8-536. |
2284 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | | 2295 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | |
2285 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) | 2296 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
2286 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2297 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2287 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2298 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
2288 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2299 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2289 } | 2300 } |
2290 | 2301 |
2291 | 2302 |
2292 void Assembler::vsub(const DwVfpRegister dst, | 2303 void Assembler::vsub(const DwVfpRegister dst, |
2293 const DwVfpRegister src1, | 2304 const DwVfpRegister src1, |
2294 const DwVfpRegister src2, | 2305 const DwVfpRegister src2, |
2295 const Condition cond) { | 2306 const Condition cond) { |
2296 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 2307 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
2297 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2308 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2298 // Instruction details available in ARM DDI 0406A, A8-784. | 2309 // Instruction details available in ARM DDI 0406A, A8-784. |
2299 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | | 2310 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | |
2300 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) | 2311 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
2301 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2312 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2302 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2313 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
2303 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2314 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
2304 } | 2315 } |
2305 | 2316 |
2306 | 2317 |
2307 void Assembler::vmul(const DwVfpRegister dst, | 2318 void Assembler::vmul(const DwVfpRegister dst, |
2308 const DwVfpRegister src1, | 2319 const DwVfpRegister src1, |
2309 const DwVfpRegister src2, | 2320 const DwVfpRegister src2, |
2310 const Condition cond) { | 2321 const Condition cond) { |
2311 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 2322 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
2312 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2323 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2313 // Instruction details available in ARM DDI 0406A, A8-784. | 2324 // Instruction details available in ARM DDI 0406A, A8-784. |
2314 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | | 2325 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | |
2315 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) | 2326 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
2316 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2327 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2317 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | | 2328 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | |
2318 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2329 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2319 } | 2330 } |
2320 | 2331 |
2321 | 2332 |
2322 void Assembler::vdiv(const DwVfpRegister dst, | 2333 void Assembler::vdiv(const DwVfpRegister dst, |
2323 const DwVfpRegister src1, | 2334 const DwVfpRegister src1, |
2324 const DwVfpRegister src2, | 2335 const DwVfpRegister src2, |
2325 const Condition cond) { | 2336 const Condition cond) { |
2326 // Dd = vdiv(Dn, Dm) double precision floating point division. | 2337 // Dd = vdiv(Dn, Dm) double precision floating point division. |
2327 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2338 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2328 // Instruction details available in ARM DDI 0406A, A8-584. | 2339 // Instruction details available in ARM DDI 0406A, A8-584. |
2329 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | | 2340 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | |
2330 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) | 2341 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
2331 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2342 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2332 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | | 2343 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | |
2333 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2344 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2334 } | 2345 } |
2335 | 2346 |
2336 | 2347 |
2337 void Assembler::vcmp(const DwVfpRegister src1, | 2348 void Assembler::vcmp(const DwVfpRegister src1, |
2338 const DwVfpRegister src2, | 2349 const DwVfpRegister src2, |
2339 const Condition cond) { | 2350 const Condition cond) { |
2340 // vcmp(Dd, Dm) double precision floating point comparison. | 2351 // vcmp(Dd, Dm) double precision floating point comparison. |
2341 // Instruction details available in ARM DDI 0406A, A8-570. | 2352 // Instruction details available in ARM DDI 0406A, A8-570. |
2342 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | | 2353 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | |
2343 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) | 2354 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) |
2344 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2355 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2345 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | | 2356 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | |
2346 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2357 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
2347 } | 2358 } |
2348 | 2359 |
2349 | 2360 |
2350 void Assembler::vcmp(const DwVfpRegister src1, | 2361 void Assembler::vcmp(const DwVfpRegister src1, |
2351 const double src2, | 2362 const double src2, |
2352 const Condition cond) { | 2363 const Condition cond) { |
2353 // vcmp(Dd, Dm) double precision floating point comparison. | 2364 // vcmp(Dd, Dm) double precision floating point comparison. |
2354 // Instruction details available in ARM DDI 0406A, A8-570. | 2365 // Instruction details available in ARM DDI 0406A, A8-570. |
2355 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | | 2366 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | |
2356 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) | 2367 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) |
2357 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2368 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2358 ASSERT(src2 == 0.0); | 2369 ASSERT(src2 == 0.0); |
2359 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | | 2370 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | |
2360 src1.code()*B12 | 0x5*B9 | B8 | B6); | 2371 src1.code()*B12 | 0x5*B9 | B8 | B6); |
2361 } | 2372 } |
2362 | 2373 |
2363 | 2374 |
2364 void Assembler::vmsr(Register dst, Condition cond) { | 2375 void Assembler::vmsr(Register dst, Condition cond) { |
2365 // Instruction details available in ARM DDI 0406A, A8-652. | 2376 // Instruction details available in ARM DDI 0406A, A8-652. |
2366 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | | 2377 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | |
2367 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2378 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2368 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2379 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2369 emit(cond | 0xE*B24 | 0xE*B20 | B16 | | 2380 emit(cond | 0xE*B24 | 0xE*B20 | B16 | |
2370 dst.code()*B12 | 0xA*B8 | B4); | 2381 dst.code()*B12 | 0xA*B8 | B4); |
2371 } | 2382 } |
2372 | 2383 |
2373 | 2384 |
2374 void Assembler::vmrs(Register dst, Condition cond) { | 2385 void Assembler::vmrs(Register dst, Condition cond) { |
2375 // Instruction details available in ARM DDI 0406A, A8-652. | 2386 // Instruction details available in ARM DDI 0406A, A8-652. |
2376 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | | 2387 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
2377 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2388 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2378 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2389 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2379 emit(cond | 0xE*B24 | 0xF*B20 | B16 | | 2390 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
2380 dst.code()*B12 | 0xA*B8 | B4); | 2391 dst.code()*B12 | 0xA*B8 | B4); |
2381 } | 2392 } |
2382 | 2393 |
2383 | 2394 |
2384 void Assembler::vsqrt(const DwVfpRegister dst, | 2395 void Assembler::vsqrt(const DwVfpRegister dst, |
2385 const DwVfpRegister src, | 2396 const DwVfpRegister src, |
2386 const Condition cond) { | 2397 const Condition cond) { |
2387 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | | 2398 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | |
2388 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) | 2399 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) |
2389 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2400 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2390 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | | 2401 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | |
2391 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); | 2402 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); |
2392 } | 2403 } |
2393 | 2404 |
2394 | 2405 |
2395 // Pseudo instructions. | 2406 // Pseudo instructions. |
2396 void Assembler::nop(int type) { | 2407 void Assembler::nop(int type) { |
2397 // This is mov rx, rx. | 2408 // This is mov rx, rx. |
2398 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. | 2409 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. |
2399 emit(al | 13*B21 | type*B12 | type); | 2410 emit(al | 13*B21 | type*B12 | type); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2671 | 2682 |
2672 // Since a constant pool was just emitted, move the check offset forward by | 2683 // Since a constant pool was just emitted, move the check offset forward by |
2673 // the standard interval. | 2684 // the standard interval. |
2674 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 2685 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
2675 } | 2686 } |
2676 | 2687 |
2677 | 2688 |
2678 } } // namespace v8::internal | 2689 } } // namespace v8::internal |
2679 | 2690 |
2680 #endif // V8_TARGET_ARCH_ARM | 2691 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |