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 14 matching lines...) Expand all Loading... |
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
31 // OF THE POSSIBILITY OF SUCH DAMAGE. | 31 // OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | 32 |
33 // The original source code covered by the above license above has been | 33 // The original source code covered by the above license above has been |
34 // modified significantly by Google Inc. | 34 // modified significantly by Google Inc. |
35 // Copyright 2011 the V8 project authors. All rights reserved. | 35 // Copyright 2012 the V8 project authors. All rights reserved. |
36 | 36 |
37 #include "v8.h" | 37 #include "v8.h" |
38 | 38 |
39 #if defined(V8_TARGET_ARCH_ARM) | 39 #if defined(V8_TARGET_ARCH_ARM) |
40 | 40 |
41 #include "arm/assembler-arm-inl.h" | 41 #include "arm/assembler-arm-inl.h" |
42 #include "serialize.h" | 42 #include "serialize.h" |
43 | 43 |
44 namespace v8 { | 44 namespace v8 { |
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))); |
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::IsSupported(VFP3)); |
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 (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { |
1973 // The double can be encoded in the instruction. | 1981 // The double can be encoded in the instruction. |
1974 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); | 1982 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); |
1975 } else { | 1983 } else { |
1976 // Synthesise the double from ARM immediates. This could be implemented | 1984 // Synthesise the double from ARM immediates. This could be implemented |
1977 // using vldr from a constant pool. | 1985 // using vldr from a constant pool. |
1978 uint32_t lo, hi; | 1986 uint32_t lo, hi; |
1979 DoubleAsTwoUInt32(imm, &lo, &hi); | 1987 DoubleAsTwoUInt32(imm, &lo, &hi); |
1980 | 1988 |
1981 if (lo == hi) { | 1989 if (lo == hi) { |
1982 // If the lo and hi parts of the double are equal, the literal is easier | 1990 // If the lo and hi parts of the double are equal, the literal is easier |
(...skipping 13 matching lines...) Expand all Loading... |
1996 } | 2004 } |
1997 } | 2005 } |
1998 } | 2006 } |
1999 | 2007 |
2000 | 2008 |
2001 void Assembler::vmov(const SwVfpRegister dst, | 2009 void Assembler::vmov(const SwVfpRegister dst, |
2002 const SwVfpRegister src, | 2010 const SwVfpRegister src, |
2003 const Condition cond) { | 2011 const Condition cond) { |
2004 // Sd = Sm | 2012 // Sd = Sm |
2005 // Instruction details available in ARM DDI 0406B, A8-642. | 2013 // Instruction details available in ARM DDI 0406B, A8-642. |
2006 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2014 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2007 int sd, d, sm, m; | 2015 int sd, d, sm, m; |
2008 dst.split_code(&sd, &d); | 2016 dst.split_code(&sd, &d); |
2009 src.split_code(&sm, &m); | 2017 src.split_code(&sm, &m); |
2010 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); | 2018 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); |
2011 } | 2019 } |
2012 | 2020 |
2013 | 2021 |
2014 void Assembler::vmov(const DwVfpRegister dst, | 2022 void Assembler::vmov(const DwVfpRegister dst, |
2015 const DwVfpRegister src, | 2023 const DwVfpRegister src, |
2016 const Condition cond) { | 2024 const Condition cond) { |
2017 // Dd = Dm | 2025 // Dd = Dm |
2018 // Instruction details available in ARM DDI 0406B, A8-642. | 2026 // Instruction details available in ARM DDI 0406B, A8-642. |
2019 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2027 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2020 emit(cond | 0xE*B24 | 0xB*B20 | | 2028 emit(cond | 0xE*B24 | 0xB*B20 | |
2021 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); | 2029 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); |
2022 } | 2030 } |
2023 | 2031 |
2024 | 2032 |
2025 void Assembler::vmov(const DwVfpRegister dst, | 2033 void Assembler::vmov(const DwVfpRegister dst, |
2026 const Register src1, | 2034 const Register src1, |
2027 const Register src2, | 2035 const Register src2, |
2028 const Condition cond) { | 2036 const Condition cond) { |
2029 // Dm = <Rt,Rt2>. | 2037 // Dm = <Rt,Rt2>. |
2030 // Instruction details available in ARM DDI 0406A, A8-646. | 2038 // 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) | | 2039 // 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 | 2040 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2033 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2041 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2034 ASSERT(!src1.is(pc) && !src2.is(pc)); | 2042 ASSERT(!src1.is(pc) && !src2.is(pc)); |
2035 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2043 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
2036 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); | 2044 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); |
2037 } | 2045 } |
2038 | 2046 |
2039 | 2047 |
2040 void Assembler::vmov(const Register dst1, | 2048 void Assembler::vmov(const Register dst1, |
2041 const Register dst2, | 2049 const Register dst2, |
2042 const DwVfpRegister src, | 2050 const DwVfpRegister src, |
2043 const Condition cond) { | 2051 const Condition cond) { |
2044 // <Rt,Rt2> = Dm. | 2052 // <Rt,Rt2> = Dm. |
2045 // Instruction details available in ARM DDI 0406A, A8-646. | 2053 // 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) | | 2054 // 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 | 2055 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2048 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2056 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2049 ASSERT(!dst1.is(pc) && !dst2.is(pc)); | 2057 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
2050 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2058 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
2051 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); | 2059 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); |
2052 } | 2060 } |
2053 | 2061 |
2054 | 2062 |
2055 void Assembler::vmov(const SwVfpRegister dst, | 2063 void Assembler::vmov(const SwVfpRegister dst, |
2056 const Register src, | 2064 const Register src, |
2057 const Condition cond) { | 2065 const Condition cond) { |
2058 // Sn = Rt. | 2066 // Sn = Rt. |
2059 // Instruction details available in ARM DDI 0406A, A8-642. | 2067 // 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) | | 2068 // 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) | 2069 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2062 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2070 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2063 ASSERT(!src.is(pc)); | 2071 ASSERT(!src.is(pc)); |
2064 int sn, n; | 2072 int sn, n; |
2065 dst.split_code(&sn, &n); | 2073 dst.split_code(&sn, &n); |
2066 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); | 2074 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); |
2067 } | 2075 } |
2068 | 2076 |
2069 | 2077 |
2070 void Assembler::vmov(const Register dst, | 2078 void Assembler::vmov(const Register dst, |
2071 const SwVfpRegister src, | 2079 const SwVfpRegister src, |
2072 const Condition cond) { | 2080 const Condition cond) { |
2073 // Rt = Sn. | 2081 // Rt = Sn. |
2074 // Instruction details available in ARM DDI 0406A, A8-642. | 2082 // 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) | | 2083 // 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) | 2084 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2077 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2085 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2078 ASSERT(!dst.is(pc)); | 2086 ASSERT(!dst.is(pc)); |
2079 int sn, n; | 2087 int sn, n; |
2080 src.split_code(&sn, &n); | 2088 src.split_code(&sn, &n); |
2081 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); | 2089 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); |
2082 } | 2090 } |
2083 | 2091 |
2084 | 2092 |
2085 // Type of data to read from or write to VFP register. | 2093 // Type of data to read from or write to VFP register. |
2086 // Used as specifier in generic vcvt instruction. | 2094 // Used as specifier in generic vcvt instruction. |
2087 enum VFPType { S32, U32, F32, F64 }; | 2095 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 | | 2200 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
2193 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 2201 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
2194 } | 2202 } |
2195 } | 2203 } |
2196 | 2204 |
2197 | 2205 |
2198 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 2206 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
2199 const SwVfpRegister src, | 2207 const SwVfpRegister src, |
2200 VFPConversionMode mode, | 2208 VFPConversionMode mode, |
2201 const Condition cond) { | 2209 const Condition cond) { |
2202 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2210 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2203 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); | 2211 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); |
2204 } | 2212 } |
2205 | 2213 |
2206 | 2214 |
2207 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, | 2215 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, |
2208 const SwVfpRegister src, | 2216 const SwVfpRegister src, |
2209 VFPConversionMode mode, | 2217 VFPConversionMode mode, |
2210 const Condition cond) { | 2218 const Condition cond) { |
2211 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2219 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2212 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); | 2220 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); |
2213 } | 2221 } |
2214 | 2222 |
2215 | 2223 |
2216 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, | 2224 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, |
2217 const SwVfpRegister src, | 2225 const SwVfpRegister src, |
2218 VFPConversionMode mode, | 2226 VFPConversionMode mode, |
2219 const Condition cond) { | 2227 const Condition cond) { |
2220 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2228 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2221 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); | 2229 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); |
2222 } | 2230 } |
2223 | 2231 |
2224 | 2232 |
2225 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, | 2233 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, |
2226 const DwVfpRegister src, | 2234 const DwVfpRegister src, |
2227 VFPConversionMode mode, | 2235 VFPConversionMode mode, |
2228 const Condition cond) { | 2236 const Condition cond) { |
2229 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2237 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2230 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); | 2238 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); |
2231 } | 2239 } |
2232 | 2240 |
2233 | 2241 |
2234 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, | 2242 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, |
2235 const DwVfpRegister src, | 2243 const DwVfpRegister src, |
2236 VFPConversionMode mode, | 2244 VFPConversionMode mode, |
2237 const Condition cond) { | 2245 const Condition cond) { |
2238 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2246 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2239 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); | 2247 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); |
2240 } | 2248 } |
2241 | 2249 |
2242 | 2250 |
2243 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, | 2251 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, |
2244 const SwVfpRegister src, | 2252 const SwVfpRegister src, |
2245 VFPConversionMode mode, | 2253 VFPConversionMode mode, |
2246 const Condition cond) { | 2254 const Condition cond) { |
2247 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2255 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2248 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); | 2256 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); |
2249 } | 2257 } |
2250 | 2258 |
2251 | 2259 |
2252 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, | 2260 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
2253 const DwVfpRegister src, | 2261 const DwVfpRegister src, |
2254 VFPConversionMode mode, | 2262 VFPConversionMode mode, |
2255 const Condition cond) { | 2263 const Condition cond) { |
2256 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2264 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2257 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 2265 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
2258 } | 2266 } |
2259 | 2267 |
2260 | 2268 |
2261 void Assembler::vneg(const DwVfpRegister dst, | 2269 void Assembler::vneg(const DwVfpRegister dst, |
2262 const DwVfpRegister src, | 2270 const DwVfpRegister src, |
2263 const Condition cond) { | 2271 const Condition cond) { |
| 2272 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2264 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | | 2273 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | |
2265 0x5*B9 | B8 | B6 | src.code()); | 2274 0x5*B9 | B8 | B6 | src.code()); |
2266 } | 2275 } |
2267 | 2276 |
2268 | 2277 |
2269 void Assembler::vabs(const DwVfpRegister dst, | 2278 void Assembler::vabs(const DwVfpRegister dst, |
2270 const DwVfpRegister src, | 2279 const DwVfpRegister src, |
2271 const Condition cond) { | 2280 const Condition cond) { |
| 2281 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2272 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | | 2282 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | |
2273 0x5*B9 | B8 | 0x3*B6 | src.code()); | 2283 0x5*B9 | B8 | 0x3*B6 | src.code()); |
2274 } | 2284 } |
2275 | 2285 |
2276 | 2286 |
2277 void Assembler::vadd(const DwVfpRegister dst, | 2287 void Assembler::vadd(const DwVfpRegister dst, |
2278 const DwVfpRegister src1, | 2288 const DwVfpRegister src1, |
2279 const DwVfpRegister src2, | 2289 const DwVfpRegister src2, |
2280 const Condition cond) { | 2290 const Condition cond) { |
2281 // Dd = vadd(Dn, Dm) double precision floating point addition. | 2291 // Dd = vadd(Dn, Dm) double precision floating point addition. |
2282 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2292 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2283 // Instruction details available in ARM DDI 0406A, A8-536. | 2293 // Instruction details available in ARM DDI 0406A, A8-536. |
2284 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | | 2294 // 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) | 2295 // 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)); | 2296 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2287 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2297 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
2288 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2298 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2289 } | 2299 } |
2290 | 2300 |
2291 | 2301 |
2292 void Assembler::vsub(const DwVfpRegister dst, | 2302 void Assembler::vsub(const DwVfpRegister dst, |
2293 const DwVfpRegister src1, | 2303 const DwVfpRegister src1, |
2294 const DwVfpRegister src2, | 2304 const DwVfpRegister src2, |
2295 const Condition cond) { | 2305 const Condition cond) { |
2296 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 2306 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
2297 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2307 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2298 // Instruction details available in ARM DDI 0406A, A8-784. | 2308 // Instruction details available in ARM DDI 0406A, A8-784. |
2299 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | | 2309 // 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) | 2310 // 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)); | 2311 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2302 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2312 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
2303 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2313 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
2304 } | 2314 } |
2305 | 2315 |
2306 | 2316 |
2307 void Assembler::vmul(const DwVfpRegister dst, | 2317 void Assembler::vmul(const DwVfpRegister dst, |
2308 const DwVfpRegister src1, | 2318 const DwVfpRegister src1, |
2309 const DwVfpRegister src2, | 2319 const DwVfpRegister src2, |
2310 const Condition cond) { | 2320 const Condition cond) { |
2311 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 2321 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
2312 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2322 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2313 // Instruction details available in ARM DDI 0406A, A8-784. | 2323 // Instruction details available in ARM DDI 0406A, A8-784. |
2314 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | | 2324 // 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) | 2325 // 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)); | 2326 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2317 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | | 2327 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | |
2318 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2328 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2319 } | 2329 } |
2320 | 2330 |
2321 | 2331 |
2322 void Assembler::vdiv(const DwVfpRegister dst, | 2332 void Assembler::vdiv(const DwVfpRegister dst, |
2323 const DwVfpRegister src1, | 2333 const DwVfpRegister src1, |
2324 const DwVfpRegister src2, | 2334 const DwVfpRegister src2, |
2325 const Condition cond) { | 2335 const Condition cond) { |
2326 // Dd = vdiv(Dn, Dm) double precision floating point division. | 2336 // Dd = vdiv(Dn, Dm) double precision floating point division. |
2327 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2337 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2328 // Instruction details available in ARM DDI 0406A, A8-584. | 2338 // Instruction details available in ARM DDI 0406A, A8-584. |
2329 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | | 2339 // 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) | 2340 // 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)); | 2341 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2332 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | | 2342 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | |
2333 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2343 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2334 } | 2344 } |
2335 | 2345 |
2336 | 2346 |
2337 void Assembler::vcmp(const DwVfpRegister src1, | 2347 void Assembler::vcmp(const DwVfpRegister src1, |
2338 const DwVfpRegister src2, | 2348 const DwVfpRegister src2, |
2339 const Condition cond) { | 2349 const Condition cond) { |
2340 // vcmp(Dd, Dm) double precision floating point comparison. | 2350 // vcmp(Dd, Dm) double precision floating point comparison. |
2341 // Instruction details available in ARM DDI 0406A, A8-570. | 2351 // Instruction details available in ARM DDI 0406A, A8-570. |
2342 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | | 2352 // 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) | 2353 // 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)); | 2354 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2345 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | | 2355 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | |
2346 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2356 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
2347 } | 2357 } |
2348 | 2358 |
2349 | 2359 |
2350 void Assembler::vcmp(const DwVfpRegister src1, | 2360 void Assembler::vcmp(const DwVfpRegister src1, |
2351 const double src2, | 2361 const double src2, |
2352 const Condition cond) { | 2362 const Condition cond) { |
2353 // vcmp(Dd, Dm) double precision floating point comparison. | 2363 // vcmp(Dd, Dm) double precision floating point comparison. |
2354 // Instruction details available in ARM DDI 0406A, A8-570. | 2364 // Instruction details available in ARM DDI 0406A, A8-570. |
2355 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | | 2365 // 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) | 2366 // 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)); | 2367 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2358 ASSERT(src2 == 0.0); | 2368 ASSERT(src2 == 0.0); |
2359 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | | 2369 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | |
2360 src1.code()*B12 | 0x5*B9 | B8 | B6); | 2370 src1.code()*B12 | 0x5*B9 | B8 | B6); |
2361 } | 2371 } |
2362 | 2372 |
2363 | 2373 |
2364 void Assembler::vmsr(Register dst, Condition cond) { | 2374 void Assembler::vmsr(Register dst, Condition cond) { |
2365 // Instruction details available in ARM DDI 0406A, A8-652. | 2375 // Instruction details available in ARM DDI 0406A, A8-652. |
2366 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | | 2376 // 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) | 2377 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2368 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2378 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2369 emit(cond | 0xE*B24 | 0xE*B20 | B16 | | 2379 emit(cond | 0xE*B24 | 0xE*B20 | B16 | |
2370 dst.code()*B12 | 0xA*B8 | B4); | 2380 dst.code()*B12 | 0xA*B8 | B4); |
2371 } | 2381 } |
2372 | 2382 |
2373 | 2383 |
2374 void Assembler::vmrs(Register dst, Condition cond) { | 2384 void Assembler::vmrs(Register dst, Condition cond) { |
2375 // Instruction details available in ARM DDI 0406A, A8-652. | 2385 // Instruction details available in ARM DDI 0406A, A8-652. |
2376 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | | 2386 // 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) | 2387 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2378 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2388 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2379 emit(cond | 0xE*B24 | 0xF*B20 | B16 | | 2389 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
2380 dst.code()*B12 | 0xA*B8 | B4); | 2390 dst.code()*B12 | 0xA*B8 | B4); |
2381 } | 2391 } |
2382 | 2392 |
2383 | 2393 |
2384 void Assembler::vsqrt(const DwVfpRegister dst, | 2394 void Assembler::vsqrt(const DwVfpRegister dst, |
2385 const DwVfpRegister src, | 2395 const DwVfpRegister src, |
2386 const Condition cond) { | 2396 const Condition cond) { |
2387 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | | 2397 // 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) | 2398 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) |
2389 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2399 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
2390 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | | 2400 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | |
2391 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); | 2401 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); |
2392 } | 2402 } |
2393 | 2403 |
2394 | 2404 |
2395 // Pseudo instructions. | 2405 // Pseudo instructions. |
2396 void Assembler::nop(int type) { | 2406 void Assembler::nop(int type) { |
2397 // This is mov rx, rx. | 2407 // This is mov rx, rx. |
2398 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. | 2408 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. |
2399 emit(al | 13*B21 | type*B12 | type); | 2409 emit(al | 13*B21 | type*B12 | type); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2671 | 2681 |
2672 // Since a constant pool was just emitted, move the check offset forward by | 2682 // Since a constant pool was just emitted, move the check offset forward by |
2673 // the standard interval. | 2683 // the standard interval. |
2674 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 2684 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
2675 } | 2685 } |
2676 | 2686 |
2677 | 2687 |
2678 } } // namespace v8::internal | 2688 } } // namespace v8::internal |
2679 | 2689 |
2680 #endif // V8_TARGET_ARCH_ARM | 2690 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |