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 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 i.TempRegister(0), i.TempRegister(1), | 765 i.TempRegister(0), i.TempRegister(1), |
766 i.TempRegister(2)); | 766 i.TempRegister(2)); |
767 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 767 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
768 __ Jump(x10); | 768 __ Jump(x10); |
769 frame_access_state()->ClearSPDelta(); | 769 frame_access_state()->ClearSPDelta(); |
770 frame_access_state()->SetFrameAccessToDefault(); | 770 frame_access_state()->SetFrameAccessToDefault(); |
771 break; | 771 break; |
772 } | 772 } |
773 case kArchPrepareCallCFunction: | 773 case kArchPrepareCallCFunction: |
774 // We don't need kArchPrepareCallCFunction on arm64 as the instruction | 774 // We don't need kArchPrepareCallCFunction on arm64 as the instruction |
775 // selector already perform a Claim to reserve space on the stack and | 775 // selector has already performed a Claim to reserve space on the stack. |
776 // guarantee correct alignment of stack pointer. | 776 // Frame alignment is always 16 bytes, and the stack pointer is already |
| 777 // 16-byte aligned, therefore we do not need to align the stack pointer |
| 778 // by an unknown value, and it is safe to continue accessing the frame |
| 779 // via the stack pointer. |
777 UNREACHABLE(); | 780 UNREACHABLE(); |
778 break; | 781 break; |
779 case kArchPrepareTailCall: | 782 case kArchPrepareTailCall: |
780 AssemblePrepareTailCall(); | 783 AssemblePrepareTailCall(); |
781 break; | 784 break; |
782 case kArchCallCFunction: { | 785 case kArchCallCFunction: { |
783 int const num_parameters = MiscField::decode(instr->opcode()); | 786 int const num_parameters = MiscField::decode(instr->opcode()); |
784 if (instr->InputAt(0)->IsImmediate()) { | 787 if (instr->InputAt(0)->IsImmediate()) { |
785 ExternalReference ref = i.InputExternalReference(0); | 788 ExternalReference ref = i.InputExternalReference(0); |
786 __ CallCFunction(ref, num_parameters, 0); | 789 __ CallCFunction(ref, num_parameters, 0); |
787 } else { | 790 } else { |
788 Register func = i.InputRegister(0); | 791 Register func = i.InputRegister(0); |
789 __ CallCFunction(func, num_parameters, 0); | 792 __ CallCFunction(func, num_parameters, 0); |
790 } | 793 } |
791 // CallCFunction only supports register arguments so we never need to call | 794 frame_access_state()->SetFrameAccessToDefault(); |
792 // frame()->ClearOutgoingParameterSlots() here. | 795 frame_access_state()->ClearSPDelta(); |
793 DCHECK(frame_access_state()->sp_delta() == 0); | |
794 break; | 796 break; |
795 } | 797 } |
796 case kArchJmp: | 798 case kArchJmp: |
797 AssembleArchJump(i.InputRpo(0)); | 799 AssembleArchJump(i.InputRpo(0)); |
798 break; | 800 break; |
799 case kArchTableSwitch: | 801 case kArchTableSwitch: |
800 AssembleArchTableSwitch(instr); | 802 AssembleArchTableSwitch(instr); |
801 break; | 803 break; |
802 case kArchLookupSwitch: | 804 case kArchLookupSwitch: |
803 AssembleArchLookupSwitch(instr); | 805 AssembleArchLookupSwitch(instr); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 break; | 1223 break; |
1222 case kArm64CompareAndBranch32: | 1224 case kArm64CompareAndBranch32: |
1223 case kArm64CompareAndBranch: | 1225 case kArm64CompareAndBranch: |
1224 // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch. | 1226 // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch. |
1225 break; | 1227 break; |
1226 case kArm64ClaimCSP: { | 1228 case kArm64ClaimCSP: { |
1227 int count = RoundUp(i.InputInt32(0), 2); | 1229 int count = RoundUp(i.InputInt32(0), 2); |
1228 Register prev = __ StackPointer(); | 1230 Register prev = __ StackPointer(); |
1229 if (prev.Is(jssp)) { | 1231 if (prev.Is(jssp)) { |
1230 // TODO(titzer): make this a macro-assembler method. | 1232 // TODO(titzer): make this a macro-assembler method. |
1231 // Align the CSP and store the previous JSSP on the stack. | 1233 // Align the CSP and store the previous JSSP on the stack. We do not |
| 1234 // need to modify the SP delta here, as we will continue to access the |
| 1235 // frame via JSSP. |
1232 UseScratchRegisterScope scope(masm()); | 1236 UseScratchRegisterScope scope(masm()); |
1233 Register tmp = scope.AcquireX(); | 1237 Register tmp = scope.AcquireX(); |
1234 | 1238 |
| 1239 // TODO(arm64): Storing JSSP on the stack is redundant when calling a C |
| 1240 // function, as JSSP is callee-saved (we still need to do this when |
| 1241 // calling a code object that uses the CSP as the stack pointer). See |
| 1242 // the code generation for kArchCallCodeObject vs. kArchCallCFunction |
| 1243 // (the latter does not restore CSP/JSSP). |
| 1244 // MacroAssembler::CallCFunction() (safely) drops this extra slot |
| 1245 // anyway. |
1235 int sp_alignment = __ ActivationFrameAlignment(); | 1246 int sp_alignment = __ ActivationFrameAlignment(); |
1236 __ Sub(tmp, jssp, kPointerSize); | 1247 __ Sub(tmp, jssp, kPointerSize); |
1237 __ And(tmp, tmp, Operand(~static_cast<uint64_t>(sp_alignment - 1))); | 1248 __ Bic(csp, tmp, sp_alignment - 1); |
1238 __ Mov(csp, tmp); | |
1239 __ Str(jssp, MemOperand(csp)); | 1249 __ Str(jssp, MemOperand(csp)); |
1240 if (count > 0) { | 1250 if (count > 0) { |
1241 __ SetStackPointer(csp); | 1251 __ SetStackPointer(csp); |
1242 __ Claim(count); | 1252 __ Claim(count); |
1243 __ SetStackPointer(prev); | 1253 __ SetStackPointer(prev); |
1244 } | 1254 } |
1245 } else { | 1255 } else { |
1246 __ AssertCspAligned(); | 1256 __ AssertCspAligned(); |
1247 if (count > 0) { | 1257 if (count > 0) { |
1248 __ Claim(count); | 1258 __ Claim(count); |
1249 frame_access_state()->IncreaseSPDelta(count); | 1259 frame_access_state()->IncreaseSPDelta(count); |
1250 } | 1260 } |
1251 } | 1261 } |
1252 break; | 1262 break; |
1253 } | 1263 } |
1254 case kArm64ClaimJSSP: { | 1264 case kArm64ClaimJSSP: { |
1255 int count = i.InputInt32(0); | 1265 int count = i.InputInt32(0); |
1256 if (csp.Is(__ StackPointer())) { | 1266 if (csp.Is(__ StackPointer())) { |
1257 // No JSSP is set up. Compute it from the CSP. | 1267 // No JSSP is set up. Compute it from the CSP. |
1258 __ AssertCspAligned(); | 1268 __ AssertCspAligned(); |
1259 if (count > 0) { | 1269 if (count > 0) { |
1260 int even = RoundUp(count, 2); | 1270 int even = RoundUp(count, 2); |
1261 __ Sub(jssp, csp, count * kPointerSize); | 1271 __ Sub(jssp, csp, count * kPointerSize); |
| 1272 // We must also update CSP to maintain stack consistency: |
1262 __ Sub(csp, csp, even * kPointerSize); // Must always be aligned. | 1273 __ Sub(csp, csp, even * kPointerSize); // Must always be aligned. |
| 1274 __ AssertStackConsistency(); |
1263 frame_access_state()->IncreaseSPDelta(even); | 1275 frame_access_state()->IncreaseSPDelta(even); |
1264 } else { | 1276 } else { |
1265 __ Mov(jssp, csp); | 1277 __ Mov(jssp, csp); |
1266 } | 1278 } |
1267 } else { | 1279 } else { |
1268 // JSSP is the current stack pointer, just use regular Claim(). | 1280 // JSSP is the current stack pointer, just use regular Claim(). |
1269 __ Claim(count); | 1281 __ Claim(count); |
1270 frame_access_state()->IncreaseSPDelta(count); | 1282 frame_access_state()->IncreaseSPDelta(count); |
1271 } | 1283 } |
1272 break; | 1284 break; |
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2282 padding_size -= kInstructionSize; | 2294 padding_size -= kInstructionSize; |
2283 } | 2295 } |
2284 } | 2296 } |
2285 } | 2297 } |
2286 | 2298 |
2287 #undef __ | 2299 #undef __ |
2288 | 2300 |
2289 } // namespace compiler | 2301 } // namespace compiler |
2290 } // namespace internal | 2302 } // namespace internal |
2291 } // namespace v8 | 2303 } // namespace v8 |
OLD | NEW |