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 1660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1931 frame->AlignFrame(16); | 1931 frame->AlignFrame(16); |
1932 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1932 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1933 | 1933 |
1934 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { | 1934 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { |
1935 __ SetStackPointer(csp); | 1935 __ SetStackPointer(csp); |
1936 } else { | 1936 } else { |
1937 __ SetStackPointer(jssp); | 1937 __ SetStackPointer(jssp); |
1938 } | 1938 } |
1939 | 1939 |
1940 // Save FP registers. | 1940 // Save FP registers. |
1941 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits, | 1941 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, |
1942 descriptor->CalleeSavedFPRegisters()); | 1942 descriptor->CalleeSavedFPRegisters()); |
1943 int saved_count = saves_fp.Count(); | 1943 int saved_count = saves_fp.Count(); |
1944 if (saved_count != 0) { | 1944 if (saved_count != 0) { |
1945 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedV().list()); | 1945 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); |
1946 frame->AllocateSavedCalleeRegisterSlots(saved_count * | 1946 frame->AllocateSavedCalleeRegisterSlots(saved_count * |
1947 (kDoubleSize / kPointerSize)); | 1947 (kDoubleSize / kPointerSize)); |
1948 } | 1948 } |
1949 | 1949 |
1950 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, | 1950 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, |
1951 descriptor->CalleeSavedRegisters()); | 1951 descriptor->CalleeSavedRegisters()); |
1952 saved_count = saves.Count(); | 1952 saved_count = saves.Count(); |
1953 if (saved_count != 0) { | 1953 if (saved_count != 0) { |
1954 frame->AllocateSavedCalleeRegisterSlots(saved_count); | 1954 frame->AllocateSavedCalleeRegisterSlots(saved_count); |
1955 } | 1955 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 !descriptor->IsJSFunctionCall() && !descriptor->IsCFunctionCall(); | 2007 !descriptor->IsJSFunctionCall() && !descriptor->IsCFunctionCall(); |
2008 if (is_stub_frame) { | 2008 if (is_stub_frame) { |
2009 UseScratchRegisterScope temps(masm()); | 2009 UseScratchRegisterScope temps(masm()); |
2010 Register temp = temps.AcquireX(); | 2010 Register temp = temps.AcquireX(); |
2011 __ Mov(temp, StackFrame::TypeToMarker(info()->GetOutputStackFrameType())); | 2011 __ Mov(temp, StackFrame::TypeToMarker(info()->GetOutputStackFrameType())); |
2012 __ Str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); | 2012 __ Str(temp, MemOperand(fp, TypedFrameConstants::kFrameTypeOffset)); |
2013 } | 2013 } |
2014 } | 2014 } |
2015 | 2015 |
2016 // Save FP registers. | 2016 // Save FP registers. |
2017 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits, | 2017 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, |
2018 descriptor->CalleeSavedFPRegisters()); | 2018 descriptor->CalleeSavedFPRegisters()); |
2019 int saved_count = saves_fp.Count(); | 2019 int saved_count = saves_fp.Count(); |
2020 if (saved_count != 0) { | 2020 if (saved_count != 0) { |
2021 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedV().list()); | 2021 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); |
2022 __ PushCPURegList(saves_fp); | 2022 __ PushCPURegList(saves_fp); |
2023 } | 2023 } |
2024 // Save registers. | 2024 // Save registers. |
2025 // TODO(palfia): TF save list is not in sync with | 2025 // TODO(palfia): TF save list is not in sync with |
2026 // CPURegList::GetCalleeSaved(): x30 is missing. | 2026 // CPURegList::GetCalleeSaved(): x30 is missing. |
2027 // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list()); | 2027 // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list()); |
2028 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, | 2028 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, |
2029 descriptor->CalleeSavedRegisters()); | 2029 descriptor->CalleeSavedRegisters()); |
2030 saved_count = saves.Count(); | 2030 saved_count = saves.Count(); |
2031 if (saved_count != 0) { | 2031 if (saved_count != 0) { |
2032 __ PushCPURegList(saves); | 2032 __ PushCPURegList(saves); |
2033 } | 2033 } |
2034 } | 2034 } |
2035 | 2035 |
2036 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { | 2036 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { |
2037 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2037 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2038 | 2038 |
2039 // Restore registers. | 2039 // Restore registers. |
2040 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, | 2040 CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits, |
2041 descriptor->CalleeSavedRegisters()); | 2041 descriptor->CalleeSavedRegisters()); |
2042 if (saves.Count() != 0) { | 2042 if (saves.Count() != 0) { |
2043 __ PopCPURegList(saves); | 2043 __ PopCPURegList(saves); |
2044 } | 2044 } |
2045 | 2045 |
2046 // Restore fp registers. | 2046 // Restore fp registers. |
2047 CPURegList saves_fp = CPURegList(CPURegister::kVRegister, kDRegSizeInBits, | 2047 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, |
2048 descriptor->CalleeSavedFPRegisters()); | 2048 descriptor->CalleeSavedFPRegisters()); |
2049 if (saves_fp.Count() != 0) { | 2049 if (saves_fp.Count() != 0) { |
2050 __ PopCPURegList(saves_fp); | 2050 __ PopCPURegList(saves_fp); |
2051 } | 2051 } |
2052 | 2052 |
2053 unwinding_info_writer_.MarkBlockWillExit(); | 2053 unwinding_info_writer_.MarkBlockWillExit(); |
2054 | 2054 |
2055 Arm64OperandConverter g(this, nullptr); | 2055 Arm64OperandConverter g(this, nullptr); |
2056 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 2056 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
2057 if (descriptor->IsCFunctionCall()) { | 2057 if (descriptor->IsCFunctionCall()) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 __ LoadObject(dst, src_object); | 2137 __ LoadObject(dst, src_object); |
2138 } | 2138 } |
2139 } else { | 2139 } else { |
2140 __ Mov(dst, g.ToImmediate(source)); | 2140 __ Mov(dst, g.ToImmediate(source)); |
2141 } | 2141 } |
2142 if (destination->IsStackSlot()) { | 2142 if (destination->IsStackSlot()) { |
2143 __ Str(dst, g.ToMemOperand(destination, masm())); | 2143 __ Str(dst, g.ToMemOperand(destination, masm())); |
2144 } | 2144 } |
2145 } else if (src.type() == Constant::kFloat32) { | 2145 } else if (src.type() == Constant::kFloat32) { |
2146 if (destination->IsFPRegister()) { | 2146 if (destination->IsFPRegister()) { |
2147 VRegister dst = g.ToDoubleRegister(destination).S(); | 2147 FPRegister dst = g.ToDoubleRegister(destination).S(); |
2148 __ Fmov(dst, src.ToFloat32()); | 2148 __ Fmov(dst, src.ToFloat32()); |
2149 } else { | 2149 } else { |
2150 DCHECK(destination->IsFPStackSlot()); | 2150 DCHECK(destination->IsFPStackSlot()); |
2151 if (bit_cast<int32_t>(src.ToFloat32()) == 0) { | 2151 if (bit_cast<int32_t>(src.ToFloat32()) == 0) { |
2152 __ Str(wzr, g.ToMemOperand(destination, masm())); | 2152 __ Str(wzr, g.ToMemOperand(destination, masm())); |
2153 } else { | 2153 } else { |
2154 UseScratchRegisterScope scope(masm()); | 2154 UseScratchRegisterScope scope(masm()); |
2155 VRegister temp = scope.AcquireS(); | 2155 FPRegister temp = scope.AcquireS(); |
2156 __ Fmov(temp, src.ToFloat32()); | 2156 __ Fmov(temp, src.ToFloat32()); |
2157 __ Str(temp, g.ToMemOperand(destination, masm())); | 2157 __ Str(temp, g.ToMemOperand(destination, masm())); |
2158 } | 2158 } |
2159 } | 2159 } |
2160 } else { | 2160 } else { |
2161 DCHECK_EQ(Constant::kFloat64, src.type()); | 2161 DCHECK_EQ(Constant::kFloat64, src.type()); |
2162 if (destination->IsFPRegister()) { | 2162 if (destination->IsFPRegister()) { |
2163 VRegister dst = g.ToDoubleRegister(destination); | 2163 FPRegister dst = g.ToDoubleRegister(destination); |
2164 __ Fmov(dst, src.ToFloat64()); | 2164 __ Fmov(dst, src.ToFloat64()); |
2165 } else { | 2165 } else { |
2166 DCHECK(destination->IsFPStackSlot()); | 2166 DCHECK(destination->IsFPStackSlot()); |
2167 if (bit_cast<int64_t>(src.ToFloat64()) == 0) { | 2167 if (bit_cast<int64_t>(src.ToFloat64()) == 0) { |
2168 __ Str(xzr, g.ToMemOperand(destination, masm())); | 2168 __ Str(xzr, g.ToMemOperand(destination, masm())); |
2169 } else { | 2169 } else { |
2170 UseScratchRegisterScope scope(masm()); | 2170 UseScratchRegisterScope scope(masm()); |
2171 VRegister temp = scope.AcquireD(); | 2171 FPRegister temp = scope.AcquireD(); |
2172 __ Fmov(temp, src.ToFloat64()); | 2172 __ Fmov(temp, src.ToFloat64()); |
2173 __ Str(temp, g.ToMemOperand(destination, masm())); | 2173 __ Str(temp, g.ToMemOperand(destination, masm())); |
2174 } | 2174 } |
2175 } | 2175 } |
2176 } | 2176 } |
2177 } else if (source->IsFPRegister()) { | 2177 } else if (source->IsFPRegister()) { |
2178 VRegister src = g.ToDoubleRegister(source); | 2178 FPRegister src = g.ToDoubleRegister(source); |
2179 if (destination->IsFPRegister()) { | 2179 if (destination->IsFPRegister()) { |
2180 VRegister dst = g.ToDoubleRegister(destination); | 2180 FPRegister dst = g.ToDoubleRegister(destination); |
2181 __ Fmov(dst, src); | 2181 __ Fmov(dst, src); |
2182 } else { | 2182 } else { |
2183 DCHECK(destination->IsFPStackSlot()); | 2183 DCHECK(destination->IsFPStackSlot()); |
2184 __ Str(src, g.ToMemOperand(destination, masm())); | 2184 __ Str(src, g.ToMemOperand(destination, masm())); |
2185 } | 2185 } |
2186 } else if (source->IsFPStackSlot()) { | 2186 } else if (source->IsFPStackSlot()) { |
2187 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); | 2187 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
2188 MemOperand src = g.ToMemOperand(source, masm()); | 2188 MemOperand src = g.ToMemOperand(source, masm()); |
2189 if (destination->IsFPRegister()) { | 2189 if (destination->IsFPRegister()) { |
2190 __ Ldr(g.ToDoubleRegister(destination), src); | 2190 __ Ldr(g.ToDoubleRegister(destination), src); |
2191 } else { | 2191 } else { |
2192 UseScratchRegisterScope scope(masm()); | 2192 UseScratchRegisterScope scope(masm()); |
2193 VRegister temp = scope.AcquireD(); | 2193 FPRegister temp = scope.AcquireD(); |
2194 __ Ldr(temp, src); | 2194 __ Ldr(temp, src); |
2195 __ Str(temp, g.ToMemOperand(destination, masm())); | 2195 __ Str(temp, g.ToMemOperand(destination, masm())); |
2196 } | 2196 } |
2197 } else { | 2197 } else { |
2198 UNREACHABLE(); | 2198 UNREACHABLE(); |
2199 } | 2199 } |
2200 } | 2200 } |
2201 | 2201 |
2202 | 2202 |
2203 void CodeGenerator::AssembleSwap(InstructionOperand* source, | 2203 void CodeGenerator::AssembleSwap(InstructionOperand* source, |
(...skipping 23 matching lines...) Expand all Loading... |
2227 DoubleRegister temp_0 = scope.AcquireD(); | 2227 DoubleRegister temp_0 = scope.AcquireD(); |
2228 DoubleRegister temp_1 = scope.AcquireD(); | 2228 DoubleRegister temp_1 = scope.AcquireD(); |
2229 MemOperand src = g.ToMemOperand(source, masm()); | 2229 MemOperand src = g.ToMemOperand(source, masm()); |
2230 MemOperand dst = g.ToMemOperand(destination, masm()); | 2230 MemOperand dst = g.ToMemOperand(destination, masm()); |
2231 __ Ldr(temp_0, src); | 2231 __ Ldr(temp_0, src); |
2232 __ Ldr(temp_1, dst); | 2232 __ Ldr(temp_1, dst); |
2233 __ Str(temp_0, dst); | 2233 __ Str(temp_0, dst); |
2234 __ Str(temp_1, src); | 2234 __ Str(temp_1, src); |
2235 } else if (source->IsFPRegister()) { | 2235 } else if (source->IsFPRegister()) { |
2236 UseScratchRegisterScope scope(masm()); | 2236 UseScratchRegisterScope scope(masm()); |
2237 VRegister temp = scope.AcquireD(); | 2237 FPRegister temp = scope.AcquireD(); |
2238 VRegister src = g.ToDoubleRegister(source); | 2238 FPRegister src = g.ToDoubleRegister(source); |
2239 if (destination->IsFPRegister()) { | 2239 if (destination->IsFPRegister()) { |
2240 VRegister dst = g.ToDoubleRegister(destination); | 2240 FPRegister dst = g.ToDoubleRegister(destination); |
2241 __ Fmov(temp, src); | 2241 __ Fmov(temp, src); |
2242 __ Fmov(src, dst); | 2242 __ Fmov(src, dst); |
2243 __ Fmov(dst, temp); | 2243 __ Fmov(dst, temp); |
2244 } else { | 2244 } else { |
2245 DCHECK(destination->IsFPStackSlot()); | 2245 DCHECK(destination->IsFPStackSlot()); |
2246 MemOperand dst = g.ToMemOperand(destination, masm()); | 2246 MemOperand dst = g.ToMemOperand(destination, masm()); |
2247 __ Fmov(temp, src); | 2247 __ Fmov(temp, src); |
2248 __ Ldr(src, dst); | 2248 __ Ldr(src, dst); |
2249 __ Str(temp, dst); | 2249 __ Str(temp, dst); |
2250 } | 2250 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2282 padding_size -= kInstructionSize; | 2282 padding_size -= kInstructionSize; |
2283 } | 2283 } |
2284 } | 2284 } |
2285 } | 2285 } |
2286 | 2286 |
2287 #undef __ | 2287 #undef __ |
2288 | 2288 |
2289 } // namespace compiler | 2289 } // namespace compiler |
2290 } // namespace internal | 2290 } // namespace internal |
2291 } // namespace v8 | 2291 } // namespace v8 |
OLD | NEW |