OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |