| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 5 #if V8_TARGET_ARCH_ARM | 
| 6 | 6 | 
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" | 
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" | 
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" | 
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" | 
| (...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 992   FrameScope scope(masm, StackFrame::MANUAL); | 992   FrameScope scope(masm, StackFrame::MANUAL); | 
| 993   __ EnterExitFrame(save_doubles()); | 993   __ EnterExitFrame(save_doubles()); | 
| 994 | 994 | 
| 995   // Store a copy of argc in callee-saved registers for later. | 995   // Store a copy of argc in callee-saved registers for later. | 
| 996   __ mov(r4, Operand(r0)); | 996   __ mov(r4, Operand(r0)); | 
| 997 | 997 | 
| 998   // r0, r4: number of arguments including receiver  (C callee-saved) | 998   // r0, r4: number of arguments including receiver  (C callee-saved) | 
| 999   // r1: pointer to the first argument (C callee-saved) | 999   // r1: pointer to the first argument (C callee-saved) | 
| 1000   // r5: pointer to builtin function  (C callee-saved) | 1000   // r5: pointer to builtin function  (C callee-saved) | 
| 1001 | 1001 | 
| 1002   // Result returned in r0 or r0+r1 by default. |  | 
| 1003 |  | 
| 1004 #if V8_HOST_ARCH_ARM |  | 
| 1005   int frame_alignment = MacroAssembler::ActivationFrameAlignment(); | 1002   int frame_alignment = MacroAssembler::ActivationFrameAlignment(); | 
| 1006   int frame_alignment_mask = frame_alignment - 1; | 1003   int frame_alignment_mask = frame_alignment - 1; | 
|  | 1004 #if V8_HOST_ARCH_ARM | 
| 1007   if (FLAG_debug_code) { | 1005   if (FLAG_debug_code) { | 
| 1008     if (frame_alignment > kPointerSize) { | 1006     if (frame_alignment > kPointerSize) { | 
| 1009       Label alignment_as_expected; | 1007       Label alignment_as_expected; | 
| 1010       DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); | 1008       DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); | 
| 1011       __ tst(sp, Operand(frame_alignment_mask)); | 1009       __ tst(sp, Operand(frame_alignment_mask)); | 
| 1012       __ b(eq, &alignment_as_expected); | 1010       __ b(eq, &alignment_as_expected); | 
| 1013       // Don't use Check here, as it will call Runtime_Abort re-entering here. | 1011       // Don't use Check here, as it will call Runtime_Abort re-entering here. | 
| 1014       __ stop("Unexpected alignment"); | 1012       __ stop("Unexpected alignment"); | 
| 1015       __ bind(&alignment_as_expected); | 1013       __ bind(&alignment_as_expected); | 
| 1016     } | 1014     } | 
| 1017   } | 1015   } | 
| 1018 #endif | 1016 #endif | 
| 1019 | 1017 | 
| 1020   // Call C built-in. | 1018   // Call C built-in. | 
| 1021   // r0 = argc, r1 = argv | 1019   int result_stack_size; | 
| 1022   __ mov(r2, Operand(ExternalReference::isolate_address(isolate()))); | 1020   if (result_size() <= 2) { | 
|  | 1021     // r0 = argc, r1 = argv, r2 = isolate | 
|  | 1022     __ mov(r2, Operand(ExternalReference::isolate_address(isolate()))); | 
|  | 1023     result_stack_size = 0; | 
|  | 1024   } else { | 
|  | 1025     DCHECK_EQ(3, result_size()); | 
|  | 1026     // Allocate additional space for the result. | 
|  | 1027     result_stack_size = | 
|  | 1028         ((result_size() * kPointerSize) + frame_alignment_mask) & | 
|  | 1029         ~frame_alignment_mask; | 
|  | 1030     __ sub(sp, sp, Operand(result_stack_size)); | 
|  | 1031 | 
|  | 1032     // r0 = hidden result argument, r1 = argc, r2 = argv, r3 = isolate. | 
|  | 1033     __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); | 
|  | 1034     __ mov(r2, Operand(r1)); | 
|  | 1035     __ mov(r1, Operand(r0)); | 
|  | 1036     __ mov(r0, Operand(sp)); | 
|  | 1037   } | 
| 1023 | 1038 | 
| 1024   // To let the GC traverse the return address of the exit frames, we need to | 1039   // To let the GC traverse the return address of the exit frames, we need to | 
| 1025   // know where the return address is. The CEntryStub is unmovable, so | 1040   // know where the return address is. The CEntryStub is unmovable, so | 
| 1026   // we can store the address on the stack to be able to find it again and | 1041   // we can store the address on the stack to be able to find it again and | 
| 1027   // we never have to restore it, because it will not change. | 1042   // we never have to restore it, because it will not change. | 
| 1028   // Compute the return address in lr to return to after the jump below. Pc is | 1043   // Compute the return address in lr to return to after the jump below. Pc is | 
| 1029   // already at '+ 8' from the current instruction but return is after three | 1044   // already at '+ 8' from the current instruction but return is after three | 
| 1030   // instructions so add another 4 to pc to get the return address. | 1045   // instructions so add another 4 to pc to get the return address. | 
| 1031   { | 1046   { | 
| 1032     // Prevent literal pool emission before return address. | 1047     // Prevent literal pool emission before return address. | 
| 1033     Assembler::BlockConstPoolScope block_const_pool(masm); | 1048     Assembler::BlockConstPoolScope block_const_pool(masm); | 
| 1034     __ add(lr, pc, Operand(4)); | 1049     __ add(lr, pc, Operand(4)); | 
| 1035     __ str(lr, MemOperand(sp, 0)); | 1050     __ str(lr, MemOperand(sp, result_stack_size)); | 
| 1036     __ Call(r5); | 1051     __ Call(r5); | 
| 1037   } | 1052   } | 
|  | 1053   if (result_size() > 2) { | 
|  | 1054     DCHECK_EQ(3, result_size()); | 
|  | 1055     // Read result values stored on stack. | 
|  | 1056     __ ldr(r2, MemOperand(r0, 2 * kPointerSize)); | 
|  | 1057     __ ldr(r1, MemOperand(r0, 1 * kPointerSize)); | 
|  | 1058     __ ldr(r0, MemOperand(r0, 0 * kPointerSize)); | 
|  | 1059   } | 
|  | 1060   // Result returned in r0, r1:r0 or r2:r1:r0 - do not destroy these registers! | 
| 1038 | 1061 | 
| 1039   __ VFPEnsureFPSCRState(r2); | 1062   __ VFPEnsureFPSCRState(r3); | 
| 1040 | 1063 | 
| 1041   // Check result for exception sentinel. | 1064   // Check result for exception sentinel. | 
| 1042   Label exception_returned; | 1065   Label exception_returned; | 
| 1043   __ CompareRoot(r0, Heap::kExceptionRootIndex); | 1066   __ CompareRoot(r0, Heap::kExceptionRootIndex); | 
| 1044   __ b(eq, &exception_returned); | 1067   __ b(eq, &exception_returned); | 
| 1045 | 1068 | 
| 1046   // Check that there is no pending exception, otherwise we | 1069   // Check that there is no pending exception, otherwise we | 
| 1047   // should have returned the exception sentinel. | 1070   // should have returned the exception sentinel. | 
| 1048   if (FLAG_debug_code) { | 1071   if (FLAG_debug_code) { | 
| 1049     Label okay; | 1072     Label okay; | 
| 1050     ExternalReference pending_exception_address( | 1073     ExternalReference pending_exception_address( | 
| 1051         Isolate::kPendingExceptionAddress, isolate()); | 1074         Isolate::kPendingExceptionAddress, isolate()); | 
| 1052     __ mov(r2, Operand(pending_exception_address)); | 1075     __ mov(r3, Operand(pending_exception_address)); | 
| 1053     __ ldr(r2, MemOperand(r2)); | 1076     __ ldr(r3, MemOperand(r3)); | 
| 1054     __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 1077     __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 
| 1055     // Cannot use check here as it attempts to generate call into runtime. | 1078     // Cannot use check here as it attempts to generate call into runtime. | 
| 1056     __ b(eq, &okay); | 1079     __ b(eq, &okay); | 
| 1057     __ stop("Unexpected pending exception"); | 1080     __ stop("Unexpected pending exception"); | 
| 1058     __ bind(&okay); | 1081     __ bind(&okay); | 
| 1059   } | 1082   } | 
| 1060 | 1083 | 
| 1061   // Exit C frame and return. | 1084   // Exit C frame and return. | 
| 1062   // r0:r1: result | 1085   // r0:r1: result | 
| 1063   // sp: stack pointer | 1086   // sp: stack pointer | 
| 1064   // fp: frame pointer | 1087   // fp: frame pointer | 
| (...skipping 4319 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5384                            MemOperand(fp, 6 * kPointerSize), NULL); | 5407                            MemOperand(fp, 6 * kPointerSize), NULL); | 
| 5385 } | 5408 } | 
| 5386 | 5409 | 
| 5387 | 5410 | 
| 5388 #undef __ | 5411 #undef __ | 
| 5389 | 5412 | 
| 5390 }  // namespace internal | 5413 }  // namespace internal | 
| 5391 }  // namespace v8 | 5414 }  // namespace v8 | 
| 5392 | 5415 | 
| 5393 #endif  // V8_TARGET_ARCH_ARM | 5416 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|