| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 supported_ |= 1u << ARMv7; | 114 supported_ |= 1u << ARMv7; |
| 115 } | 115 } |
| 116 | 116 |
| 117 if (FLAG_enable_sudiv) { | 117 if (FLAG_enable_sudiv) { |
| 118 supported_ |= 1u << SUDIV; | 118 supported_ |= 1u << SUDIV; |
| 119 } | 119 } |
| 120 | 120 |
| 121 if (FLAG_enable_movw_movt) { | 121 if (FLAG_enable_movw_movt) { |
| 122 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | 122 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
| 123 } | 123 } |
| 124 |
| 125 if (FLAG_enable_32dregs) { |
| 126 supported_ |= 1u << VFP32DREGS; |
| 127 } |
| 128 |
| 124 #else // __arm__ | 129 #else // __arm__ |
| 125 // Probe for additional features not already known to be available. | 130 // Probe for additional features not already known to be available. |
| 126 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { | 131 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { |
| 127 // This implementation also sets the VFP flags if runtime | 132 // This implementation also sets the VFP flags if runtime |
| 128 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI | 133 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI |
| 129 // 0406B, page A1-6. | 134 // 0406B, page A1-6. |
| 130 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; | 135 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; |
| 131 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { | 136 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { |
| 132 found_by_runtime_probing_ |= 1u << VFP2; | 137 found_by_runtime_probing_ |= 1u << VFP2; |
| 133 } | 138 } |
| 134 | 139 |
| 135 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { | 140 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { |
| 136 found_by_runtime_probing_ |= 1u << ARMv7; | 141 found_by_runtime_probing_ |= 1u << ARMv7; |
| 137 } | 142 } |
| 138 | 143 |
| 139 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { | 144 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { |
| 140 found_by_runtime_probing_ |= 1u << SUDIV; | 145 found_by_runtime_probing_ |= 1u << SUDIV; |
| 141 } | 146 } |
| 142 | 147 |
| 143 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { | 148 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { |
| 144 found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES; | 149 found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES; |
| 145 } | 150 } |
| 146 | 151 |
| 147 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && | 152 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && |
| 148 OS::ArmCpuHasFeature(ARMv7)) { | 153 OS::ArmCpuHasFeature(ARMv7)) { |
| 149 found_by_runtime_probing_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | 154 found_by_runtime_probing_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
| 150 } | 155 } |
| 151 | 156 |
| 157 if (!IsSupported(VFP32DREGS) && OS::ArmCpuHasFeature(VFP32DREGS)) { |
| 158 found_by_runtime_probing_ |= 1u << VFP32DREGS; |
| 159 } |
| 160 |
| 152 supported_ |= found_by_runtime_probing_; | 161 supported_ |= found_by_runtime_probing_; |
| 153 #endif | 162 #endif |
| 154 | 163 |
| 155 // Assert that VFP3 implies VFP2 and ARMv7. | 164 // Assert that VFP3 implies VFP2 and ARMv7. |
| 156 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); | 165 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); |
| 157 } | 166 } |
| 158 | 167 |
| 159 | 168 |
| 160 // ----------------------------------------------------------------------------- | 169 // ----------------------------------------------------------------------------- |
| 161 // Implementation of RelocInfo | 170 // Implementation of RelocInfo |
| (...skipping 1511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1673 } | 1682 } |
| 1674 | 1683 |
| 1675 | 1684 |
| 1676 // Support for VFP. | 1685 // Support for VFP. |
| 1677 | 1686 |
| 1678 void Assembler::vldr(const DwVfpRegister dst, | 1687 void Assembler::vldr(const DwVfpRegister dst, |
| 1679 const Register base, | 1688 const Register base, |
| 1680 int offset, | 1689 int offset, |
| 1681 const Condition cond) { | 1690 const Condition cond) { |
| 1682 // Ddst = MEM(Rbase + offset). | 1691 // Ddst = MEM(Rbase + offset). |
| 1683 // Instruction details available in ARM DDI 0406A, A8-628. | 1692 // Instruction details available in ARM DDI 0406C.b, A8-924. |
| 1684 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1693 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | |
| 1685 // Vdst(15-12) | 1011(11-8) | offset | 1694 // Vd(15-12) | 1011(11-8) | offset |
| 1686 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1695 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 1687 int u = 1; | 1696 int u = 1; |
| 1688 if (offset < 0) { | 1697 if (offset < 0) { |
| 1689 offset = -offset; | 1698 offset = -offset; |
| 1690 u = 0; | 1699 u = 0; |
| 1691 } | 1700 } |
| 1701 int vd, d; |
| 1702 dst.split_code(&vd, &d); |
| 1692 | 1703 |
| 1693 ASSERT(offset >= 0); | 1704 ASSERT(offset >= 0); |
| 1694 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1705 if ((offset % 4) == 0 && (offset / 4) < 256) { |
| 1695 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | | 1706 emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 | |
| 1696 0xB*B8 | ((offset / 4) & 255)); | 1707 0xB*B8 | ((offset / 4) & 255)); |
| 1697 } else { | 1708 } else { |
| 1698 // Larger offsets must be handled by computing the correct address | 1709 // Larger offsets must be handled by computing the correct address |
| 1699 // in the ip register. | 1710 // in the ip register. |
| 1700 ASSERT(!base.is(ip)); | 1711 ASSERT(!base.is(ip)); |
| 1701 if (u == 1) { | 1712 if (u == 1) { |
| 1702 add(ip, base, Operand(offset)); | 1713 add(ip, base, Operand(offset)); |
| 1703 } else { | 1714 } else { |
| 1704 sub(ip, base, Operand(offset)); | 1715 sub(ip, base, Operand(offset)); |
| 1705 } | 1716 } |
| 1706 emit(cond | 0xD1*B20 | ip.code()*B16 | dst.code()*B12 | 0xB*B8); | 1717 emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8); |
| 1707 } | 1718 } |
| 1708 } | 1719 } |
| 1709 | 1720 |
| 1710 | 1721 |
| 1711 void Assembler::vldr(const DwVfpRegister dst, | 1722 void Assembler::vldr(const DwVfpRegister dst, |
| 1712 const MemOperand& operand, | 1723 const MemOperand& operand, |
| 1713 const Condition cond) { | 1724 const Condition cond) { |
| 1714 ASSERT(!operand.rm().is_valid()); | 1725 ASSERT(!operand.rm().is_valid()); |
| 1715 ASSERT(operand.am_ == Offset); | 1726 ASSERT(operand.am_ == Offset); |
| 1716 vldr(dst, operand.rn(), operand.offset(), cond); | 1727 vldr(dst, operand.rn(), operand.offset(), cond); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1759 ASSERT(operand.am_ == Offset); | 1770 ASSERT(operand.am_ == Offset); |
| 1760 vldr(dst, operand.rn(), operand.offset(), cond); | 1771 vldr(dst, operand.rn(), operand.offset(), cond); |
| 1761 } | 1772 } |
| 1762 | 1773 |
| 1763 | 1774 |
| 1764 void Assembler::vstr(const DwVfpRegister src, | 1775 void Assembler::vstr(const DwVfpRegister src, |
| 1765 const Register base, | 1776 const Register base, |
| 1766 int offset, | 1777 int offset, |
| 1767 const Condition cond) { | 1778 const Condition cond) { |
| 1768 // MEM(Rbase + offset) = Dsrc. | 1779 // MEM(Rbase + offset) = Dsrc. |
| 1769 // Instruction details available in ARM DDI 0406A, A8-786. | 1780 // Instruction details available in ARM DDI 0406C.b, A8-1082. |
| 1770 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | | 1781 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | |
| 1771 // Vsrc(15-12) | 1011(11-8) | (offset/4) | 1782 // Vd(15-12) | 1011(11-8) | (offset/4) |
| 1772 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1783 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 1773 int u = 1; | 1784 int u = 1; |
| 1774 if (offset < 0) { | 1785 if (offset < 0) { |
| 1775 offset = -offset; | 1786 offset = -offset; |
| 1776 u = 0; | 1787 u = 0; |
| 1777 } | 1788 } |
| 1778 ASSERT(offset >= 0); | 1789 ASSERT(offset >= 0); |
| 1790 int vd, d; |
| 1791 src.split_code(&vd, &d); |
| 1792 |
| 1779 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1793 if ((offset % 4) == 0 && (offset / 4) < 256) { |
| 1780 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | | 1794 emit(cond | 0xD*B24 | u*B23 | d*B22 | base.code()*B16 | vd*B12 | 0xB*B8 | |
| 1781 0xB*B8 | ((offset / 4) & 255)); | 1795 ((offset / 4) & 255)); |
| 1782 } else { | 1796 } else { |
| 1783 // Larger offsets must be handled by computing the correct address | 1797 // Larger offsets must be handled by computing the correct address |
| 1784 // in the ip register. | 1798 // in the ip register. |
| 1785 ASSERT(!base.is(ip)); | 1799 ASSERT(!base.is(ip)); |
| 1786 if (u == 1) { | 1800 if (u == 1) { |
| 1787 add(ip, base, Operand(offset)); | 1801 add(ip, base, Operand(offset)); |
| 1788 } else { | 1802 } else { |
| 1789 sub(ip, base, Operand(offset)); | 1803 sub(ip, base, Operand(offset)); |
| 1790 } | 1804 } |
| 1791 emit(cond | 0xD0*B20 | ip.code()*B16 | src.code()*B12 | 0xB*B8); | 1805 emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8); |
| 1792 } | 1806 } |
| 1793 } | 1807 } |
| 1794 | 1808 |
| 1795 | 1809 |
| 1796 void Assembler::vstr(const DwVfpRegister src, | 1810 void Assembler::vstr(const DwVfpRegister src, |
| 1797 const MemOperand& operand, | 1811 const MemOperand& operand, |
| 1798 const Condition cond) { | 1812 const Condition cond) { |
| 1799 ASSERT(!operand.rm().is_valid()); | 1813 ASSERT(!operand.rm().is_valid()); |
| 1800 ASSERT(operand.am_ == Offset); | 1814 ASSERT(operand.am_ == Offset); |
| 1801 vstr(src, operand.rn(), operand.offset(), cond); | 1815 vstr(src, operand.rn(), operand.offset(), cond); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1843 ASSERT(operand.am_ == Offset); | 1857 ASSERT(operand.am_ == Offset); |
| 1844 vstr(src, operand.rn(), operand.offset(), cond); | 1858 vstr(src, operand.rn(), operand.offset(), cond); |
| 1845 } | 1859 } |
| 1846 | 1860 |
| 1847 | 1861 |
| 1848 void Assembler::vldm(BlockAddrMode am, | 1862 void Assembler::vldm(BlockAddrMode am, |
| 1849 Register base, | 1863 Register base, |
| 1850 DwVfpRegister first, | 1864 DwVfpRegister first, |
| 1851 DwVfpRegister last, | 1865 DwVfpRegister last, |
| 1852 Condition cond) { | 1866 Condition cond) { |
| 1853 // Instruction details available in ARM DDI 0406A, A8-626. | 1867 // Instruction details available in ARM DDI 0406C.b, A8-922. |
| 1854 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1868 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
| 1855 // first(15-12) | 1010(11-8) | (count * 2) | 1869 // first(15-12) | 1011(11-8) | (count * 2) |
| 1856 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1870 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 1857 ASSERT_LE(first.code(), last.code()); | 1871 ASSERT_LE(first.code(), last.code()); |
| 1858 ASSERT(am == ia || am == ia_w || am == db_w); | 1872 ASSERT(am == ia || am == ia_w || am == db_w); |
| 1859 ASSERT(!base.is(pc)); | 1873 ASSERT(!base.is(pc)); |
| 1860 | 1874 |
| 1861 int sd, d; | 1875 int sd, d; |
| 1862 first.split_code(&sd, &d); | 1876 first.split_code(&sd, &d); |
| 1863 int count = last.code() - first.code() + 1; | 1877 int count = last.code() - first.code() + 1; |
| 1864 ASSERT(count <= 16); | 1878 ASSERT(count <= 16); |
| 1865 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1879 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
| 1866 0xB*B8 | count*2); | 1880 0xB*B8 | count*2); |
| 1867 } | 1881 } |
| 1868 | 1882 |
| 1869 | 1883 |
| 1870 void Assembler::vstm(BlockAddrMode am, | 1884 void Assembler::vstm(BlockAddrMode am, |
| 1871 Register base, | 1885 Register base, |
| 1872 DwVfpRegister first, | 1886 DwVfpRegister first, |
| 1873 DwVfpRegister last, | 1887 DwVfpRegister last, |
| 1874 Condition cond) { | 1888 Condition cond) { |
| 1875 // Instruction details available in ARM DDI 0406A, A8-784. | 1889 // Instruction details available in ARM DDI 0406C.b, A8-1080. |
| 1876 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 1890 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
| 1877 // first(15-12) | 1011(11-8) | (count * 2) | 1891 // first(15-12) | 1011(11-8) | (count * 2) |
| 1878 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1892 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 1879 ASSERT_LE(first.code(), last.code()); | 1893 ASSERT_LE(first.code(), last.code()); |
| 1880 ASSERT(am == ia || am == ia_w || am == db_w); | 1894 ASSERT(am == ia || am == ia_w || am == db_w); |
| 1881 ASSERT(!base.is(pc)); | 1895 ASSERT(!base.is(pc)); |
| 1882 | 1896 |
| 1883 int sd, d; | 1897 int sd, d; |
| 1884 first.split_code(&sd, &d); | 1898 first.split_code(&sd, &d); |
| 1885 int count = last.code() - first.code() + 1; | 1899 int count = last.code() - first.code() + 1; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1985 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. | 1999 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. |
| 1986 | 2000 |
| 1987 return true; | 2001 return true; |
| 1988 } | 2002 } |
| 1989 | 2003 |
| 1990 | 2004 |
| 1991 void Assembler::vmov(const DwVfpRegister dst, | 2005 void Assembler::vmov(const DwVfpRegister dst, |
| 1992 double imm, | 2006 double imm, |
| 1993 const Register scratch, | 2007 const Register scratch, |
| 1994 const Condition cond) { | 2008 const Condition cond) { |
| 1995 // Dd = immediate | |
| 1996 // Instruction details available in ARM DDI 0406B, A8-640. | |
| 1997 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2009 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 1998 | 2010 |
| 1999 uint32_t enc; | 2011 uint32_t enc; |
| 2000 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { | 2012 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { |
| 2001 // The double can be encoded in the instruction. | 2013 // The double can be encoded in the instruction. |
| 2002 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); | 2014 |
| 2015 // Dd = immediate |
| 2016 // Instruction details available in ARM DDI 0406C.b, A8-936. |
| 2017 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
| 2018 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) |
| 2019 int vd, d; |
| 2020 dst.split_code(&vd, &d); |
| 2021 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); |
| 2003 } else { | 2022 } else { |
| 2004 // Synthesise the double from ARM immediates. This could be implemented | 2023 // Synthesise the double from ARM immediates. This could be implemented |
| 2005 // using vldr from a constant pool. | 2024 // using vldr from a constant pool. |
| 2006 uint32_t lo, hi; | 2025 uint32_t lo, hi; |
| 2007 DoubleAsTwoUInt32(imm, &lo, &hi); | 2026 DoubleAsTwoUInt32(imm, &lo, &hi); |
| 2008 mov(ip, Operand(lo)); | 2027 mov(ip, Operand(lo)); |
| 2009 | 2028 |
| 2010 if (scratch.is(no_reg)) { | 2029 if (scratch.is(no_reg)) { |
| 2011 // Move the low part of the double into the lower of the corresponsing S | 2030 // Move the low and high part separately using vmov.32. |
| 2012 // registers of D register dst. | 2031 vmov(dst, 0, ip, cond); |
| 2013 vmov(dst.low(), ip, cond); | |
| 2014 | |
| 2015 // Move the high part of the double into the higher of the corresponsing S | |
| 2016 // registers of D register dst. | |
| 2017 mov(ip, Operand(hi)); | 2032 mov(ip, Operand(hi)); |
| 2018 vmov(dst.high(), ip, cond); | 2033 vmov(dst, 1, ip, cond); |
| 2019 } else { | 2034 } else { |
| 2020 // Move the low and high parts of the double to a D register in one | 2035 // Move the low and high parts of the double to a D register in one |
| 2021 // instruction. | 2036 // instruction. |
| 2022 mov(scratch, Operand(hi)); | 2037 mov(scratch, Operand(hi)); |
| 2023 vmov(dst, ip, scratch, cond); | 2038 vmov(dst, ip, scratch, cond); |
| 2024 } | 2039 } |
| 2025 } | 2040 } |
| 2026 } | 2041 } |
| 2027 | 2042 |
| 2028 | 2043 |
| 2029 void Assembler::vmov(const SwVfpRegister dst, | 2044 void Assembler::vmov(const SwVfpRegister dst, |
| 2030 const SwVfpRegister src, | 2045 const SwVfpRegister src, |
| 2031 const Condition cond) { | 2046 const Condition cond) { |
| 2032 // Sd = Sm | 2047 // Sd = Sm |
| 2033 // Instruction details available in ARM DDI 0406B, A8-642. | 2048 // Instruction details available in ARM DDI 0406B, A8-642. |
| 2034 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2049 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2035 int sd, d, sm, m; | 2050 int sd, d, sm, m; |
| 2036 dst.split_code(&sd, &d); | 2051 dst.split_code(&sd, &d); |
| 2037 src.split_code(&sm, &m); | 2052 src.split_code(&sm, &m); |
| 2038 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); | 2053 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); |
| 2039 } | 2054 } |
| 2040 | 2055 |
| 2041 | 2056 |
| 2042 void Assembler::vmov(const DwVfpRegister dst, | 2057 void Assembler::vmov(const DwVfpRegister dst, |
| 2043 const DwVfpRegister src, | 2058 const DwVfpRegister src, |
| 2044 const Condition cond) { | 2059 const Condition cond) { |
| 2045 // Dd = Dm | 2060 // Dd = Dm |
| 2046 // Instruction details available in ARM DDI 0406B, A8-642. | 2061 // Instruction details available in ARM DDI 0406C.b, A8-938. |
| 2062 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
| 2063 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2047 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2064 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2048 emit(cond | 0xE*B24 | 0xB*B20 | | 2065 int vd, d; |
| 2049 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); | 2066 dst.split_code(&vd, &d); |
| 2067 int vm, m; |
| 2068 src.split_code(&vm, &m); |
| 2069 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | |
| 2070 vm); |
| 2050 } | 2071 } |
| 2051 | 2072 |
| 2052 | 2073 |
| 2074 void Assembler::vmov(const DwVfpRegister dst, |
| 2075 int index, |
| 2076 const Register src, |
| 2077 const Condition cond) { |
| 2078 // Dd[index] = Rt |
| 2079 // Instruction details available in ARM DDI 0406C.b, A8-940. |
| 2080 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | |
| 2081 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) |
| 2082 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2083 ASSERT(index == 0 || index == 1); |
| 2084 int vd, d; |
| 2085 dst.split_code(&vd, &d); |
| 2086 emit(cond | 0xE*B24 | index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | d*B7 | |
| 2087 B4); |
| 2088 } |
| 2089 |
| 2090 |
| 2053 void Assembler::vmov(const DwVfpRegister dst, | 2091 void Assembler::vmov(const DwVfpRegister dst, |
| 2054 const Register src1, | 2092 const Register src1, |
| 2055 const Register src2, | 2093 const Register src2, |
| 2056 const Condition cond) { | 2094 const Condition cond) { |
| 2057 // Dm = <Rt,Rt2>. | 2095 // Dm = <Rt,Rt2>. |
| 2058 // Instruction details available in ARM DDI 0406A, A8-646. | 2096 // Instruction details available in ARM DDI 0406C.b, A8-948. |
| 2059 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | | 2097 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
| 2060 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2098 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| 2061 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2099 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2062 ASSERT(!src1.is(pc) && !src2.is(pc)); | 2100 ASSERT(!src1.is(pc) && !src2.is(pc)); |
| 2101 int vm, m; |
| 2102 dst.split_code(&vm, &m); |
| 2063 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2103 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
| 2064 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); | 2104 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
| 2065 } | 2105 } |
| 2066 | 2106 |
| 2067 | 2107 |
| 2068 void Assembler::vmov(const Register dst1, | 2108 void Assembler::vmov(const Register dst1, |
| 2069 const Register dst2, | 2109 const Register dst2, |
| 2070 const DwVfpRegister src, | 2110 const DwVfpRegister src, |
| 2071 const Condition cond) { | 2111 const Condition cond) { |
| 2072 // <Rt,Rt2> = Dm. | 2112 // <Rt,Rt2> = Dm. |
| 2073 // Instruction details available in ARM DDI 0406A, A8-646. | 2113 // Instruction details available in ARM DDI 0406C.b, A8-948. |
| 2074 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | | 2114 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
| 2075 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2115 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| 2076 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2116 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2077 ASSERT(!dst1.is(pc) && !dst2.is(pc)); | 2117 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
| 2118 int vm, m; |
| 2119 src.split_code(&vm, &m); |
| 2078 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2120 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
| 2079 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); | 2121 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
| 2080 } | 2122 } |
| 2081 | 2123 |
| 2082 | 2124 |
| 2083 void Assembler::vmov(const SwVfpRegister dst, | 2125 void Assembler::vmov(const SwVfpRegister dst, |
| 2084 const Register src, | 2126 const Register src, |
| 2085 const Condition cond) { | 2127 const Condition cond) { |
| 2086 // Sn = Rt. | 2128 // Sn = Rt. |
| 2087 // Instruction details available in ARM DDI 0406A, A8-642. | 2129 // Instruction details available in ARM DDI 0406A, A8-642. |
| 2088 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | | 2130 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
| 2089 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2131 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 VFPConversionMode mode, | 2324 VFPConversionMode mode, |
| 2283 const Condition cond) { | 2325 const Condition cond) { |
| 2284 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2326 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2285 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 2327 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
| 2286 } | 2328 } |
| 2287 | 2329 |
| 2288 | 2330 |
| 2289 void Assembler::vneg(const DwVfpRegister dst, | 2331 void Assembler::vneg(const DwVfpRegister dst, |
| 2290 const DwVfpRegister src, | 2332 const DwVfpRegister src, |
| 2291 const Condition cond) { | 2333 const Condition cond) { |
| 2334 // Instruction details available in ARM DDI 0406C.b, A8-968. |
| 2335 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | |
| 2336 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2292 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2337 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2293 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | | 2338 int vd, d; |
| 2294 0x5*B9 | B8 | B6 | src.code()); | 2339 dst.split_code(&vd, &d); |
| 2340 int vm, m; |
| 2341 src.split_code(&vm, &m); |
| 2342 |
| 2343 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
| 2344 m*B5 | vm); |
| 2295 } | 2345 } |
| 2296 | 2346 |
| 2297 | 2347 |
| 2298 void Assembler::vabs(const DwVfpRegister dst, | 2348 void Assembler::vabs(const DwVfpRegister dst, |
| 2299 const DwVfpRegister src, | 2349 const DwVfpRegister src, |
| 2300 const Condition cond) { | 2350 const Condition cond) { |
| 2351 // Instruction details available in ARM DDI 0406C.b, A8-524. |
| 2352 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
| 2353 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2301 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2354 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2302 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | | 2355 int vd, d; |
| 2303 0x5*B9 | B8 | 0x3*B6 | src.code()); | 2356 dst.split_code(&vd, &d); |
| 2357 int vm, m; |
| 2358 src.split_code(&vm, &m); |
| 2359 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | |
| 2360 m*B5 | vm); |
| 2304 } | 2361 } |
| 2305 | 2362 |
| 2306 | 2363 |
| 2307 void Assembler::vadd(const DwVfpRegister dst, | 2364 void Assembler::vadd(const DwVfpRegister dst, |
| 2308 const DwVfpRegister src1, | 2365 const DwVfpRegister src1, |
| 2309 const DwVfpRegister src2, | 2366 const DwVfpRegister src2, |
| 2310 const Condition cond) { | 2367 const Condition cond) { |
| 2311 // Dd = vadd(Dn, Dm) double precision floating point addition. | 2368 // Dd = vadd(Dn, Dm) double precision floating point addition. |
| 2312 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2369 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 2313 // Instruction details available in ARM DDI 0406A, A8-536. | 2370 // Instruction details available in ARM DDI 0406C.b, A8-830. |
| 2314 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | | 2371 // cond(31-28) | 11100(27-23)| D(22) | 11(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) | 2372 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| 2316 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2373 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2317 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2374 int vd, d; |
| 2318 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2375 dst.split_code(&vd, &d); |
| 2376 int vn, n; |
| 2377 src1.split_code(&vn, &n); |
| 2378 int vm, m; |
| 2379 src2.split_code(&vm, &m); |
| 2380 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
| 2381 n*B7 | m*B5 | vm); |
| 2319 } | 2382 } |
| 2320 | 2383 |
| 2321 | 2384 |
| 2322 void Assembler::vsub(const DwVfpRegister dst, | 2385 void Assembler::vsub(const DwVfpRegister dst, |
| 2323 const DwVfpRegister src1, | 2386 const DwVfpRegister src1, |
| 2324 const DwVfpRegister src2, | 2387 const DwVfpRegister src2, |
| 2325 const Condition cond) { | 2388 const Condition cond) { |
| 2326 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 2389 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
| 2327 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2390 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 2328 // Instruction details available in ARM DDI 0406A, A8-784. | 2391 // Instruction details available in ARM DDI 0406C.b, A8-1086. |
| 2329 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | | 2392 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
| 2330 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) | 2393 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2331 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2394 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2332 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2395 int vd, d; |
| 2333 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2396 dst.split_code(&vd, &d); |
| 2397 int vn, n; |
| 2398 src1.split_code(&vn, &n); |
| 2399 int vm, m; |
| 2400 src2.split_code(&vm, &m); |
| 2401 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
| 2402 n*B7 | B6 | m*B5 | vm); |
| 2334 } | 2403 } |
| 2335 | 2404 |
| 2336 | 2405 |
| 2337 void Assembler::vmul(const DwVfpRegister dst, | 2406 void Assembler::vmul(const DwVfpRegister dst, |
| 2338 const DwVfpRegister src1, | 2407 const DwVfpRegister src1, |
| 2339 const DwVfpRegister src2, | 2408 const DwVfpRegister src2, |
| 2340 const Condition cond) { | 2409 const Condition cond) { |
| 2341 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 2410 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
| 2342 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2411 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 2343 // Instruction details available in ARM DDI 0406A, A8-784. | 2412 // Instruction details available in ARM DDI 0406C.b, A8-960. |
| 2344 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | | 2413 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | |
| 2345 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) | 2414 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| 2346 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2415 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2347 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | | 2416 int vd, d; |
| 2348 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2417 dst.split_code(&vd, &d); |
| 2418 int vn, n; |
| 2419 src1.split_code(&vn, &n); |
| 2420 int vm, m; |
| 2421 src2.split_code(&vm, &m); |
| 2422 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
| 2423 n*B7 | m*B5 | vm); |
| 2349 } | 2424 } |
| 2350 | 2425 |
| 2351 | 2426 |
| 2352 void Assembler::vmla(const DwVfpRegister dst, | 2427 void Assembler::vmla(const DwVfpRegister dst, |
| 2353 const DwVfpRegister src1, | 2428 const DwVfpRegister src1, |
| 2354 const DwVfpRegister src2, | 2429 const DwVfpRegister src2, |
| 2355 const Condition cond) { | 2430 const Condition cond) { |
| 2356 // Instruction details available in ARM DDI 0406C.b, A8-892. | 2431 // Instruction details available in ARM DDI 0406C.b, A8-932. |
| 2357 // cond(31-28) | 11100(27-23) | D=?(22) | 00(21-20) | Vn(19-16) | | 2432 // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
| 2358 // Vd(15-12) | 101(11-9) | sz(8)=1 | N=?(7) | op(6)=0 | M=?(5) | 0(4) | | 2433 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0) |
| 2359 // Vm(3-0) | 2434 int vd, d; |
| 2360 unsigned x = (cond | 0x1C*B23 | src1.code()*B16 | | 2435 dst.split_code(&vd, &d); |
| 2361 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2436 int vn, n; |
| 2362 emit(x); | 2437 src1.split_code(&vn, &n); |
| 2438 int vm, m; |
| 2439 src2.split_code(&vm, &m); |
| 2440 emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
| 2441 vm); |
| 2363 } | 2442 } |
| 2364 | 2443 |
| 2365 | 2444 |
| 2366 void Assembler::vdiv(const DwVfpRegister dst, | 2445 void Assembler::vdiv(const DwVfpRegister dst, |
| 2367 const DwVfpRegister src1, | 2446 const DwVfpRegister src1, |
| 2368 const DwVfpRegister src2, | 2447 const DwVfpRegister src2, |
| 2369 const Condition cond) { | 2448 const Condition cond) { |
| 2370 // Dd = vdiv(Dn, Dm) double precision floating point division. | 2449 // Dd = vdiv(Dn, Dm) double precision floating point division. |
| 2371 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2450 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 2372 // Instruction details available in ARM DDI 0406A, A8-584. | 2451 // Instruction details available in ARM DDI 0406C.b, A8-882. |
| 2373 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | | 2452 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | |
| 2374 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) | 2453 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| 2375 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2454 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2376 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | | 2455 int vd, d; |
| 2377 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2456 dst.split_code(&vd, &d); |
| 2457 int vn, n; |
| 2458 src1.split_code(&vn, &n); |
| 2459 int vm, m; |
| 2460 src2.split_code(&vm, &m); |
| 2461 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
| 2462 vm); |
| 2378 } | 2463 } |
| 2379 | 2464 |
| 2380 | 2465 |
| 2381 void Assembler::vcmp(const DwVfpRegister src1, | 2466 void Assembler::vcmp(const DwVfpRegister src1, |
| 2382 const DwVfpRegister src2, | 2467 const DwVfpRegister src2, |
| 2383 const Condition cond) { | 2468 const Condition cond) { |
| 2384 // vcmp(Dd, Dm) double precision floating point comparison. | 2469 // vcmp(Dd, Dm) double precision floating point comparison. |
| 2385 // Instruction details available in ARM DDI 0406A, A8-570. | 2470 // Instruction details available in ARM DDI 0406C.b, A8-864. |
| 2386 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | | 2471 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | |
| 2387 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) | 2472 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2388 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2473 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2389 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | | 2474 int vd, d; |
| 2390 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2475 src1.split_code(&vd, &d); |
| 2476 int vm, m; |
| 2477 src2.split_code(&vm, &m); |
| 2478 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
| 2479 m*B5 | vm); |
| 2391 } | 2480 } |
| 2392 | 2481 |
| 2393 | 2482 |
| 2394 void Assembler::vcmp(const DwVfpRegister src1, | 2483 void Assembler::vcmp(const DwVfpRegister src1, |
| 2395 const double src2, | 2484 const double src2, |
| 2396 const Condition cond) { | 2485 const Condition cond) { |
| 2397 // vcmp(Dd, Dm) double precision floating point comparison. | 2486 // vcmp(Dd, #0.0) double precision floating point comparison. |
| 2398 // Instruction details available in ARM DDI 0406A, A8-570. | 2487 // Instruction details available in ARM DDI 0406C.b, A8-864. |
| 2399 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | | 2488 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | |
| 2400 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) | 2489 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) |
| 2401 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2490 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2402 ASSERT(src2 == 0.0); | 2491 ASSERT(src2 == 0.0); |
| 2403 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | | 2492 int vd, d; |
| 2404 src1.code()*B12 | 0x5*B9 | B8 | B6); | 2493 src1.split_code(&vd, &d); |
| 2494 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); |
| 2405 } | 2495 } |
| 2406 | 2496 |
| 2407 | 2497 |
| 2408 void Assembler::vmsr(Register dst, Condition cond) { | 2498 void Assembler::vmsr(Register dst, Condition cond) { |
| 2409 // Instruction details available in ARM DDI 0406A, A8-652. | 2499 // Instruction details available in ARM DDI 0406A, A8-652. |
| 2410 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | | 2500 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | |
| 2411 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2501 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
| 2412 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2502 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2413 emit(cond | 0xE*B24 | 0xE*B20 | B16 | | 2503 emit(cond | 0xE*B24 | 0xE*B20 | B16 | |
| 2414 dst.code()*B12 | 0xA*B8 | B4); | 2504 dst.code()*B12 | 0xA*B8 | B4); |
| 2415 } | 2505 } |
| 2416 | 2506 |
| 2417 | 2507 |
| 2418 void Assembler::vmrs(Register dst, Condition cond) { | 2508 void Assembler::vmrs(Register dst, Condition cond) { |
| 2419 // Instruction details available in ARM DDI 0406A, A8-652. | 2509 // Instruction details available in ARM DDI 0406A, A8-652. |
| 2420 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | | 2510 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
| 2421 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2511 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
| 2422 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2512 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2423 emit(cond | 0xE*B24 | 0xF*B20 | B16 | | 2513 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
| 2424 dst.code()*B12 | 0xA*B8 | B4); | 2514 dst.code()*B12 | 0xA*B8 | B4); |
| 2425 } | 2515 } |
| 2426 | 2516 |
| 2427 | 2517 |
| 2428 void Assembler::vsqrt(const DwVfpRegister dst, | 2518 void Assembler::vsqrt(const DwVfpRegister dst, |
| 2429 const DwVfpRegister src, | 2519 const DwVfpRegister src, |
| 2430 const Condition cond) { | 2520 const Condition cond) { |
| 2431 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | | 2521 // Instruction details available in ARM DDI 0406C.b, A8-1058. |
| 2432 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) | 2522 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | |
| 2523 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) |
| 2433 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2524 ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| 2434 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | | 2525 int vd, d; |
| 2435 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); | 2526 dst.split_code(&vd, &d); |
| 2527 int vm, m; |
| 2528 src.split_code(&vm, &m); |
| 2529 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | |
| 2530 m*B5 | vm); |
| 2436 } | 2531 } |
| 2437 | 2532 |
| 2438 | 2533 |
| 2439 // Pseudo instructions. | 2534 // Pseudo instructions. |
| 2440 void Assembler::nop(int type) { | 2535 void Assembler::nop(int type) { |
| 2441 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes | 2536 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes |
| 2442 // some of the CPU's pipeline and has to issue. Older ARM chips simply used | 2537 // some of the CPU's pipeline and has to issue. Older ARM chips simply used |
| 2443 // MOV Rx, Rx as NOP and it performs better even in newer CPUs. | 2538 // MOV Rx, Rx as NOP and it performs better even in newer CPUs. |
| 2444 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode | 2539 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode |
| 2445 // a type. | 2540 // a type. |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2743 | 2838 |
| 2744 // Since a constant pool was just emitted, move the check offset forward by | 2839 // Since a constant pool was just emitted, move the check offset forward by |
| 2745 // the standard interval. | 2840 // the standard interval. |
| 2746 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 2841 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
| 2747 } | 2842 } |
| 2748 | 2843 |
| 2749 | 2844 |
| 2750 } } // namespace v8::internal | 2845 } } // namespace v8::internal |
| 2751 | 2846 |
| 2752 #endif // V8_TARGET_ARCH_ARM | 2847 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |