| 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 1791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 void Assembler::stc2(Coprocessor coproc, | 1802 void Assembler::stc2(Coprocessor coproc, |
| 1803 CRegister crd, | 1803 CRegister crd, |
| 1804 Register rn, | 1804 Register rn, |
| 1805 int option, | 1805 int option, |
| 1806 LFlag l) { // v5 and above | 1806 LFlag l) { // v5 and above |
| 1807 stc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); | 1807 stc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); |
| 1808 } | 1808 } |
| 1809 | 1809 |
| 1810 | 1810 |
| 1811 // Support for VFP. | 1811 // Support for VFP. |
| 1812 |
| 1812 void Assembler::vldr(const DwVfpRegister dst, | 1813 void Assembler::vldr(const DwVfpRegister dst, |
| 1813 const Register base, | 1814 const Register base, |
| 1814 int offset, | 1815 int offset, |
| 1815 const Condition cond) { | 1816 const Condition cond) { |
| 1816 // Ddst = MEM(Rbase + offset). | 1817 // Ddst = MEM(Rbase + offset). |
| 1817 // Instruction details available in ARM DDI 0406A, A8-628. | 1818 // Instruction details available in ARM DDI 0406A, A8-628. |
| 1818 // cond(31-28) | 1101(27-24)| 1001(23-20) | Rbase(19-16) | | 1819 // cond(31-28) | 1101(27-24)| 1001(23-20) | Rbase(19-16) | |
| 1819 // Vdst(15-12) | 1011(11-8) | offset | 1820 // Vdst(15-12) | 1011(11-8) | offset |
| 1820 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1821 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 1821 ASSERT(offset % 4 == 0); | 1822 ASSERT(offset % 4 == 0); |
| 1822 ASSERT((offset / 4) < 256); | 1823 ASSERT((offset / 4) < 256); |
| 1823 ASSERT(offset >= 0); | 1824 ASSERT(offset >= 0); |
| 1824 emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 | | 1825 emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 | |
| 1825 0xB*B8 | ((offset / 4) & 255)); | 1826 0xB*B8 | ((offset / 4) & 255)); |
| 1826 } | 1827 } |
| 1827 | 1828 |
| 1828 | 1829 |
| 1829 void Assembler::vldr(const SwVfpRegister dst, | 1830 void Assembler::vldr(const SwVfpRegister dst, |
| 1830 const Register base, | 1831 const Register base, |
| 1831 int offset, | 1832 int offset, |
| 1832 const Condition cond) { | 1833 const Condition cond) { |
| 1833 // Sdst = MEM(Rbase + offset). | 1834 // Sdst = MEM(Rbase + offset). |
| 1834 // Instruction details available in ARM DDI 0406A, A8-628. | 1835 // Instruction details available in ARM DDI 0406A, A8-628. |
| 1835 // cond(31-28) | 1101(27-24)| 1001(23-20) | Rbase(19-16) | | 1836 // cond(31-28) | 1101(27-24)| 1001(23-20) | Rbase(19-16) | |
| 1836 // Vdst(15-12) | 1010(11-8) | offset | 1837 // Vdst(15-12) | 1010(11-8) | offset |
| 1837 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1838 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 1838 ASSERT(offset % 4 == 0); | 1839 ASSERT(offset % 4 == 0); |
| 1839 ASSERT((offset / 4) < 256); | 1840 ASSERT((offset / 4) < 256); |
| 1840 ASSERT(offset >= 0); | 1841 ASSERT(offset >= 0); |
| 1841 emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 | | 1842 int sd, d; |
| 1843 dst.split_code(&sd, &d); |
| 1844 emit(cond | d*B22 | 0xD9*B20 | base.code()*B16 | sd*B12 | |
| 1842 0xA*B8 | ((offset / 4) & 255)); | 1845 0xA*B8 | ((offset / 4) & 255)); |
| 1843 } | 1846 } |
| 1844 | 1847 |
| 1845 | 1848 |
| 1846 void Assembler::vstr(const DwVfpRegister src, | 1849 void Assembler::vstr(const DwVfpRegister src, |
| 1847 const Register base, | 1850 const Register base, |
| 1848 int offset, | 1851 int offset, |
| 1849 const Condition cond) { | 1852 const Condition cond) { |
| 1850 // MEM(Rbase + offset) = Dsrc. | 1853 // MEM(Rbase + offset) = Dsrc. |
| 1851 // Instruction details available in ARM DDI 0406A, A8-786. | 1854 // Instruction details available in ARM DDI 0406A, A8-786. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1865 int offset, | 1868 int offset, |
| 1866 const Condition cond) { | 1869 const Condition cond) { |
| 1867 // MEM(Rbase + offset) = SSrc. | 1870 // MEM(Rbase + offset) = SSrc. |
| 1868 // Instruction details available in ARM DDI 0406A, A8-786. | 1871 // Instruction details available in ARM DDI 0406A, A8-786. |
| 1869 // cond(31-28) | 1101(27-24)| 1000(23-20) | Rbase(19-16) | | 1872 // cond(31-28) | 1101(27-24)| 1000(23-20) | Rbase(19-16) | |
| 1870 // Vdst(15-12) | 1010(11-8) | (offset/4) | 1873 // Vdst(15-12) | 1010(11-8) | (offset/4) |
| 1871 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1874 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 1872 ASSERT(offset % 4 == 0); | 1875 ASSERT(offset % 4 == 0); |
| 1873 ASSERT((offset / 4) < 256); | 1876 ASSERT((offset / 4) < 256); |
| 1874 ASSERT(offset >= 0); | 1877 ASSERT(offset >= 0); |
| 1875 emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 | | 1878 int sd, d; |
| 1879 src.split_code(&sd, &d); |
| 1880 emit(cond | d*B22 | 0xD8*B20 | base.code()*B16 | sd*B12 | |
| 1876 0xA*B8 | ((offset / 4) & 255)); | 1881 0xA*B8 | ((offset / 4) & 255)); |
| 1877 } | 1882 } |
| 1878 | 1883 |
| 1879 | 1884 |
| 1880 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { | 1885 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
| 1881 uint64_t i; | 1886 uint64_t i; |
| 1882 memcpy(&i, &d, 8); | 1887 memcpy(&i, &d, 8); |
| 1883 | 1888 |
| 1884 *lo = i & 0xffffffff; | 1889 *lo = i & 0xffffffff; |
| 1885 *hi = i >> 32; | 1890 *hi = i >> 32; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1972 } | 1977 } |
| 1973 } | 1978 } |
| 1974 | 1979 |
| 1975 | 1980 |
| 1976 void Assembler::vmov(const SwVfpRegister dst, | 1981 void Assembler::vmov(const SwVfpRegister dst, |
| 1977 const SwVfpRegister src, | 1982 const SwVfpRegister src, |
| 1978 const Condition cond) { | 1983 const Condition cond) { |
| 1979 // Sd = Sm | 1984 // Sd = Sm |
| 1980 // Instruction details available in ARM DDI 0406B, A8-642. | 1985 // Instruction details available in ARM DDI 0406B, A8-642. |
| 1981 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1986 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 1982 emit(cond | 0xE*B24 | 0xB*B20 | | 1987 int sd, d, sm, m; |
| 1983 dst.code()*B12 | 0x5*B9 | B6 | src.code()); | 1988 dst.split_code(&sd, &d); |
| 1989 src.split_code(&sm, &m); |
| 1990 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); |
| 1984 } | 1991 } |
| 1985 | 1992 |
| 1986 | 1993 |
| 1987 void Assembler::vmov(const DwVfpRegister dst, | 1994 void Assembler::vmov(const DwVfpRegister dst, |
| 1988 const DwVfpRegister src, | 1995 const DwVfpRegister src, |
| 1989 const Condition cond) { | 1996 const Condition cond) { |
| 1990 // Dd = Dm | 1997 // Dd = Dm |
| 1991 // Instruction details available in ARM DDI 0406B, A8-642. | 1998 // Instruction details available in ARM DDI 0406B, A8-642. |
| 1992 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 1999 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 1993 emit(cond | 0xE*B24 | 0xB*B20 | | 2000 emit(cond | 0xE*B24 | 0xB*B20 | |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2027 | 2034 |
| 2028 void Assembler::vmov(const SwVfpRegister dst, | 2035 void Assembler::vmov(const SwVfpRegister dst, |
| 2029 const Register src, | 2036 const Register src, |
| 2030 const Condition cond) { | 2037 const Condition cond) { |
| 2031 // Sn = Rt. | 2038 // Sn = Rt. |
| 2032 // Instruction details available in ARM DDI 0406A, A8-642. | 2039 // Instruction details available in ARM DDI 0406A, A8-642. |
| 2033 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | | 2040 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
| 2034 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2041 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
| 2035 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2042 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 2036 ASSERT(!src.is(pc)); | 2043 ASSERT(!src.is(pc)); |
| 2037 emit(cond | 0xE*B24 | (dst.code() >> 1)*B16 | | 2044 int sn, n; |
| 2038 src.code()*B12 | 0xA*B8 | (0x1 & dst.code())*B7 | B4); | 2045 dst.split_code(&sn, &n); |
| 2046 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); |
| 2039 } | 2047 } |
| 2040 | 2048 |
| 2041 | 2049 |
| 2042 void Assembler::vmov(const Register dst, | 2050 void Assembler::vmov(const Register dst, |
| 2043 const SwVfpRegister src, | 2051 const SwVfpRegister src, |
| 2044 const Condition cond) { | 2052 const Condition cond) { |
| 2045 // Rt = Sn. | 2053 // Rt = Sn. |
| 2046 // Instruction details available in ARM DDI 0406A, A8-642. | 2054 // Instruction details available in ARM DDI 0406A, A8-642. |
| 2047 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | | 2055 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
| 2048 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2056 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
| 2049 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2057 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| 2050 ASSERT(!dst.is(pc)); | 2058 ASSERT(!dst.is(pc)); |
| 2051 emit(cond | 0xE*B24 | B20 | (src.code() >> 1)*B16 | | 2059 int sn, n; |
| 2052 dst.code()*B12 | 0xA*B8 | (0x1 & src.code())*B7 | B4); | 2060 src.split_code(&sn, &n); |
| 2061 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); |
| 2053 } | 2062 } |
| 2054 | 2063 |
| 2055 | 2064 |
| 2056 // Type of data to read from or write to VFP register. | 2065 // Type of data to read from or write to VFP register. |
| 2057 // Used as specifier in generic vcvt instruction. | 2066 // Used as specifier in generic vcvt instruction. |
| 2058 enum VFPType { S32, U32, F32, F64 }; | 2067 enum VFPType { S32, U32, F32, F64 }; |
| 2059 | 2068 |
| 2060 | 2069 |
| 2061 static bool IsSignedVFPType(VFPType type) { | 2070 static bool IsSignedVFPType(VFPType type) { |
| 2062 switch (type) { | 2071 switch (type) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2092 return false; | 2101 return false; |
| 2093 case F64: | 2102 case F64: |
| 2094 return true; | 2103 return true; |
| 2095 default: | 2104 default: |
| 2096 UNREACHABLE(); | 2105 UNREACHABLE(); |
| 2097 return false; | 2106 return false; |
| 2098 } | 2107 } |
| 2099 } | 2108 } |
| 2100 | 2109 |
| 2101 | 2110 |
| 2102 // Depending on split_last_bit split binary representation of reg_code into Vm:M | 2111 // Split five bit reg_code based on size of reg_type. |
| 2103 // or M:Vm form (where M is single bit). | 2112 // 32-bit register codes are Vm:M |
| 2104 static void SplitRegCode(bool split_last_bit, | 2113 // 64-bit register codes are M:Vm |
| 2114 // where Vm is four bits, and M is a single bit. |
| 2115 static void SplitRegCode(VFPType reg_type, |
| 2105 int reg_code, | 2116 int reg_code, |
| 2106 int* vm, | 2117 int* vm, |
| 2107 int* m) { | 2118 int* m) { |
| 2108 if (split_last_bit) { | 2119 ASSERT((reg_code >= 0) && (reg_code <= 31)); |
| 2120 if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) { |
| 2121 // 32 bit type. |
| 2109 *m = reg_code & 0x1; | 2122 *m = reg_code & 0x1; |
| 2110 *vm = reg_code >> 1; | 2123 *vm = reg_code >> 1; |
| 2111 } else { | 2124 } else { |
| 2125 // 64 bit type. |
| 2112 *m = (reg_code & 0x10) >> 4; | 2126 *m = (reg_code & 0x10) >> 4; |
| 2113 *vm = reg_code & 0x0F; | 2127 *vm = reg_code & 0x0F; |
| 2114 } | 2128 } |
| 2115 } | 2129 } |
| 2116 | 2130 |
| 2117 | 2131 |
| 2118 // Encode vcvt.src_type.dst_type instruction. | 2132 // Encode vcvt.src_type.dst_type instruction. |
| 2119 static Instr EncodeVCVT(const VFPType dst_type, | 2133 static Instr EncodeVCVT(const VFPType dst_type, |
| 2120 const int dst_code, | 2134 const int dst_code, |
| 2121 const VFPType src_type, | 2135 const VFPType src_type, |
| 2122 const int src_code, | 2136 const int src_code, |
| 2123 const Condition cond) { | 2137 const Condition cond) { |
| 2138 ASSERT(src_type != dst_type); |
| 2139 int D, Vd, M, Vm; |
| 2140 SplitRegCode(src_type, src_code, &Vm, &M); |
| 2141 SplitRegCode(dst_type, dst_code, &Vd, &D); |
| 2142 |
| 2124 if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) { | 2143 if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) { |
| 2125 // Conversion between IEEE floating point and 32-bit integer. | 2144 // Conversion between IEEE floating point and 32-bit integer. |
| 2126 // Instruction details available in ARM DDI 0406B, A8.6.295. | 2145 // Instruction details available in ARM DDI 0406B, A8.6.295. |
| 2127 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) | | 2146 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) | |
| 2128 // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2147 // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2129 ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type)); | 2148 ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type)); |
| 2130 | 2149 |
| 2131 int sz, opc2, D, Vd, M, Vm, op; | 2150 int sz, opc2, op; |
| 2132 | 2151 |
| 2133 if (IsIntegerVFPType(dst_type)) { | 2152 if (IsIntegerVFPType(dst_type)) { |
| 2134 opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4; | 2153 opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4; |
| 2135 sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0; | 2154 sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0; |
| 2136 op = 1; // round towards zero | 2155 op = 1; // round towards zero |
| 2137 SplitRegCode(!IsDoubleVFPType(src_type), src_code, &Vm, &M); | |
| 2138 SplitRegCode(true, dst_code, &Vd, &D); | |
| 2139 } else { | 2156 } else { |
| 2140 ASSERT(IsIntegerVFPType(src_type)); | 2157 ASSERT(IsIntegerVFPType(src_type)); |
| 2141 | |
| 2142 opc2 = 0x0; | 2158 opc2 = 0x0; |
| 2143 sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0; | 2159 sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0; |
| 2144 op = IsSignedVFPType(src_type) ? 0x1 : 0x0; | 2160 op = IsSignedVFPType(src_type) ? 0x1 : 0x0; |
| 2145 SplitRegCode(true, src_code, &Vm, &M); | |
| 2146 SplitRegCode(!IsDoubleVFPType(dst_type), dst_code, &Vd, &D); | |
| 2147 } | 2161 } |
| 2148 | 2162 |
| 2149 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 | | 2163 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 | |
| 2150 Vd*B12 | 0x5*B9 | sz*B8 | op*B7 | B6 | M*B5 | Vm); | 2164 Vd*B12 | 0x5*B9 | sz*B8 | op*B7 | B6 | M*B5 | Vm); |
| 2151 } else { | 2165 } else { |
| 2152 // Conversion between IEEE double and single precision. | 2166 // Conversion between IEEE double and single precision. |
| 2153 // Instruction details available in ARM DDI 0406B, A8.6.298. | 2167 // Instruction details available in ARM DDI 0406B, A8.6.298. |
| 2154 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) | | 2168 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) | |
| 2155 // Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2169 // Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2156 int sz, D, Vd, M, Vm; | 2170 int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0; |
| 2157 | |
| 2158 ASSERT(IsDoubleVFPType(dst_type) != IsDoubleVFPType(src_type)); | |
| 2159 sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0; | |
| 2160 SplitRegCode(IsDoubleVFPType(src_type), dst_code, &Vd, &D); | |
| 2161 SplitRegCode(!IsDoubleVFPType(src_type), src_code, &Vm, &M); | |
| 2162 | |
| 2163 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | | 2171 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
| 2164 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 2172 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
| 2165 } | 2173 } |
| 2166 } | 2174 } |
| 2167 | 2175 |
| 2168 | 2176 |
| 2169 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 2177 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
| 2170 const SwVfpRegister src, | 2178 const SwVfpRegister src, |
| 2171 const Condition cond) { | 2179 const Condition cond) { |
| 2172 ASSERT(CpuFeatures::IsEnabled(VFP3)); | 2180 ASSERT(CpuFeatures::IsEnabled(VFP3)); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 | 2614 |
| 2607 // Since a constant pool was just emitted, move the check offset forward by | 2615 // Since a constant pool was just emitted, move the check offset forward by |
| 2608 // the standard interval. | 2616 // the standard interval. |
| 2609 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 2617 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
| 2610 } | 2618 } |
| 2611 | 2619 |
| 2612 | 2620 |
| 2613 } } // namespace v8::internal | 2621 } } // namespace v8::internal |
| 2614 | 2622 |
| 2615 #endif // V8_TARGET_ARCH_ARM | 2623 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |