Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(557)

Side by Side Diff: src/arm/assembler-arm.cc

Issue 10818026: Relax requirement from VFP3 to VFP2 where possible. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« build/common.gypi ('K') | « src/arm/assembler-arm.h ('k') | src/arm/builtins-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698