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 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
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 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 __ add(r4, r4, sp); | 1048 __ add(r4, r4, sp); |
1049 __ subi(r4, r4, Operand(kPointerSize)); | 1049 __ subi(r4, r4, Operand(kPointerSize)); |
1050 } | 1050 } |
1051 | 1051 |
1052 // Enter the exit frame that transitions from JavaScript to C++. | 1052 // Enter the exit frame that transitions from JavaScript to C++. |
1053 FrameScope scope(masm, StackFrame::MANUAL); | 1053 FrameScope scope(masm, StackFrame::MANUAL); |
1054 | 1054 |
1055 // Need at least one extra slot for return address location. | 1055 // Need at least one extra slot for return address location. |
1056 int arg_stack_space = 1; | 1056 int arg_stack_space = 1; |
1057 | 1057 |
1058 // PPC LINUX ABI: | |
1059 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | |
1060 // Pass buffer for return value on stack if necessary | 1058 // Pass buffer for return value on stack if necessary |
1061 if (result_size() > 1) { | 1059 bool needs_return_buffer = |
1062 DCHECK_EQ(2, result_size()); | 1060 result_size() > 2 || |
1063 arg_stack_space += 2; | 1061 (result_size() == 2 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS); |
| 1062 if (needs_return_buffer) { |
| 1063 arg_stack_space += result_size(); |
1064 } | 1064 } |
1065 #endif | |
1066 | 1065 |
1067 __ EnterExitFrame(save_doubles(), arg_stack_space); | 1066 __ EnterExitFrame(save_doubles(), arg_stack_space); |
1068 | 1067 |
1069 // Store a copy of argc in callee-saved registers for later. | 1068 // Store a copy of argc in callee-saved registers for later. |
1070 __ mr(r14, r3); | 1069 __ mr(r14, r3); |
1071 | 1070 |
1072 // r3, r14: number of arguments including receiver (C callee-saved) | 1071 // r3, r14: number of arguments including receiver (C callee-saved) |
1073 // r4: pointer to the first argument | 1072 // r4: pointer to the first argument |
1074 // r15: pointer to builtin function (C callee-saved) | 1073 // r15: pointer to builtin function (C callee-saved) |
1075 | 1074 |
1076 // Result returned in registers or stack, depending on result size and ABI. | 1075 // Result returned in registers or stack, depending on result size and ABI. |
1077 | 1076 |
1078 Register isolate_reg = r5; | 1077 Register isolate_reg = r5; |
1079 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | 1078 if (needs_return_buffer) { |
1080 if (result_size() > 1) { | 1079 // The return value is a non-scalar value. |
1081 // The return value is 16-byte non-scalar value. | |
1082 // Use frame storage reserved by calling function to pass return | 1080 // Use frame storage reserved by calling function to pass return |
1083 // buffer as implicit first argument. | 1081 // buffer as implicit first argument. |
1084 __ mr(r5, r4); | 1082 __ mr(r5, r4); |
1085 __ mr(r4, r3); | 1083 __ mr(r4, r3); |
1086 __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize)); | 1084 __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize)); |
1087 isolate_reg = r6; | 1085 isolate_reg = r6; |
1088 } | 1086 } |
1089 #endif | |
1090 | 1087 |
1091 // Call C built-in. | 1088 // Call C built-in. |
1092 __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate()))); | 1089 __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate()))); |
1093 | 1090 |
1094 Register target = r15; | 1091 Register target = r15; |
1095 #if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR) | 1092 #if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR) |
1096 // Native AIX/PPC64 Linux use a function descriptor. | 1093 // Native AIX/PPC64 Linux use a function descriptor. |
1097 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize)); | 1094 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize)); |
1098 __ LoadP(ip, MemOperand(r15, 0)); // Instruction address | 1095 __ LoadP(ip, MemOperand(r15, 0)); // Instruction address |
1099 target = ip; | 1096 target = ip; |
1100 #elif ABI_CALL_VIA_IP | 1097 #elif ABI_CALL_VIA_IP |
1101 __ Move(ip, r15); | 1098 __ Move(ip, r15); |
1102 target = ip; | 1099 target = ip; |
1103 #endif | 1100 #endif |
1104 | 1101 |
1105 // To let the GC traverse the return address of the exit frames, we need to | 1102 // To let the GC traverse the return address of the exit frames, we need to |
1106 // know where the return address is. The CEntryStub is unmovable, so | 1103 // know where the return address is. The CEntryStub is unmovable, so |
1107 // we can store the address on the stack to be able to find it again and | 1104 // we can store the address on the stack to be able to find it again and |
1108 // we never have to restore it, because it will not change. | 1105 // we never have to restore it, because it will not change. |
1109 Label after_call; | 1106 Label after_call; |
1110 __ mov_label_addr(r0, &after_call); | 1107 __ mov_label_addr(r0, &after_call); |
1111 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); | 1108 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); |
1112 __ Call(target); | 1109 __ Call(target); |
1113 __ bind(&after_call); | 1110 __ bind(&after_call); |
1114 | 1111 |
1115 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | |
1116 // If return value is on the stack, pop it to registers. | 1112 // If return value is on the stack, pop it to registers. |
1117 if (result_size() > 1) { | 1113 if (needs_return_buffer) { |
| 1114 if (result_size() > 2) __ LoadP(r5, MemOperand(r3, 2 * kPointerSize)); |
1118 __ LoadP(r4, MemOperand(r3, kPointerSize)); | 1115 __ LoadP(r4, MemOperand(r3, kPointerSize)); |
1119 __ LoadP(r3, MemOperand(r3)); | 1116 __ LoadP(r3, MemOperand(r3)); |
1120 } | 1117 } |
1121 #endif | |
1122 | 1118 |
1123 // Check result for exception sentinel. | 1119 // Check result for exception sentinel. |
1124 Label exception_returned; | 1120 Label exception_returned; |
1125 __ CompareRoot(r3, Heap::kExceptionRootIndex); | 1121 __ CompareRoot(r3, Heap::kExceptionRootIndex); |
1126 __ beq(&exception_returned); | 1122 __ beq(&exception_returned); |
1127 | 1123 |
1128 // Check that there is no pending exception, otherwise we | 1124 // Check that there is no pending exception, otherwise we |
1129 // should have returned the exception sentinel. | 1125 // should have returned the exception sentinel. |
1130 if (FLAG_debug_code) { | 1126 if (FLAG_debug_code) { |
1131 Label okay; | 1127 Label okay; |
1132 ExternalReference pending_exception_address( | 1128 ExternalReference pending_exception_address( |
1133 Isolate::kPendingExceptionAddress, isolate()); | 1129 Isolate::kPendingExceptionAddress, isolate()); |
1134 | 1130 |
1135 __ mov(r5, Operand(pending_exception_address)); | 1131 __ mov(r6, Operand(pending_exception_address)); |
1136 __ LoadP(r5, MemOperand(r5)); | 1132 __ LoadP(r6, MemOperand(r6)); |
1137 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | 1133 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); |
1138 // Cannot use check here as it attempts to generate call into runtime. | 1134 // Cannot use check here as it attempts to generate call into runtime. |
1139 __ beq(&okay); | 1135 __ beq(&okay); |
1140 __ stop("Unexpected pending exception"); | 1136 __ stop("Unexpected pending exception"); |
1141 __ bind(&okay); | 1137 __ bind(&okay); |
1142 } | 1138 } |
1143 | 1139 |
1144 // Exit C frame and return. | 1140 // Exit C frame and return. |
1145 // r3:r4: result | 1141 // r3:r4: result |
1146 // sp: stack pointer | 1142 // sp: stack pointer |
1147 // fp: frame pointer | 1143 // fp: frame pointer |
(...skipping 4509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5657 kStackUnwindSpace, NULL, | 5653 kStackUnwindSpace, NULL, |
5658 MemOperand(fp, 6 * kPointerSize), NULL); | 5654 MemOperand(fp, 6 * kPointerSize), NULL); |
5659 } | 5655 } |
5660 | 5656 |
5661 | 5657 |
5662 #undef __ | 5658 #undef __ |
5663 } // namespace internal | 5659 } // namespace internal |
5664 } // namespace v8 | 5660 } // namespace v8 |
5665 | 5661 |
5666 #endif // V8_TARGET_ARCH_PPC | 5662 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |