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

Side by Side Diff: src/compiler/arm64/code-generator-arm64.cc

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: Created 3 years, 11 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/arm64/frames-arm64.h" 7 #include "src/arm64/frames-arm64.h"
8 #include "src/arm64/macro-assembler-arm64.h" 8 #include "src/arm64/macro-assembler-arm64.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler/code-generator-impl.h" 10 #include "src/compiler/code-generator-impl.h"
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); 245 DCHECK(op->IsStackSlot() || op->IsFPStackSlot());
246 return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm); 246 return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm);
247 } 247 }
248 248
249 MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const { 249 MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const {
250 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); 250 FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
251 if (offset.from_frame_pointer()) { 251 if (offset.from_frame_pointer()) {
252 int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset(); 252 int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset();
253 // Convert FP-offsets to SP-offsets if it results in better code. 253 // Convert FP-offsets to SP-offsets if it results in better code.
254 if (Assembler::IsImmLSUnscaled(from_sp) || 254 if (Assembler::IsImmLSUnscaled(from_sp) ||
255 Assembler::IsImmLSScaled(from_sp, LSDoubleWord)) { 255 Assembler::IsImmLSScaled(from_sp, 3)) {
256 offset = FrameOffset::FromStackPointer(from_sp); 256 offset = FrameOffset::FromStackPointer(from_sp);
257 } 257 }
258 } 258 }
259 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, 259 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp,
260 offset.offset()); 260 offset.offset());
261 } 261 }
262 }; 262 };
263 263
264 264
265 namespace { 265 namespace {
(...skipping 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 frame->AlignFrame(16); 1769 frame->AlignFrame(16);
1770 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 1770 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1771 1771
1772 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { 1772 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) {
1773 __ SetStackPointer(csp); 1773 __ SetStackPointer(csp);
1774 } else { 1774 } else {
1775 __ SetStackPointer(jssp); 1775 __ SetStackPointer(jssp);
1776 } 1776 }
1777 1777
1778 // Save FP registers. 1778 // Save FP registers.
1779 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, 1779 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits,
1780 descriptor->CalleeSavedFPRegisters()); 1780 descriptor->CalleeSavedFPRegisters());
1781 int saved_count = saves_fp.Count(); 1781 int saved_count = saves_fp.Count();
1782 if (saved_count != 0) { 1782 if (saved_count != 0) {
1783 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); 1783 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedV().list());
1784 frame->AllocateSavedCalleeRegisterSlots(saved_count * 1784 frame->AllocateSavedCalleeRegisterSlots(saved_count *
1785 (kDoubleSize / kPointerSize)); 1785 (kDoubleSize / kPointerSize));
1786 } 1786 }
1787 1787
1788 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, 1788 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
1789 descriptor->CalleeSavedRegisters()); 1789 descriptor->CalleeSavedRegisters());
1790 saved_count = saves.Count(); 1790 saved_count = saves.Count();
1791 if (saved_count != 0) { 1791 if (saved_count != 0) {
1792 frame->AllocateSavedCalleeRegisterSlots(saved_count); 1792 frame->AllocateSavedCalleeRegisterSlots(saved_count);
1793 } 1793 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 !descriptor->IsJSFunctionCall() && !descriptor->IsCFunctionCall(); 1846 !descriptor->IsJSFunctionCall() && !descriptor->IsCFunctionCall();
1847 if (is_stub_frame) { 1847 if (is_stub_frame) {
1848 UseScratchRegisterScope temps(masm()); 1848 UseScratchRegisterScope temps(masm());
1849 Register temp = temps.AcquireX(); 1849 Register temp = temps.AcquireX();
1850 __ Mov(temp, Smi::FromInt(info()->GetOutputStackFrameType())); 1850 __ Mov(temp, Smi::FromInt(info()->GetOutputStackFrameType()));
1851 __ Str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); 1851 __ Str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset));
1852 } 1852 }
1853 } 1853 }
1854 1854
1855 // Save FP registers. 1855 // Save FP registers.
1856 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, 1856 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits,
1857 descriptor->CalleeSavedFPRegisters()); 1857 descriptor->CalleeSavedFPRegisters());
1858 int saved_count = saves_fp.Count(); 1858 int saved_count = saves_fp.Count();
1859 if (saved_count != 0) { 1859 if (saved_count != 0) {
1860 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); 1860 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedV().list());
1861 __ PushCPURegList(saves_fp); 1861 __ PushCPURegList(saves_fp);
1862 } 1862 }
1863 // Save registers. 1863 // Save registers.
1864 // TODO(palfia): TF save list is not in sync with 1864 // TODO(palfia): TF save list is not in sync with
1865 // CPURegList::GetCalleeSaved(): x30 is missing. 1865 // CPURegList::GetCalleeSaved(): x30 is missing.
1866 // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list()); 1866 // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list());
1867 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, 1867 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
1868 descriptor->CalleeSavedRegisters()); 1868 descriptor->CalleeSavedRegisters());
1869 saved_count = saves.Count(); 1869 saved_count = saves.Count();
1870 if (saved_count != 0) { 1870 if (saved_count != 0) {
1871 __ PushCPURegList(saves); 1871 __ PushCPURegList(saves);
1872 } 1872 }
1873 } 1873 }
1874 1874
1875 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { 1875 void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
1876 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 1876 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1877 1877
1878 // Restore registers. 1878 // Restore registers.
1879 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, 1879 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
1880 descriptor->CalleeSavedRegisters()); 1880 descriptor->CalleeSavedRegisters());
1881 if (saves.Count() != 0) { 1881 if (saves.Count() != 0) {
1882 __ PopCPURegList(saves); 1882 __ PopCPURegList(saves);
1883 } 1883 }
1884 1884
1885 // Restore fp registers. 1885 // Restore fp registers.
1886 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, 1886 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits,
1887 descriptor->CalleeSavedFPRegisters()); 1887 descriptor->CalleeSavedFPRegisters());
1888 if (saves_fp.Count() != 0) { 1888 if (saves_fp.Count() != 0) {
1889 __ PopCPURegList(saves_fp); 1889 __ PopCPURegList(saves_fp);
1890 } 1890 }
1891 1891
1892 unwinding_info_writer_.MarkBlockWillExit(); 1892 unwinding_info_writer_.MarkBlockWillExit();
1893 1893
1894 Arm64OperandConverter g(this, nullptr); 1894 Arm64OperandConverter g(this, nullptr);
1895 int pop_count = static_cast<int>(descriptor->StackParameterCount()); 1895 int pop_count = static_cast<int>(descriptor->StackParameterCount());
1896 if (descriptor->IsCFunctionCall()) { 1896 if (descriptor->IsCFunctionCall()) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 __ LoadObject(dst, src_object); 1975 __ LoadObject(dst, src_object);
1976 } 1976 }
1977 } else { 1977 } else {
1978 __ Mov(dst, g.ToImmediate(source)); 1978 __ Mov(dst, g.ToImmediate(source));
1979 } 1979 }
1980 if (destination->IsStackSlot()) { 1980 if (destination->IsStackSlot()) {
1981 __ Str(dst, g.ToMemOperand(destination, masm())); 1981 __ Str(dst, g.ToMemOperand(destination, masm()));
1982 } 1982 }
1983 } else if (src.type() == Constant::kFloat32) { 1983 } else if (src.type() == Constant::kFloat32) {
1984 if (destination->IsFPRegister()) { 1984 if (destination->IsFPRegister()) {
1985 FPRegister dst = g.ToDoubleRegister(destination).S(); 1985 VRegister dst = g.ToDoubleRegister(destination).S();
1986 __ Fmov(dst, src.ToFloat32()); 1986 __ Fmov(dst, src.ToFloat32());
1987 } else { 1987 } else {
1988 DCHECK(destination->IsFPStackSlot()); 1988 DCHECK(destination->IsFPStackSlot());
1989 if (bit_cast<int32_t>(src.ToFloat32()) == 0) { 1989 if (bit_cast<int32_t>(src.ToFloat32()) == 0) {
1990 __ Str(wzr, g.ToMemOperand(destination, masm())); 1990 __ Str(wzr, g.ToMemOperand(destination, masm()));
1991 } else { 1991 } else {
1992 UseScratchRegisterScope scope(masm()); 1992 UseScratchRegisterScope scope(masm());
1993 FPRegister temp = scope.AcquireS(); 1993 VRegister temp = scope.AcquireS();
1994 __ Fmov(temp, src.ToFloat32()); 1994 __ Fmov(temp, src.ToFloat32());
1995 __ Str(temp, g.ToMemOperand(destination, masm())); 1995 __ Str(temp, g.ToMemOperand(destination, masm()));
1996 } 1996 }
1997 } 1997 }
1998 } else { 1998 } else {
1999 DCHECK_EQ(Constant::kFloat64, src.type()); 1999 DCHECK_EQ(Constant::kFloat64, src.type());
2000 if (destination->IsFPRegister()) { 2000 if (destination->IsFPRegister()) {
2001 FPRegister dst = g.ToDoubleRegister(destination); 2001 VRegister dst = g.ToDoubleRegister(destination);
2002 __ Fmov(dst, src.ToFloat64()); 2002 __ Fmov(dst, src.ToFloat64());
2003 } else { 2003 } else {
2004 DCHECK(destination->IsFPStackSlot()); 2004 DCHECK(destination->IsFPStackSlot());
2005 if (bit_cast<int64_t>(src.ToFloat64()) == 0) { 2005 if (bit_cast<int64_t>(src.ToFloat64()) == 0) {
2006 __ Str(xzr, g.ToMemOperand(destination, masm())); 2006 __ Str(xzr, g.ToMemOperand(destination, masm()));
2007 } else { 2007 } else {
2008 UseScratchRegisterScope scope(masm()); 2008 UseScratchRegisterScope scope(masm());
2009 FPRegister temp = scope.AcquireD(); 2009 VRegister temp = scope.AcquireD();
2010 __ Fmov(temp, src.ToFloat64()); 2010 __ Fmov(temp, src.ToFloat64());
2011 __ Str(temp, g.ToMemOperand(destination, masm())); 2011 __ Str(temp, g.ToMemOperand(destination, masm()));
2012 } 2012 }
2013 } 2013 }
2014 } 2014 }
2015 } else if (source->IsFPRegister()) { 2015 } else if (source->IsFPRegister()) {
2016 FPRegister src = g.ToDoubleRegister(source); 2016 VRegister src = g.ToDoubleRegister(source);
2017 if (destination->IsFPRegister()) { 2017 if (destination->IsFPRegister()) {
2018 FPRegister dst = g.ToDoubleRegister(destination); 2018 VRegister dst = g.ToDoubleRegister(destination);
2019 __ Fmov(dst, src); 2019 __ Fmov(dst, src);
2020 } else { 2020 } else {
2021 DCHECK(destination->IsFPStackSlot()); 2021 DCHECK(destination->IsFPStackSlot());
2022 __ Str(src, g.ToMemOperand(destination, masm())); 2022 __ Str(src, g.ToMemOperand(destination, masm()));
2023 } 2023 }
2024 } else if (source->IsFPStackSlot()) { 2024 } else if (source->IsFPStackSlot()) {
2025 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); 2025 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot());
2026 MemOperand src = g.ToMemOperand(source, masm()); 2026 MemOperand src = g.ToMemOperand(source, masm());
2027 if (destination->IsFPRegister()) { 2027 if (destination->IsFPRegister()) {
2028 __ Ldr(g.ToDoubleRegister(destination), src); 2028 __ Ldr(g.ToDoubleRegister(destination), src);
2029 } else { 2029 } else {
2030 UseScratchRegisterScope scope(masm()); 2030 UseScratchRegisterScope scope(masm());
2031 FPRegister temp = scope.AcquireD(); 2031 VRegister temp = scope.AcquireD();
2032 __ Ldr(temp, src); 2032 __ Ldr(temp, src);
2033 __ Str(temp, g.ToMemOperand(destination, masm())); 2033 __ Str(temp, g.ToMemOperand(destination, masm()));
2034 } 2034 }
2035 } else { 2035 } else {
2036 UNREACHABLE(); 2036 UNREACHABLE();
2037 } 2037 }
2038 } 2038 }
2039 2039
2040 2040
2041 void CodeGenerator::AssembleSwap(InstructionOperand* source, 2041 void CodeGenerator::AssembleSwap(InstructionOperand* source,
(...skipping 23 matching lines...) Expand all
2065 DoubleRegister temp_0 = scope.AcquireD(); 2065 DoubleRegister temp_0 = scope.AcquireD();
2066 DoubleRegister temp_1 = scope.AcquireD(); 2066 DoubleRegister temp_1 = scope.AcquireD();
2067 MemOperand src = g.ToMemOperand(source, masm()); 2067 MemOperand src = g.ToMemOperand(source, masm());
2068 MemOperand dst = g.ToMemOperand(destination, masm()); 2068 MemOperand dst = g.ToMemOperand(destination, masm());
2069 __ Ldr(temp_0, src); 2069 __ Ldr(temp_0, src);
2070 __ Ldr(temp_1, dst); 2070 __ Ldr(temp_1, dst);
2071 __ Str(temp_0, dst); 2071 __ Str(temp_0, dst);
2072 __ Str(temp_1, src); 2072 __ Str(temp_1, src);
2073 } else if (source->IsFPRegister()) { 2073 } else if (source->IsFPRegister()) {
2074 UseScratchRegisterScope scope(masm()); 2074 UseScratchRegisterScope scope(masm());
2075 FPRegister temp = scope.AcquireD(); 2075 VRegister temp = scope.AcquireD();
2076 FPRegister src = g.ToDoubleRegister(source); 2076 VRegister src = g.ToDoubleRegister(source);
2077 if (destination->IsFPRegister()) { 2077 if (destination->IsFPRegister()) {
2078 FPRegister dst = g.ToDoubleRegister(destination); 2078 VRegister dst = g.ToDoubleRegister(destination);
2079 __ Fmov(temp, src); 2079 __ Fmov(temp, src);
2080 __ Fmov(src, dst); 2080 __ Fmov(src, dst);
2081 __ Fmov(dst, temp); 2081 __ Fmov(dst, temp);
2082 } else { 2082 } else {
2083 DCHECK(destination->IsFPStackSlot()); 2083 DCHECK(destination->IsFPStackSlot());
2084 MemOperand dst = g.ToMemOperand(destination, masm()); 2084 MemOperand dst = g.ToMemOperand(destination, masm());
2085 __ Fmov(temp, src); 2085 __ Fmov(temp, src);
2086 __ Ldr(src, dst); 2086 __ Ldr(src, dst);
2087 __ Str(temp, dst); 2087 __ Str(temp, dst);
2088 } 2088 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 padding_size -= kInstructionSize; 2120 padding_size -= kInstructionSize;
2121 } 2121 }
2122 } 2122 }
2123 } 2123 }
2124 2124
2125 #undef __ 2125 #undef __
2126 2126
2127 } // namespace compiler 2127 } // namespace compiler
2128 } // namespace internal 2128 } // namespace internal
2129 } // namespace v8 2129 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698