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