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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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/builtins-arm.cc » ('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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 const Instr kLdrStrOffsetMask = 0x00000fff; 264 const Instr kLdrStrOffsetMask = 0x00000fff;
265 265
266 266
267 // Spare buffer. 267 // Spare buffer.
268 static const int kMinimalBufferSize = 4*KB; 268 static const int kMinimalBufferSize = 4*KB;
269 static byte* spare_buffer_ = NULL; 269 static byte* spare_buffer_ = NULL;
270 270
271 271
272 Assembler::Assembler(void* buffer, int buffer_size) 272 Assembler::Assembler(void* buffer, int buffer_size)
273 : positions_recorder_(this), 273 : positions_recorder_(this),
274 allow_peephole_optimization_(false) { 274 allow_peephole_optimization_(false),
275 emit_debug_code_(FLAG_debug_code) {
275 allow_peephole_optimization_ = FLAG_peephole_optimization; 276 allow_peephole_optimization_ = FLAG_peephole_optimization;
276 if (buffer == NULL) { 277 if (buffer == NULL) {
277 // Do our own buffer management. 278 // Do our own buffer management.
278 if (buffer_size <= kMinimalBufferSize) { 279 if (buffer_size <= kMinimalBufferSize) {
279 buffer_size = kMinimalBufferSize; 280 buffer_size = kMinimalBufferSize;
280 281
281 if (spare_buffer_ != NULL) { 282 if (spare_buffer_ != NULL) {
282 buffer = spare_buffer_; 283 buffer = spare_buffer_;
283 spare_buffer_ = NULL; 284 spare_buffer_ = NULL;
284 } 285 }
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 } 761 }
761 #endif // def DEBUG 762 #endif // def DEBUG
762 return Serializer::enabled(); 763 return Serializer::enabled();
763 } else if (rmode_ == RelocInfo::NONE) { 764 } else if (rmode_ == RelocInfo::NONE) {
764 return false; 765 return false;
765 } 766 }
766 return true; 767 return true;
767 } 768 }
768 769
769 770
770 bool Operand::is_single_instruction() const { 771 bool Operand::is_single_instruction(Instr instr) const {
771 if (rm_.is_valid()) return true; 772 if (rm_.is_valid()) return true;
772 if (must_use_constant_pool()) return false;
773 uint32_t dummy1, dummy2; 773 uint32_t dummy1, dummy2;
774 return fits_shifter(imm32_, &dummy1, &dummy2, NULL); 774 if (must_use_constant_pool() ||
775 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
776 // The immediate operand cannot be encoded as a shifter operand, or use of
777 // constant pool is required. For a mov instruction not setting the
778 // condition code additional instruction conventions can be used.
779 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
780 if (must_use_constant_pool() || !CpuFeatures::IsSupported(ARMv7)) {
781 // mov instruction will be an ldr from constant pool (one instruction).
782 return true;
783 } else {
784 // mov instruction will be a mov or movw followed by movt (two
785 // instructions).
786 return false;
787 }
788 } else {
789 // If this is not a mov or mvn instruction there will always an additional
790 // instructions - either mov or ldr. The mov might actually be two
791 // instructions mov or movw followed by movt so including the actual
792 // instruction two or three instructions will be generated.
793 return false;
794 }
795 } else {
796 // No use of constant pool and the immediate operand can be encoded as a
797 // shifter operand.
798 return true;
799 }
775 } 800 }
776 801
777 802
778 void Assembler::addrmod1(Instr instr, 803 void Assembler::addrmod1(Instr instr,
779 Register rn, 804 Register rn,
780 Register rd, 805 Register rd,
781 const Operand& x) { 806 const Operand& x) {
782 CheckBuffer(); 807 CheckBuffer();
783 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0); 808 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
784 if (!x.rm_.is_valid()) { 809 if (!x.rm_.is_valid()) {
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 // Ddst = MEM(Rbase + offset). 1866 // Ddst = MEM(Rbase + offset).
1842 // Instruction details available in ARM DDI 0406A, A8-628. 1867 // Instruction details available in ARM DDI 0406A, A8-628.
1843 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | 1868 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
1844 // Vdst(15-12) | 1011(11-8) | offset 1869 // Vdst(15-12) | 1011(11-8) | offset
1845 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1870 ASSERT(CpuFeatures::IsEnabled(VFP3));
1846 int u = 1; 1871 int u = 1;
1847 if (offset < 0) { 1872 if (offset < 0) {
1848 offset = -offset; 1873 offset = -offset;
1849 u = 0; 1874 u = 0;
1850 } 1875 }
1851 ASSERT(offset % 4 == 0); 1876
1852 ASSERT((offset / 4) < 256);
1853 ASSERT(offset >= 0); 1877 ASSERT(offset >= 0);
1854 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | 1878 if ((offset % 4) == 0 && (offset / 4) < 256) {
1855 0xB*B8 | ((offset / 4) & 255)); 1879 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 |
1880 0xB*B8 | ((offset / 4) & 255));
1881 } else {
1882 // Larger offsets must be handled by computing the correct address
1883 // in the ip register.
1884 ASSERT(!base.is(ip));
1885 if (u == 1) {
1886 add(ip, base, Operand(offset));
1887 } else {
1888 sub(ip, base, Operand(offset));
1889 }
1890 emit(cond | 0xD1*B20 | ip.code()*B16 | dst.code()*B12 | 0xB*B8);
1891 }
1892 }
1893
1894
1895 void Assembler::vldr(const DwVfpRegister dst,
1896 const MemOperand& operand,
1897 const Condition cond) {
1898 ASSERT(!operand.rm().is_valid());
1899 ASSERT(operand.am_ == Offset);
1900 vldr(dst, operand.rn(), operand.offset(), cond);
1856 } 1901 }
1857 1902
1858 1903
1859 void Assembler::vldr(const SwVfpRegister dst, 1904 void Assembler::vldr(const SwVfpRegister dst,
1860 const Register base, 1905 const Register base,
1861 int offset, 1906 int offset,
1862 const Condition cond) { 1907 const Condition cond) {
1863 // Sdst = MEM(Rbase + offset). 1908 // Sdst = MEM(Rbase + offset).
1864 // Instruction details available in ARM DDI 0406A, A8-628. 1909 // Instruction details available in ARM DDI 0406A, A8-628.
1865 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | 1910 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
1866 // Vdst(15-12) | 1010(11-8) | offset 1911 // Vdst(15-12) | 1010(11-8) | offset
1867 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1912 ASSERT(CpuFeatures::IsEnabled(VFP3));
1868 int u = 1; 1913 int u = 1;
1869 if (offset < 0) { 1914 if (offset < 0) {
1870 offset = -offset; 1915 offset = -offset;
1871 u = 0; 1916 u = 0;
1872 } 1917 }
1873 ASSERT(offset % 4 == 0);
1874 ASSERT((offset / 4) < 256);
1875 ASSERT(offset >= 0);
1876 int sd, d; 1918 int sd, d;
1877 dst.split_code(&sd, &d); 1919 dst.split_code(&sd, &d);
1920 ASSERT(offset >= 0);
1921
1922 if ((offset % 4) == 0 && (offset / 4) < 256) {
1878 emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 | 1923 emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 |
1879 0xA*B8 | ((offset / 4) & 255)); 1924 0xA*B8 | ((offset / 4) & 255));
1925 } else {
1926 // Larger offsets must be handled by computing the correct address
1927 // in the ip register.
1928 ASSERT(!base.is(ip));
1929 if (u == 1) {
1930 add(ip, base, Operand(offset));
1931 } else {
1932 sub(ip, base, Operand(offset));
1933 }
1934 emit(cond | d*B22 | 0xD1*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
1935 }
1936 }
1937
1938
1939 void Assembler::vldr(const SwVfpRegister dst,
1940 const MemOperand& operand,
1941 const Condition cond) {
1942 ASSERT(!operand.rm().is_valid());
1943 ASSERT(operand.am_ == Offset);
1944 vldr(dst, operand.rn(), operand.offset(), cond);
1880 } 1945 }
1881 1946
1882 1947
1883 void Assembler::vstr(const DwVfpRegister src, 1948 void Assembler::vstr(const DwVfpRegister src,
1884 const Register base, 1949 const Register base,
1885 int offset, 1950 int offset,
1886 const Condition cond) { 1951 const Condition cond) {
1887 // MEM(Rbase + offset) = Dsrc. 1952 // MEM(Rbase + offset) = Dsrc.
1888 // Instruction details available in ARM DDI 0406A, A8-786. 1953 // Instruction details available in ARM DDI 0406A, A8-786.
1889 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | 1954 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) |
1890 // Vsrc(15-12) | 1011(11-8) | (offset/4) 1955 // Vsrc(15-12) | 1011(11-8) | (offset/4)
1891 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1956 ASSERT(CpuFeatures::IsEnabled(VFP3));
1892 int u = 1; 1957 int u = 1;
1893 if (offset < 0) { 1958 if (offset < 0) {
1894 offset = -offset; 1959 offset = -offset;
1895 u = 0; 1960 u = 0;
1896 } 1961 }
1897 ASSERT(offset % 4 == 0);
1898 ASSERT((offset / 4) < 256);
1899 ASSERT(offset >= 0); 1962 ASSERT(offset >= 0);
1900 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | 1963 if ((offset % 4) == 0 && (offset / 4) < 256) {
1901 0xB*B8 | ((offset / 4) & 255)); 1964 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 |
1965 0xB*B8 | ((offset / 4) & 255));
1966 } else {
1967 // Larger offsets must be handled by computing the correct address
1968 // in the ip register.
1969 ASSERT(!base.is(ip));
1970 if (u == 1) {
1971 add(ip, base, Operand(offset));
1972 } else {
1973 sub(ip, base, Operand(offset));
1974 }
1975 emit(cond | 0xD0*B20 | ip.code()*B16 | src.code()*B12 | 0xB*B8);
1976 }
1977 }
1978
1979
1980 void Assembler::vstr(const DwVfpRegister src,
1981 const MemOperand& operand,
1982 const Condition cond) {
1983 ASSERT(!operand.rm().is_valid());
1984 ASSERT(operand.am_ == Offset);
1985 vstr(src, operand.rn(), operand.offset(), cond);
1902 } 1986 }
1903 1987
1904 1988
1905 void Assembler::vstr(const SwVfpRegister src, 1989 void Assembler::vstr(const SwVfpRegister src,
1906 const Register base, 1990 const Register base,
1907 int offset, 1991 int offset,
1908 const Condition cond) { 1992 const Condition cond) {
1909 // MEM(Rbase + offset) = SSrc. 1993 // MEM(Rbase + offset) = SSrc.
1910 // Instruction details available in ARM DDI 0406A, A8-786. 1994 // Instruction details available in ARM DDI 0406A, A8-786.
1911 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | 1995 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) |
1912 // Vdst(15-12) | 1010(11-8) | (offset/4) 1996 // Vdst(15-12) | 1010(11-8) | (offset/4)
1913 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1997 ASSERT(CpuFeatures::IsEnabled(VFP3));
1914 int u = 1; 1998 int u = 1;
1915 if (offset < 0) { 1999 if (offset < 0) {
1916 offset = -offset; 2000 offset = -offset;
1917 u = 0; 2001 u = 0;
1918 } 2002 }
1919 ASSERT(offset % 4 == 0);
1920 ASSERT((offset / 4) < 256);
1921 ASSERT(offset >= 0);
1922 int sd, d; 2003 int sd, d;
1923 src.split_code(&sd, &d); 2004 src.split_code(&sd, &d);
1924 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | 2005 ASSERT(offset >= 0);
1925 0xA*B8 | ((offset / 4) & 255)); 2006 if ((offset % 4) == 0 && (offset / 4) < 256) {
2007 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
2008 0xA*B8 | ((offset / 4) & 255));
2009 } else {
2010 // Larger offsets must be handled by computing the correct address
2011 // in the ip register.
2012 ASSERT(!base.is(ip));
2013 if (u == 1) {
2014 add(ip, base, Operand(offset));
2015 } else {
2016 sub(ip, base, Operand(offset));
2017 }
2018 emit(cond | d*B22 | 0xD0*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
2019 }
2020 }
2021
2022
2023 void Assembler::vstr(const SwVfpRegister src,
2024 const MemOperand& operand,
2025 const Condition cond) {
2026 ASSERT(!operand.rm().is_valid());
2027 ASSERT(operand.am_ == Offset);
2028 vldr(src, operand.rn(), operand.offset(), cond);
1926 } 2029 }
1927 2030
1928 2031
1929 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { 2032 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
1930 uint64_t i; 2033 uint64_t i;
1931 memcpy(&i, &d, 8); 2034 memcpy(&i, &d, 8);
1932 2035
1933 *lo = i & 0xffffffff; 2036 *lo = i & 0xffffffff;
1934 *hi = i >> 32; 2037 *hi = i >> 32;
1935 } 2038 }
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
2275 2378
2276 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, 2379 void Assembler::vcvt_f32_f64(const SwVfpRegister dst,
2277 const DwVfpRegister src, 2380 const DwVfpRegister src,
2278 VFPConversionMode mode, 2381 VFPConversionMode mode,
2279 const Condition cond) { 2382 const Condition cond) {
2280 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2383 ASSERT(CpuFeatures::IsEnabled(VFP3));
2281 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); 2384 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2282 } 2385 }
2283 2386
2284 2387
2388 void Assembler::vneg(const DwVfpRegister dst,
2389 const DwVfpRegister src,
2390 const Condition cond) {
2391 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 |
2392 0x5*B9 | B8 | B6 | src.code());
2393 }
2394
2395
2285 void Assembler::vabs(const DwVfpRegister dst, 2396 void Assembler::vabs(const DwVfpRegister dst,
2286 const DwVfpRegister src, 2397 const DwVfpRegister src,
2287 const Condition cond) { 2398 const Condition cond) {
2288 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 2399 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 |
2289 0x5*B9 | B8 | 0x3*B6 | src.code()); 2400 0x5*B9 | B8 | 0x3*B6 | src.code());
2290 } 2401 }
2291 2402
2292 2403
2293 void Assembler::vadd(const DwVfpRegister dst, 2404 void Assembler::vadd(const DwVfpRegister dst,
2294 const DwVfpRegister src1, 2405 const DwVfpRegister src1,
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 BlockConstPoolBefore(pc_offset() + kInstrSize); 2659 BlockConstPoolBefore(pc_offset() + kInstrSize);
2549 } 2660 }
2550 if (rinfo.rmode() != RelocInfo::NONE) { 2661 if (rinfo.rmode() != RelocInfo::NONE) {
2551 // Don't record external references unless the heap will be serialized. 2662 // Don't record external references unless the heap will be serialized.
2552 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 2663 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2553 #ifdef DEBUG 2664 #ifdef DEBUG
2554 if (!Serializer::enabled()) { 2665 if (!Serializer::enabled()) {
2555 Serializer::TooLateToEnableNow(); 2666 Serializer::TooLateToEnableNow();
2556 } 2667 }
2557 #endif 2668 #endif
2558 if (!Serializer::enabled() && !FLAG_debug_code) { 2669 if (!Serializer::enabled() && !emit_debug_code()) {
2559 return; 2670 return;
2560 } 2671 }
2561 } 2672 }
2562 ASSERT(buffer_space() >= kMaxRelocSize); // too late to grow buffer here 2673 ASSERT(buffer_space() >= kMaxRelocSize); // too late to grow buffer here
2563 reloc_info_writer.Write(&rinfo); 2674 reloc_info_writer.Write(&rinfo);
2564 } 2675 }
2565 } 2676 }
2566 2677
2567 2678
2568 void Assembler::CheckConstPool(bool force_emit, bool require_jump) { 2679 void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2669 2780
2670 // Since a constant pool was just emitted, move the check offset forward by 2781 // Since a constant pool was just emitted, move the check offset forward by
2671 // the standard interval. 2782 // the standard interval.
2672 next_buffer_check_ = pc_offset() + kCheckConstInterval; 2783 next_buffer_check_ = pc_offset() + kCheckConstInterval;
2673 } 2784 }
2674 2785
2675 2786
2676 } } // namespace v8::internal 2787 } } // namespace v8::internal
2677 2788
2678 #endif // V8_TARGET_ARCH_ARM 2789 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/builtins-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698