OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 // Derive argv from the stack pointer so that it points to the first argument | 1097 // Derive argv from the stack pointer so that it points to the first argument |
1098 // (arg[argc-2]), or just below the receiver in case there are no arguments. | 1098 // (arg[argc-2]), or just below the receiver in case there are no arguments. |
1099 // - Adjust for the arg[] array. | 1099 // - Adjust for the arg[] array. |
1100 Register temp_argv = x11; | 1100 Register temp_argv = x11; |
1101 if (!argv_in_register()) { | 1101 if (!argv_in_register()) { |
1102 __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2)); | 1102 __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2)); |
1103 // - Adjust for the receiver. | 1103 // - Adjust for the receiver. |
1104 __ Sub(temp_argv, temp_argv, 1 * kPointerSize); | 1104 __ Sub(temp_argv, temp_argv, 1 * kPointerSize); |
1105 } | 1105 } |
1106 | 1106 |
1107 // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved | 1107 // Reserve three slots to preserve x21-x23 callee-saved registers. If the |
1108 // registers. | 1108 // result size is too large to be returned in registers then also reserve |
| 1109 // space for the return value. |
| 1110 int extra_stack_space = 3 + (result_size() <= 2 ? 0 : result_size()); |
| 1111 // Enter the exit frame. |
1109 FrameScope scope(masm, StackFrame::MANUAL); | 1112 FrameScope scope(masm, StackFrame::MANUAL); |
1110 __ EnterExitFrame(save_doubles(), x10, 3); | 1113 __ EnterExitFrame(save_doubles(), x10, extra_stack_space); |
1111 DCHECK(csp.Is(__ StackPointer())); | 1114 DCHECK(csp.Is(__ StackPointer())); |
1112 | 1115 |
1113 // Poke callee-saved registers into reserved space. | 1116 // Poke callee-saved registers into reserved space. |
1114 __ Poke(argv, 1 * kPointerSize); | 1117 __ Poke(argv, 1 * kPointerSize); |
1115 __ Poke(argc, 2 * kPointerSize); | 1118 __ Poke(argc, 2 * kPointerSize); |
1116 __ Poke(target, 3 * kPointerSize); | 1119 __ Poke(target, 3 * kPointerSize); |
1117 | 1120 |
| 1121 if (result_size() > 2) { |
| 1122 // Save the location of the return value into x8 for call. |
| 1123 __ Add(x8, __ StackPointer(), Operand(4 * kPointerSize)); |
| 1124 } |
| 1125 |
1118 // We normally only keep tagged values in callee-saved registers, as they | 1126 // We normally only keep tagged values in callee-saved registers, as they |
1119 // could be pushed onto the stack by called stubs and functions, and on the | 1127 // could be pushed onto the stack by called stubs and functions, and on the |
1120 // stack they can confuse the GC. However, we're only calling C functions | 1128 // stack they can confuse the GC. However, we're only calling C functions |
1121 // which can push arbitrary data onto the stack anyway, and so the GC won't | 1129 // which can push arbitrary data onto the stack anyway, and so the GC won't |
1122 // examine that part of the stack. | 1130 // examine that part of the stack. |
1123 __ Mov(argc, argc_input); | 1131 __ Mov(argc, argc_input); |
1124 __ Mov(target, target_input); | 1132 __ Mov(target, target_input); |
1125 __ Mov(argv, temp_argv); | 1133 __ Mov(argv, temp_argv); |
1126 | 1134 |
1127 // x21 : argv | 1135 // x21 : argv |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 __ Ldr(temp, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 1185 __ Ldr(temp, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
1178 __ Ldr(temp, MemOperand(temp, -static_cast<int64_t>(kXRegSize))); | 1186 __ Ldr(temp, MemOperand(temp, -static_cast<int64_t>(kXRegSize))); |
1179 __ Cmp(temp, x12); | 1187 __ Cmp(temp, x12); |
1180 __ Check(eq, kReturnAddressNotFoundInFrame); | 1188 __ Check(eq, kReturnAddressNotFoundInFrame); |
1181 } | 1189 } |
1182 | 1190 |
1183 // Call the builtin. | 1191 // Call the builtin. |
1184 __ Blr(target); | 1192 __ Blr(target); |
1185 __ Bind(&return_location); | 1193 __ Bind(&return_location); |
1186 | 1194 |
1187 // x0 result The return code from the call. | 1195 if (result_size() > 2) { |
| 1196 DCHECK_EQ(3, result_size()); |
| 1197 // Read result values stored on stack. |
| 1198 __ Ldr(x0, MemOperand(__ StackPointer(), 4 * kPointerSize)); |
| 1199 __ Ldr(x1, MemOperand(__ StackPointer(), 5 * kPointerSize)); |
| 1200 __ Ldr(x2, MemOperand(__ StackPointer(), 6 * kPointerSize)); |
| 1201 } |
| 1202 // Result returned in x0, x1:x0 or x2:x1:x0 - do not destroy these registers! |
| 1203 |
| 1204 // x0 result0 The return code from the call. |
| 1205 // x1 result1 For calls which return ObjectPair or ObjectTriple. |
| 1206 // x2 result2 For calls which return ObjectTriple. |
1188 // x21 argv | 1207 // x21 argv |
1189 // x22 argc | 1208 // x22 argc |
1190 // x23 target | 1209 // x23 target |
1191 const Register& result = x0; | 1210 const Register& result = x0; |
1192 | 1211 |
1193 // Check result for exception sentinel. | 1212 // Check result for exception sentinel. |
1194 Label exception_returned; | 1213 Label exception_returned; |
1195 __ CompareRoot(result, Heap::kExceptionRootIndex); | 1214 __ CompareRoot(result, Heap::kExceptionRootIndex); |
1196 __ B(eq, &exception_returned); | 1215 __ B(eq, &exception_returned); |
1197 | 1216 |
(...skipping 4637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5835 MemOperand(fp, 6 * kPointerSize), NULL); | 5854 MemOperand(fp, 6 * kPointerSize), NULL); |
5836 } | 5855 } |
5837 | 5856 |
5838 | 5857 |
5839 #undef __ | 5858 #undef __ |
5840 | 5859 |
5841 } // namespace internal | 5860 } // namespace internal |
5842 } // namespace v8 | 5861 } // namespace v8 |
5843 | 5862 |
5844 #endif // V8_TARGET_ARCH_ARM64 | 5863 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |