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 |