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, 3)) { | 260 Assembler::IsImmLSScaled(from_sp, LSDoubleWord)) { |
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::kVRegister, kDRegSizeInBits, | 1904 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, 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::GetCalleeSavedV().list()); | 1908 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().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::kVRegister, kDRegSizeInBits, | 1980 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, 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::GetCalleeSavedV().list()); | 1984 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().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::kVRegister, kDRegSizeInBits, | 2010 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, 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 VRegister dst = g.ToDoubleRegister(destination).S(); | 2110 FPRegister 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 VRegister temp = scope.AcquireS(); | 2118 FPRegister 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 VRegister dst = g.ToDoubleRegister(destination); | 2126 FPRegister 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 VRegister temp = scope.AcquireD(); | 2134 FPRegister 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 VRegister src = g.ToDoubleRegister(source); | 2141 FPRegister src = g.ToDoubleRegister(source); |
2142 if (destination->IsFPRegister()) { | 2142 if (destination->IsFPRegister()) { |
2143 VRegister dst = g.ToDoubleRegister(destination); | 2143 FPRegister 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 VRegister temp = scope.AcquireD(); | 2156 FPRegister 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 VRegister temp = scope.AcquireD(); | 2200 FPRegister temp = scope.AcquireD(); |
2201 VRegister src = g.ToDoubleRegister(source); | 2201 FPRegister src = g.ToDoubleRegister(source); |
2202 if (destination->IsFPRegister()) { | 2202 if (destination->IsFPRegister()) { |
2203 VRegister dst = g.ToDoubleRegister(destination); | 2203 FPRegister 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 |