| 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/assembler-arm64-inl.h" | 7 #include "src/arm64/assembler-arm64-inl.h" |
| 8 #include "src/arm64/frames-arm64.h" | 8 #include "src/arm64/frames-arm64.h" |
| 9 #include "src/arm64/macro-assembler-arm64-inl.h" | 9 #include "src/arm64/macro-assembler-arm64-inl.h" |
| 10 #include "src/compilation-info.h" | 10 #include "src/compilation-info.h" |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); | 250 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
| 251 return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm); | 251 return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm); |
| 252 } | 252 } |
| 253 | 253 |
| 254 MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const { | 254 MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const { |
| 255 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 255 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
| 256 if (offset.from_frame_pointer()) { | 256 if (offset.from_frame_pointer()) { |
| 257 int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset(); | 257 int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset(); |
| 258 // Convert FP-offsets to SP-offsets if it results in better code. | 258 // Convert FP-offsets to SP-offsets if it results in better code. |
| 259 if (Assembler::IsImmLSUnscaled(from_sp) || | 259 if (Assembler::IsImmLSUnscaled(from_sp) || |
| 260 Assembler::IsImmLSScaled(from_sp, LSDoubleWord)) { | 260 Assembler::IsImmLSScaled(from_sp, 3)) { |
| 261 offset = FrameOffset::FromStackPointer(from_sp); | 261 offset = FrameOffset::FromStackPointer(from_sp); |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, | 264 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, |
| 265 offset.offset()); | 265 offset.offset()); |
| 266 } | 266 } |
| 267 }; | 267 }; |
| 268 | 268 |
| 269 | 269 |
| 270 namespace { | 270 namespace { |
| (...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 frame->AlignFrame(16); | 1894 frame->AlignFrame(16); |
| 1895 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1895 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1896 | 1896 |
| 1897 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { | 1897 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { |
| 1898 __ SetStackPointer(csp); | 1898 __ SetStackPointer(csp); |
| 1899 } else { | 1899 } else { |
| 1900 __ SetStackPointer(jssp); | 1900 __ SetStackPointer(jssp); |
| 1901 } | 1901 } |
| 1902 | 1902 |
| 1903 // Save FP registers. | 1903 // Save FP registers. |
| 1904 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 1904 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits, |
| 1905 descriptor->CalleeSavedFPRegisters()); | 1905 descriptor->CalleeSavedFPRegisters()); |
| 1906 int saved_count = saves_fp.Count(); | 1906 int saved_count = saves_fp.Count(); |
| 1907 if (saved_count != 0) { | 1907 if (saved_count != 0) { |
| 1908 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); | 1908 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedV().list()); |
| 1909 frame->AllocateSavedCalleeRegisterSlots(saved_count * | 1909 frame->AllocateSavedCalleeRegisterSlots(saved_count * |
| 1910 (kDoubleSize / kPointerSize)); | 1910 (kDoubleSize / kPointerSize)); |
| 1911 } | 1911 } |
| 1912 | 1912 |
| 1913 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, | 1913 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, |
| 1914 descriptor->CalleeSavedRegisters()); | 1914 descriptor->CalleeSavedRegisters()); |
| 1915 saved_count = saves.Count(); | 1915 saved_count = saves.Count(); |
| 1916 if (saved_count != 0) { | 1916 if (saved_count != 0) { |
| 1917 frame->AllocateSavedCalleeRegisterSlots(saved_count); | 1917 frame->AllocateSavedCalleeRegisterSlots(saved_count); |
| 1918 } | 1918 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1970 !descriptor->IsJSFunctionCall() && !descriptor->IsCFunctionCall(); | 1970 !descriptor->IsJSFunctionCall() && !descriptor->IsCFunctionCall(); |
| 1971 if (is_stub_frame) { | 1971 if (is_stub_frame) { |
| 1972 UseScratchRegisterScope temps(masm()); | 1972 UseScratchRegisterScope temps(masm()); |
| 1973 Register temp = temps.AcquireX(); | 1973 Register temp = temps.AcquireX(); |
| 1974 __ Mov(temp, StackFrame::TypeToMarker(info()->GetOutputStackFrameType())); | 1974 __ Mov(temp, StackFrame::TypeToMarker(info()->GetOutputStackFrameType())); |
| 1975 __ Str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); | 1975 __ Str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); |
| 1976 } | 1976 } |
| 1977 } | 1977 } |
| 1978 | 1978 |
| 1979 // Save FP registers. | 1979 // Save FP registers. |
| 1980 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 1980 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits, |
| 1981 descriptor->CalleeSavedFPRegisters()); | 1981 descriptor->CalleeSavedFPRegisters()); |
| 1982 int saved_count = saves_fp.Count(); | 1982 int saved_count = saves_fp.Count(); |
| 1983 if (saved_count != 0) { | 1983 if (saved_count != 0) { |
| 1984 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); | 1984 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedV().list()); |
| 1985 __ PushCPURegList(saves_fp); | 1985 __ PushCPURegList(saves_fp); |
| 1986 } | 1986 } |
| 1987 // Save registers. | 1987 // Save registers. |
| 1988 // TODO(palfia): TF save list is not in sync with | 1988 // TODO(palfia): TF save list is not in sync with |
| 1989 // CPURegList::GetCalleeSaved(): x30 is missing. | 1989 // CPURegList::GetCalleeSaved(): x30 is missing. |
| 1990 // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list()); | 1990 // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list()); |
| 1991 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, | 1991 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, |
| 1992 descriptor->CalleeSavedRegisters()); | 1992 descriptor->CalleeSavedRegisters()); |
| 1993 saved_count = saves.Count(); | 1993 saved_count = saves.Count(); |
| 1994 if (saved_count != 0) { | 1994 if (saved_count != 0) { |
| 1995 __ PushCPURegList(saves); | 1995 __ PushCPURegList(saves); |
| 1996 } | 1996 } |
| 1997 } | 1997 } |
| 1998 | 1998 |
| 1999 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { | 1999 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { |
| 2000 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2000 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 2001 | 2001 |
| 2002 // Restore registers. | 2002 // Restore registers. |
| 2003 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, | 2003 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, |
| 2004 descriptor->CalleeSavedRegisters()); | 2004 descriptor->CalleeSavedRegisters()); |
| 2005 if (saves.Count() != 0) { | 2005 if (saves.Count() != 0) { |
| 2006 __ PopCPURegList(saves); | 2006 __ PopCPURegList(saves); |
| 2007 } | 2007 } |
| 2008 | 2008 |
| 2009 // Restore fp registers. | 2009 // Restore fp registers. |
| 2010 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 2010 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits, |
| 2011 descriptor->CalleeSavedFPRegisters()); | 2011 descriptor->CalleeSavedFPRegisters()); |
| 2012 if (saves_fp.Count() != 0) { | 2012 if (saves_fp.Count() != 0) { |
| 2013 __ PopCPURegList(saves_fp); | 2013 __ PopCPURegList(saves_fp); |
| 2014 } | 2014 } |
| 2015 | 2015 |
| 2016 unwinding_info_writer_.MarkBlockWillExit(); | 2016 unwinding_info_writer_.MarkBlockWillExit(); |
| 2017 | 2017 |
| 2018 Arm64OperandConverter g(this, nullptr); | 2018 Arm64OperandConverter g(this, nullptr); |
| 2019 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 2019 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
| 2020 if (descriptor->IsCFunctionCall()) { | 2020 if (descriptor->IsCFunctionCall()) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2100 __ LoadObject(dst, src_object); | 2100 __ LoadObject(dst, src_object); |
| 2101 } | 2101 } |
| 2102 } else { | 2102 } else { |
| 2103 __ Mov(dst, g.ToImmediate(source)); | 2103 __ Mov(dst, g.ToImmediate(source)); |
| 2104 } | 2104 } |
| 2105 if (destination->IsStackSlot()) { | 2105 if (destination->IsStackSlot()) { |
| 2106 __ Str(dst, g.ToMemOperand(destination, masm())); | 2106 __ Str(dst, g.ToMemOperand(destination, masm())); |
| 2107 } | 2107 } |
| 2108 } else if (src.type() == Constant::kFloat32) { | 2108 } else if (src.type() == Constant::kFloat32) { |
| 2109 if (destination->IsFPRegister()) { | 2109 if (destination->IsFPRegister()) { |
| 2110 FPRegister dst = g.ToDoubleRegister(destination).S(); | 2110 VRegister dst = g.ToDoubleRegister(destination).S(); |
| 2111 __ Fmov(dst, src.ToFloat32()); | 2111 __ Fmov(dst, src.ToFloat32()); |
| 2112 } else { | 2112 } else { |
| 2113 DCHECK(destination->IsFPStackSlot()); | 2113 DCHECK(destination->IsFPStackSlot()); |
| 2114 if (bit_cast<int32_t>(src.ToFloat32()) == 0) { | 2114 if (bit_cast<int32_t>(src.ToFloat32()) == 0) { |
| 2115 __ Str(wzr, g.ToMemOperand(destination, masm())); | 2115 __ Str(wzr, g.ToMemOperand(destination, masm())); |
| 2116 } else { | 2116 } else { |
| 2117 UseScratchRegisterScope scope(masm()); | 2117 UseScratchRegisterScope scope(masm()); |
| 2118 FPRegister temp = scope.AcquireS(); | 2118 VRegister temp = scope.AcquireS(); |
| 2119 __ Fmov(temp, src.ToFloat32()); | 2119 __ Fmov(temp, src.ToFloat32()); |
| 2120 __ Str(temp, g.ToMemOperand(destination, masm())); | 2120 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 2121 } | 2121 } |
| 2122 } | 2122 } |
| 2123 } else { | 2123 } else { |
| 2124 DCHECK_EQ(Constant::kFloat64, src.type()); | 2124 DCHECK_EQ(Constant::kFloat64, src.type()); |
| 2125 if (destination->IsFPRegister()) { | 2125 if (destination->IsFPRegister()) { |
| 2126 FPRegister dst = g.ToDoubleRegister(destination); | 2126 VRegister dst = g.ToDoubleRegister(destination); |
| 2127 __ Fmov(dst, src.ToFloat64()); | 2127 __ Fmov(dst, src.ToFloat64()); |
| 2128 } else { | 2128 } else { |
| 2129 DCHECK(destination->IsFPStackSlot()); | 2129 DCHECK(destination->IsFPStackSlot()); |
| 2130 if (bit_cast<int64_t>(src.ToFloat64()) == 0) { | 2130 if (bit_cast<int64_t>(src.ToFloat64()) == 0) { |
| 2131 __ Str(xzr, g.ToMemOperand(destination, masm())); | 2131 __ Str(xzr, g.ToMemOperand(destination, masm())); |
| 2132 } else { | 2132 } else { |
| 2133 UseScratchRegisterScope scope(masm()); | 2133 UseScratchRegisterScope scope(masm()); |
| 2134 FPRegister temp = scope.AcquireD(); | 2134 VRegister temp = scope.AcquireD(); |
| 2135 __ Fmov(temp, src.ToFloat64()); | 2135 __ Fmov(temp, src.ToFloat64()); |
| 2136 __ Str(temp, g.ToMemOperand(destination, masm())); | 2136 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 2137 } | 2137 } |
| 2138 } | 2138 } |
| 2139 } | 2139 } |
| 2140 } else if (source->IsFPRegister()) { | 2140 } else if (source->IsFPRegister()) { |
| 2141 FPRegister src = g.ToDoubleRegister(source); | 2141 VRegister src = g.ToDoubleRegister(source); |
| 2142 if (destination->IsFPRegister()) { | 2142 if (destination->IsFPRegister()) { |
| 2143 FPRegister dst = g.ToDoubleRegister(destination); | 2143 VRegister dst = g.ToDoubleRegister(destination); |
| 2144 __ Fmov(dst, src); | 2144 __ Fmov(dst, src); |
| 2145 } else { | 2145 } else { |
| 2146 DCHECK(destination->IsFPStackSlot()); | 2146 DCHECK(destination->IsFPStackSlot()); |
| 2147 __ Str(src, g.ToMemOperand(destination, masm())); | 2147 __ Str(src, g.ToMemOperand(destination, masm())); |
| 2148 } | 2148 } |
| 2149 } else if (source->IsFPStackSlot()) { | 2149 } else if (source->IsFPStackSlot()) { |
| 2150 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); | 2150 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
| 2151 MemOperand src = g.ToMemOperand(source, masm()); | 2151 MemOperand src = g.ToMemOperand(source, masm()); |
| 2152 if (destination->IsFPRegister()) { | 2152 if (destination->IsFPRegister()) { |
| 2153 __ Ldr(g.ToDoubleRegister(destination), src); | 2153 __ Ldr(g.ToDoubleRegister(destination), src); |
| 2154 } else { | 2154 } else { |
| 2155 UseScratchRegisterScope scope(masm()); | 2155 UseScratchRegisterScope scope(masm()); |
| 2156 FPRegister temp = scope.AcquireD(); | 2156 VRegister temp = scope.AcquireD(); |
| 2157 __ Ldr(temp, src); | 2157 __ Ldr(temp, src); |
| 2158 __ Str(temp, g.ToMemOperand(destination, masm())); | 2158 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 2159 } | 2159 } |
| 2160 } else { | 2160 } else { |
| 2161 UNREACHABLE(); | 2161 UNREACHABLE(); |
| 2162 } | 2162 } |
| 2163 } | 2163 } |
| 2164 | 2164 |
| 2165 | 2165 |
| 2166 void CodeGenerator::AssembleSwap(InstructionOperand* source, | 2166 void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2190 DoubleRegister temp_0 = scope.AcquireD(); | 2190 DoubleRegister temp_0 = scope.AcquireD(); |
| 2191 DoubleRegister temp_1 = scope.AcquireD(); | 2191 DoubleRegister temp_1 = scope.AcquireD(); |
| 2192 MemOperand src = g.ToMemOperand(source, masm()); | 2192 MemOperand src = g.ToMemOperand(source, masm()); |
| 2193 MemOperand dst = g.ToMemOperand(destination, masm()); | 2193 MemOperand dst = g.ToMemOperand(destination, masm()); |
| 2194 __ Ldr(temp_0, src); | 2194 __ Ldr(temp_0, src); |
| 2195 __ Ldr(temp_1, dst); | 2195 __ Ldr(temp_1, dst); |
| 2196 __ Str(temp_0, dst); | 2196 __ Str(temp_0, dst); |
| 2197 __ Str(temp_1, src); | 2197 __ Str(temp_1, src); |
| 2198 } else if (source->IsFPRegister()) { | 2198 } else if (source->IsFPRegister()) { |
| 2199 UseScratchRegisterScope scope(masm()); | 2199 UseScratchRegisterScope scope(masm()); |
| 2200 FPRegister temp = scope.AcquireD(); | 2200 VRegister temp = scope.AcquireD(); |
| 2201 FPRegister src = g.ToDoubleRegister(source); | 2201 VRegister src = g.ToDoubleRegister(source); |
| 2202 if (destination->IsFPRegister()) { | 2202 if (destination->IsFPRegister()) { |
| 2203 FPRegister dst = g.ToDoubleRegister(destination); | 2203 VRegister dst = g.ToDoubleRegister(destination); |
| 2204 __ Fmov(temp, src); | 2204 __ Fmov(temp, src); |
| 2205 __ Fmov(src, dst); | 2205 __ Fmov(src, dst); |
| 2206 __ Fmov(dst, temp); | 2206 __ Fmov(dst, temp); |
| 2207 } else { | 2207 } else { |
| 2208 DCHECK(destination->IsFPStackSlot()); | 2208 DCHECK(destination->IsFPStackSlot()); |
| 2209 MemOperand dst = g.ToMemOperand(destination, masm()); | 2209 MemOperand dst = g.ToMemOperand(destination, masm()); |
| 2210 __ Fmov(temp, src); | 2210 __ Fmov(temp, src); |
| 2211 __ Ldr(src, dst); | 2211 __ Ldr(src, dst); |
| 2212 __ Str(temp, dst); | 2212 __ Str(temp, dst); |
| 2213 } | 2213 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2245 padding_size -= kInstructionSize; | 2245 padding_size -= kInstructionSize; |
| 2246 } | 2246 } |
| 2247 } | 2247 } |
| 2248 } | 2248 } |
| 2249 | 2249 |
| 2250 #undef __ | 2250 #undef __ |
| 2251 | 2251 |
| 2252 } // namespace compiler | 2252 } // namespace compiler |
| 2253 } // namespace internal | 2253 } // namespace internal |
| 2254 } // namespace v8 | 2254 } // namespace v8 |
| OLD | NEW |