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

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

Issue 3107027: Fix incorrect encoding of single and double precision registers for some... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 1791 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698