| 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 |