| 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 |