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 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 __ mr(r5, r4); | 1082 __ mr(r5, r4); |
1083 __ mr(r4, r3); | 1083 __ mr(r4, r3); |
1084 __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize)); | 1084 __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize)); |
1085 isolate_reg = r6; | 1085 isolate_reg = r6; |
1086 } | 1086 } |
1087 | 1087 |
1088 // Call C built-in. | 1088 // Call C built-in. |
1089 __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate()))); | 1089 __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate()))); |
1090 | 1090 |
1091 Register target = r15; | 1091 Register target = r15; |
1092 #if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR) | 1092 if (ABI_USES_FUNCTION_DESCRIPTORS) { |
1093 // Native AIX/PPC64 Linux use a function descriptor. | 1093 // AIX/PPC64BE Linux use a function descriptor. |
1094 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize)); | 1094 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize)); |
1095 __ LoadP(ip, MemOperand(r15, 0)); // Instruction address | 1095 __ LoadP(ip, MemOperand(r15, 0)); // Instruction address |
1096 target = ip; | 1096 target = ip; |
1097 #elif ABI_CALL_VIA_IP | 1097 } else if (ABI_CALL_VIA_IP) { |
1098 __ Move(ip, r15); | 1098 __ Move(ip, r15); |
1099 target = ip; | 1099 target = ip; |
1100 #endif | 1100 } |
1101 | 1101 |
1102 // 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 |
1103 // know where the return address is. The CEntryStub is unmovable, so | 1103 // know where the return address is. The CEntryStub is unmovable, so |
1104 // 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 |
1105 // we never have to restore it, because it will not change. | 1105 // we never have to restore it, because it will not change. |
1106 Label after_call; | 1106 Label after_call; |
1107 __ mov_label_addr(r0, &after_call); | 1107 __ mov_label_addr(r0, &after_call); |
1108 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); | 1108 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); |
1109 __ Call(target); | 1109 __ Call(target); |
1110 __ bind(&after_call); | 1110 __ bind(&after_call); |
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2244 | 2244 |
2245 // Argument 2 (r4): Previous index. | 2245 // Argument 2 (r4): Previous index. |
2246 // Already there | 2246 // Already there |
2247 | 2247 |
2248 // Argument 1 (r3): Subject string. | 2248 // Argument 1 (r3): Subject string. |
2249 __ mr(r3, subject); | 2249 __ mr(r3, subject); |
2250 | 2250 |
2251 // Locate the code entry and call it. | 2251 // Locate the code entry and call it. |
2252 __ addi(code, code, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2252 __ addi(code, code, Operand(Code::kHeaderSize - kHeapObjectTag)); |
2253 | 2253 |
2254 | |
2255 #if ABI_USES_FUNCTION_DESCRIPTORS && defined(USE_SIMULATOR) | |
2256 // Even Simulated AIX/PPC64 Linux uses a function descriptor for the | |
2257 // RegExp routine. Extract the instruction address here since | |
2258 // DirectCEntryStub::GenerateCall will not do it for calls out to | |
2259 // what it thinks is C code compiled for the simulator/host | |
2260 // platform. | |
2261 __ LoadP(code, MemOperand(code, 0)); // Instruction address | |
2262 #endif | |
2263 | |
2264 DirectCEntryStub stub(isolate()); | 2254 DirectCEntryStub stub(isolate()); |
2265 stub.GenerateCall(masm, code); | 2255 stub.GenerateCall(masm, code); |
2266 | 2256 |
2267 __ LeaveExitFrame(false, no_reg, true); | 2257 __ LeaveExitFrame(false, no_reg, true); |
2268 | 2258 |
2269 // r3: result (int32) | 2259 // r3: result (int32) |
2270 // subject: subject string (callee saved) | 2260 // subject: subject string (callee saved) |
2271 // regexp_data: RegExp data (callee saved) | 2261 // regexp_data: RegExp data (callee saved) |
2272 // last_match_info_elements: Last match info elements (callee saved) | 2262 // last_match_info_elements: Last match info elements (callee saved) |
2273 // Check the result. | 2263 // Check the result. |
(...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3809 __ mflr(r0); | 3799 __ mflr(r0); |
3810 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); | 3800 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); |
3811 __ Call(ip); // Call the C++ function. | 3801 __ Call(ip); // Call the C++ function. |
3812 __ LoadP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); | 3802 __ LoadP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); |
3813 __ mtlr(r0); | 3803 __ mtlr(r0); |
3814 __ blr(); | 3804 __ blr(); |
3815 } | 3805 } |
3816 | 3806 |
3817 | 3807 |
3818 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, Register target) { | 3808 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, Register target) { |
3819 #if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR) | 3809 if (ABI_USES_FUNCTION_DESCRIPTORS) { |
3820 // Native AIX/PPC64 Linux use a function descriptor. | 3810 // AIX/PPC64BE Linux use a function descriptor. |
3821 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(target, kPointerSize)); | 3811 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(target, kPointerSize)); |
3822 __ LoadP(ip, MemOperand(target, 0)); // Instruction address | 3812 __ LoadP(ip, MemOperand(target, 0)); // Instruction address |
3823 #else | 3813 } else { |
3824 // ip needs to be set for DirectCEentryStub::Generate, and also | 3814 // ip needs to be set for DirectCEentryStub::Generate, and also |
3825 // for ABI_CALL_VIA_IP. | 3815 // for ABI_CALL_VIA_IP. |
3826 __ Move(ip, target); | 3816 __ Move(ip, target); |
3827 #endif | 3817 } |
3828 | 3818 |
3829 intptr_t code = reinterpret_cast<intptr_t>(GetCode().location()); | 3819 intptr_t code = reinterpret_cast<intptr_t>(GetCode().location()); |
3830 __ mov(r0, Operand(code, RelocInfo::CODE_TARGET)); | 3820 __ mov(r0, Operand(code, RelocInfo::CODE_TARGET)); |
3831 __ Call(r0); // Call the stub. | 3821 __ Call(r0); // Call the stub. |
3832 } | 3822 } |
3833 | 3823 |
3834 | 3824 |
3835 void NameDictionaryLookupStub::GenerateNegativeLookup( | 3825 void NameDictionaryLookupStub::GenerateNegativeLookup( |
3836 MacroAssembler* masm, Label* miss, Label* done, Register receiver, | 3826 MacroAssembler* masm, Label* miss, Label* done, Register receiver, |
3837 Register properties, Handle<Name> name, Register scratch0) { | 3827 Register properties, Handle<Name> name, Register scratch0) { |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4780 int frame_alignment = masm->ActivationFrameAlignment(); | 4770 int frame_alignment = masm->ActivationFrameAlignment(); |
4781 if (frame_alignment > kPointerSize) { | 4771 if (frame_alignment > kPointerSize) { |
4782 __ mr(r15, sp); | 4772 __ mr(r15, sp); |
4783 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); | 4773 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); |
4784 __ ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment))); | 4774 __ ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment))); |
4785 } | 4775 } |
4786 | 4776 |
4787 #if !defined(USE_SIMULATOR) | 4777 #if !defined(USE_SIMULATOR) |
4788 uintptr_t entry_hook = | 4778 uintptr_t entry_hook = |
4789 reinterpret_cast<uintptr_t>(isolate()->function_entry_hook()); | 4779 reinterpret_cast<uintptr_t>(isolate()->function_entry_hook()); |
| 4780 #else |
| 4781 // Under the simulator we need to indirect the entry hook through a |
| 4782 // trampoline function at a known address. |
| 4783 ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline)); |
| 4784 ExternalReference entry_hook = ExternalReference( |
| 4785 &dispatcher, ExternalReference::BUILTIN_CALL, isolate()); |
| 4786 |
| 4787 // It additionally takes an isolate as a third parameter |
| 4788 __ mov(r5, Operand(ExternalReference::isolate_address(isolate()))); |
| 4789 #endif |
| 4790 |
4790 __ mov(ip, Operand(entry_hook)); | 4791 __ mov(ip, Operand(entry_hook)); |
4791 | 4792 |
4792 #if ABI_USES_FUNCTION_DESCRIPTORS | 4793 if (ABI_USES_FUNCTION_DESCRIPTORS) { |
4793 // Function descriptor | 4794 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(ip, kPointerSize)); |
4794 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(ip, kPointerSize)); | 4795 __ LoadP(ip, MemOperand(ip, 0)); |
4795 __ LoadP(ip, MemOperand(ip, 0)); | 4796 } |
4796 #elif ABI_CALL_VIA_IP | 4797 // ip set above, so nothing more to do for ABI_CALL_VIA_IP. |
4797 // ip set above, so nothing to do. | |
4798 #endif | |
4799 | 4798 |
4800 // PPC LINUX ABI: | 4799 // PPC LINUX ABI: |
4801 __ li(r0, Operand::Zero()); | 4800 __ li(r0, Operand::Zero()); |
4802 __ StorePU(r0, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize)); | 4801 __ StorePU(r0, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize)); |
4803 #else | |
4804 // Under the simulator we need to indirect the entry hook through a | |
4805 // trampoline function at a known address. | |
4806 // It additionally takes an isolate as a third parameter | |
4807 __ mov(r5, Operand(ExternalReference::isolate_address(isolate()))); | |
4808 | 4802 |
4809 ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline)); | |
4810 __ mov(ip, Operand(ExternalReference( | |
4811 &dispatcher, ExternalReference::BUILTIN_CALL, isolate()))); | |
4812 #endif | |
4813 __ Call(ip); | 4803 __ Call(ip); |
4814 | 4804 |
4815 #if !defined(USE_SIMULATOR) | |
4816 __ addi(sp, sp, Operand(kNumRequiredStackFrameSlots * kPointerSize)); | 4805 __ addi(sp, sp, Operand(kNumRequiredStackFrameSlots * kPointerSize)); |
4817 #endif | |
4818 | 4806 |
4819 // Restore the stack pointer if needed. | 4807 // Restore the stack pointer if needed. |
4820 if (frame_alignment > kPointerSize) { | 4808 if (frame_alignment > kPointerSize) { |
4821 __ mr(sp, r15); | 4809 __ mr(sp, r15); |
4822 } | 4810 } |
4823 | 4811 |
4824 // Also pop lr to get Ret(0). | 4812 // Also pop lr to get Ret(0). |
4825 __ MultiPop(kSavedRegs | ip.bit()); | 4813 __ MultiPop(kSavedRegs | ip.bit()); |
4826 __ mtlr(ip); | 4814 __ mtlr(ip); |
4827 __ Ret(); | 4815 __ Ret(); |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5597 | 5585 |
5598 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 5586 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
5599 // ----------- S t a t e ------------- | 5587 // ----------- S t a t e ------------- |
5600 // -- sp[0] : name | 5588 // -- sp[0] : name |
5601 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object | 5589 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object |
5602 // -- ... | 5590 // -- ... |
5603 // -- r5 : api_function_address | 5591 // -- r5 : api_function_address |
5604 // ----------------------------------- | 5592 // ----------------------------------- |
5605 | 5593 |
5606 Register api_function_address = ApiGetterDescriptor::function_address(); | 5594 Register api_function_address = ApiGetterDescriptor::function_address(); |
| 5595 int arg0Slot = 0; |
| 5596 int accessorInfoSlot = 0; |
| 5597 int apiStackSpace = 0; |
5607 DCHECK(api_function_address.is(r5)); | 5598 DCHECK(api_function_address.is(r5)); |
5608 | 5599 |
5609 __ mr(r3, sp); // r0 = Handle<Name> | 5600 __ mr(r3, sp); // r0 = Handle<Name> |
5610 __ addi(r4, r3, Operand(1 * kPointerSize)); // r4 = PCA | 5601 __ addi(r4, r3, Operand(1 * kPointerSize)); // r4 = PCA |
5611 | 5602 |
5612 // If ABI passes Handles (pointer-sized struct) in a register: | 5603 // If ABI passes Handles (pointer-sized struct) in a register: |
5613 // | 5604 // |
5614 // Create 2 extra slots on stack: | 5605 // Create 2 extra slots on stack: |
5615 // [0] space for DirectCEntryStub's LR save | 5606 // [0] space for DirectCEntryStub's LR save |
5616 // [1] AccessorInfo& | 5607 // [1] AccessorInfo& |
5617 // | 5608 // |
5618 // Otherwise: | 5609 // Otherwise: |
5619 // | 5610 // |
5620 // Create 3 extra slots on stack: | 5611 // Create 3 extra slots on stack: |
5621 // [0] space for DirectCEntryStub's LR save | 5612 // [0] space for DirectCEntryStub's LR save |
5622 // [1] copy of Handle (first arg) | 5613 // [1] copy of Handle (first arg) |
5623 // [2] AccessorInfo& | 5614 // [2] AccessorInfo& |
5624 #if ABI_PASSES_HANDLES_IN_REGS | 5615 if (ABI_PASSES_HANDLES_IN_REGS) { |
5625 const int kAccessorInfoSlot = kStackFrameExtraParamSlot + 1; | 5616 accessorInfoSlot = kStackFrameExtraParamSlot + 1; |
5626 const int kApiStackSpace = 2; | 5617 apiStackSpace = 2; |
5627 #else | 5618 } else { |
5628 const int kArg0Slot = kStackFrameExtraParamSlot + 1; | 5619 arg0Slot = kStackFrameExtraParamSlot + 1; |
5629 const int kAccessorInfoSlot = kArg0Slot + 1; | 5620 accessorInfoSlot = arg0Slot + 1; |
5630 const int kApiStackSpace = 3; | 5621 apiStackSpace = 3; |
5631 #endif | 5622 } |
5632 | 5623 |
5633 FrameScope frame_scope(masm, StackFrame::MANUAL); | 5624 FrameScope frame_scope(masm, StackFrame::MANUAL); |
5634 __ EnterExitFrame(false, kApiStackSpace); | 5625 __ EnterExitFrame(false, apiStackSpace); |
5635 | 5626 |
5636 #if !ABI_PASSES_HANDLES_IN_REGS | 5627 if (!ABI_PASSES_HANDLES_IN_REGS) { |
5637 // pass 1st arg by reference | 5628 // pass 1st arg by reference |
5638 __ StoreP(r3, MemOperand(sp, kArg0Slot * kPointerSize)); | 5629 __ StoreP(r3, MemOperand(sp, arg0Slot * kPointerSize)); |
5639 __ addi(r3, sp, Operand(kArg0Slot * kPointerSize)); | 5630 __ addi(r3, sp, Operand(arg0Slot * kPointerSize)); |
5640 #endif | 5631 } |
5641 | 5632 |
5642 // Create PropertyAccessorInfo instance on the stack above the exit frame with | 5633 // Create PropertyAccessorInfo instance on the stack above the exit frame with |
5643 // r4 (internal::Object** args_) as the data. | 5634 // r4 (internal::Object** args_) as the data. |
5644 __ StoreP(r4, MemOperand(sp, kAccessorInfoSlot * kPointerSize)); | 5635 __ StoreP(r4, MemOperand(sp, accessorInfoSlot * kPointerSize)); |
5645 // r4 = AccessorInfo& | 5636 // r4 = AccessorInfo& |
5646 __ addi(r4, sp, Operand(kAccessorInfoSlot * kPointerSize)); | 5637 __ addi(r4, sp, Operand(accessorInfoSlot * kPointerSize)); |
5647 | 5638 |
5648 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 5639 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
5649 | 5640 |
5650 ExternalReference thunk_ref = | 5641 ExternalReference thunk_ref = |
5651 ExternalReference::invoke_accessor_getter_callback(isolate()); | 5642 ExternalReference::invoke_accessor_getter_callback(isolate()); |
5652 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 5643 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
5653 kStackUnwindSpace, NULL, | 5644 kStackUnwindSpace, NULL, |
5654 MemOperand(fp, 6 * kPointerSize), NULL); | 5645 MemOperand(fp, 6 * kPointerSize), NULL); |
5655 } | 5646 } |
5656 | 5647 |
5657 | 5648 |
5658 #undef __ | 5649 #undef __ |
5659 } // namespace internal | 5650 } // namespace internal |
5660 } // namespace v8 | 5651 } // namespace v8 |
5661 | 5652 |
5662 #endif // V8_TARGET_ARCH_PPC | 5653 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |