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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_PPC | 7 #if V8_TARGET_ARCH_PPC |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 __ Move(ip, r15); | 1063 __ Move(ip, r15); |
1064 Register target = ip; | 1064 Register target = ip; |
1065 #else | 1065 #else |
1066 Register target = r15; | 1066 Register target = r15; |
1067 #endif | 1067 #endif |
1068 | 1068 |
1069 // To let the GC traverse the return address of the exit frames, we need to | 1069 // To let the GC traverse the return address of the exit frames, we need to |
1070 // know where the return address is. The CEntryStub is unmovable, so | 1070 // know where the return address is. The CEntryStub is unmovable, so |
1071 // we can store the address on the stack to be able to find it again and | 1071 // we can store the address on the stack to be able to find it again and |
1072 // we never have to restore it, because it will not change. | 1072 // we never have to restore it, because it will not change. |
1073 // Compute the return address in lr to return to after the jump below. Pc is | 1073 Label after_call; |
1074 // already at '+ 8' from the current instruction but return is after three | 1074 __ mov_label_addr(r0, &after_call); |
1075 // instructions so add another 4 to pc to get the return address. | 1075 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); |
1076 { | 1076 __ Call(target); |
1077 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); | 1077 __ bind(&after_call); |
1078 Label here; | |
1079 __ b(&here, SetLK); | |
1080 __ bind(&here); | |
1081 __ mflr(r8); | |
1082 | |
1083 // Constant used below is dependent on size of Call() macro instructions | |
1084 __ addi(r0, r8, Operand(20)); | |
1085 | |
1086 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); | |
1087 __ Call(target); | |
1088 } | |
1089 | 1078 |
1090 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | 1079 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS |
1091 // If return value is on the stack, pop it to registers. | 1080 // If return value is on the stack, pop it to registers. |
1092 if (result_size() > 1) { | 1081 if (result_size() > 1) { |
1093 __ LoadP(r4, MemOperand(r3, kPointerSize)); | 1082 __ LoadP(r4, MemOperand(r3, kPointerSize)); |
1094 __ LoadP(r3, MemOperand(r3)); | 1083 __ LoadP(r3, MemOperand(r3)); |
1095 } | 1084 } |
1096 #endif | 1085 #endif |
1097 | 1086 |
1098 // Runtime functions should not return 'the hole'. Allowing it to escape may | 1087 // Runtime functions should not return 'the hole'. Allowing it to escape may |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 StubRuntimeCallHelper call_helper; | 1575 StubRuntimeCallHelper call_helper; |
1587 char_at_generator.GenerateSlow(masm, call_helper); | 1576 char_at_generator.GenerateSlow(masm, call_helper); |
1588 | 1577 |
1589 __ bind(&miss); | 1578 __ bind(&miss); |
1590 PropertyAccessCompiler::TailCallBuiltin( | 1579 PropertyAccessCompiler::TailCallBuiltin( |
1591 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 1580 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
1592 } | 1581 } |
1593 | 1582 |
1594 | 1583 |
1595 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { | 1584 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
| 1585 CHECK(!has_new_target()); |
1596 // The displacement is the offset of the last parameter (if any) | 1586 // The displacement is the offset of the last parameter (if any) |
1597 // relative to the frame pointer. | 1587 // relative to the frame pointer. |
1598 const int kDisplacement = | 1588 const int kDisplacement = |
1599 StandardFrameConstants::kCallerSPOffset - kPointerSize; | 1589 StandardFrameConstants::kCallerSPOffset - kPointerSize; |
1600 DCHECK(r4.is(ArgumentsAccessReadDescriptor::index())); | 1590 DCHECK(r4.is(ArgumentsAccessReadDescriptor::index())); |
1601 DCHECK(r3.is(ArgumentsAccessReadDescriptor::parameter_count())); | 1591 DCHECK(r3.is(ArgumentsAccessReadDescriptor::parameter_count())); |
1602 | 1592 |
1603 // Check that the key is a smi. | 1593 // Check that the key is a smi. |
1604 Label slow; | 1594 Label slow; |
1605 __ JumpIfNotSmi(r4, &slow); | 1595 __ JumpIfNotSmi(r4, &slow); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 __ push(r4); | 1636 __ push(r4); |
1647 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); | 1637 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); |
1648 } | 1638 } |
1649 | 1639 |
1650 | 1640 |
1651 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 1641 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
1652 // sp[0] : number of parameters | 1642 // sp[0] : number of parameters |
1653 // sp[1] : receiver displacement | 1643 // sp[1] : receiver displacement |
1654 // sp[2] : function | 1644 // sp[2] : function |
1655 | 1645 |
| 1646 CHECK(!has_new_target()); |
| 1647 |
1656 // Check if the calling frame is an arguments adaptor frame. | 1648 // Check if the calling frame is an arguments adaptor frame. |
1657 Label runtime; | 1649 Label runtime; |
1658 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1650 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1659 __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset)); | 1651 __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset)); |
1660 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); | 1652 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); |
1661 __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1653 __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1662 __ bne(&runtime); | 1654 __ bne(&runtime); |
1663 | 1655 |
1664 // Patch the arguments.length and the parameters pointer in the current frame. | 1656 // Patch the arguments.length and the parameters pointer in the current frame. |
1665 __ LoadP(r5, MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1657 __ LoadP(r5, MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
(...skipping 10 matching lines...) Expand all Loading... |
1676 | 1668 |
1677 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 1669 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
1678 // Stack layout: | 1670 // Stack layout: |
1679 // sp[0] : number of parameters (tagged) | 1671 // sp[0] : number of parameters (tagged) |
1680 // sp[1] : address of receiver argument | 1672 // sp[1] : address of receiver argument |
1681 // sp[2] : function | 1673 // sp[2] : function |
1682 // Registers used over whole function: | 1674 // Registers used over whole function: |
1683 // r9 : allocated object (tagged) | 1675 // r9 : allocated object (tagged) |
1684 // r11 : mapped parameter count (tagged) | 1676 // r11 : mapped parameter count (tagged) |
1685 | 1677 |
| 1678 CHECK(!has_new_target()); |
| 1679 |
1686 __ LoadP(r4, MemOperand(sp, 0 * kPointerSize)); | 1680 __ LoadP(r4, MemOperand(sp, 0 * kPointerSize)); |
1687 // r4 = parameter count (tagged) | 1681 // r4 = parameter count (tagged) |
1688 | 1682 |
1689 // Check if the calling frame is an arguments adaptor frame. | 1683 // Check if the calling frame is an arguments adaptor frame. |
1690 Label runtime; | 1684 Label runtime; |
1691 Label adaptor_frame, try_allocate; | 1685 Label adaptor_frame, try_allocate; |
1692 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1686 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1693 __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset)); | 1687 __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset)); |
1694 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); | 1688 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); |
1695 __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1689 __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1952 __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1959 __ beq(&adaptor_frame); | 1953 __ beq(&adaptor_frame); |
1960 | 1954 |
1961 // Get the length from the frame. | 1955 // Get the length from the frame. |
1962 __ LoadP(r4, MemOperand(sp, 0)); | 1956 __ LoadP(r4, MemOperand(sp, 0)); |
1963 __ b(&try_allocate); | 1957 __ b(&try_allocate); |
1964 | 1958 |
1965 // Patch the arguments.length and the parameters pointer. | 1959 // Patch the arguments.length and the parameters pointer. |
1966 __ bind(&adaptor_frame); | 1960 __ bind(&adaptor_frame); |
1967 __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1961 __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 1962 if (has_new_target()) { |
| 1963 // Subtract 1 from smi-tagged arguments count. |
| 1964 __ SubSmiLiteral(r4, r4, Smi::FromInt(1), r0); |
| 1965 } |
1968 __ StoreP(r4, MemOperand(sp, 0)); | 1966 __ StoreP(r4, MemOperand(sp, 0)); |
1969 __ SmiToPtrArrayOffset(r6, r4); | 1967 __ SmiToPtrArrayOffset(r6, r4); |
1970 __ add(r6, r5, r6); | 1968 __ add(r6, r5, r6); |
1971 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); | 1969 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
1972 __ StoreP(r6, MemOperand(sp, 1 * kPointerSize)); | 1970 __ StoreP(r6, MemOperand(sp, 1 * kPointerSize)); |
1973 | 1971 |
1974 // Try the new space allocation. Start out with computing the size | 1972 // Try the new space allocation. Start out with computing the size |
1975 // of the arguments object and the elements array in words. | 1973 // of the arguments object and the elements array in words. |
1976 Label add_arguments_object; | 1974 Label add_arguments_object; |
1977 __ bind(&try_allocate); | 1975 __ bind(&try_allocate); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 __ bind(&done); | 2042 __ bind(&done); |
2045 __ addi(sp, sp, Operand(3 * kPointerSize)); | 2043 __ addi(sp, sp, Operand(3 * kPointerSize)); |
2046 __ Ret(); | 2044 __ Ret(); |
2047 | 2045 |
2048 // Do the runtime call to allocate the arguments object. | 2046 // Do the runtime call to allocate the arguments object. |
2049 __ bind(&runtime); | 2047 __ bind(&runtime); |
2050 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); | 2048 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
2051 } | 2049 } |
2052 | 2050 |
2053 | 2051 |
| 2052 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { |
| 2053 // Stack layout on entry. |
| 2054 // sp[0] : index of rest parameter |
| 2055 // sp[4] : number of parameters |
| 2056 // sp[8] : receiver displacement |
| 2057 |
| 2058 Label runtime; |
| 2059 __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 2060 __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset)); |
| 2061 __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
| 2062 __ bne(&runtime); |
| 2063 |
| 2064 // Patch the arguments.length and the parameters pointer. |
| 2065 __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2066 __ StoreP(r4, MemOperand(sp, 1 * kPointerSize)); |
| 2067 __ SmiToPtrArrayOffset(r6, r4); |
| 2068 __ add(r6, r5, r6); |
| 2069 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 2070 __ StoreP(r6, MemOperand(sp, 2 * kPointerSize)); |
| 2071 |
| 2072 __ bind(&runtime); |
| 2073 __ TailCallRuntime(Runtime::kNewRestParam, 3, 1); |
| 2074 } |
| 2075 |
| 2076 |
2054 void RegExpExecStub::Generate(MacroAssembler* masm) { | 2077 void RegExpExecStub::Generate(MacroAssembler* masm) { |
2055 // Just jump directly to runtime if native RegExp is not selected at compile | 2078 // Just jump directly to runtime if native RegExp is not selected at compile |
2056 // time or if regexp entry in generated code is turned off runtime switch or | 2079 // time or if regexp entry in generated code is turned off runtime switch or |
2057 // at compilation. | 2080 // at compilation. |
2058 #ifdef V8_INTERPRETED_REGEXP | 2081 #ifdef V8_INTERPRETED_REGEXP |
2059 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); | 2082 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
2060 #else // V8_INTERPRETED_REGEXP | 2083 #else // V8_INTERPRETED_REGEXP |
2061 | 2084 |
2062 // Stack frame on entry. | 2085 // Stack frame on entry. |
2063 // sp[0]: last_match_info (expected JSArray) | 2086 // sp[0]: last_match_info (expected JSArray) |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2753 __ beq(&feedback_register_initialized); | 2776 __ beq(&feedback_register_initialized); |
2754 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 2777 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
2755 __ bind(&feedback_register_initialized); | 2778 __ bind(&feedback_register_initialized); |
2756 } | 2779 } |
2757 } | 2780 } |
2758 | 2781 |
2759 __ AssertUndefinedOrAllocationSite(r5, r8); | 2782 __ AssertUndefinedOrAllocationSite(r5, r8); |
2760 } | 2783 } |
2761 | 2784 |
2762 // Pass function as original constructor. | 2785 // Pass function as original constructor. |
2763 __ mr(r6, r4); | 2786 if (IsSuperConstructorCall()) { |
| 2787 __ ShiftLeftImm(r7, r3, Operand(kPointerSizeLog2)); |
| 2788 __ addi(r7, r7, Operand(kPointerSize)); |
| 2789 __ LoadPX(r6, MemOperand(sp, r7)); |
| 2790 } else { |
| 2791 __ mr(r6, r4); |
| 2792 } |
2764 | 2793 |
2765 // Jump to the function-specific construct stub. | 2794 // Jump to the function-specific construct stub. |
2766 Register jmp_reg = r7; | 2795 Register jmp_reg = r7; |
2767 __ LoadP(jmp_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 2796 __ LoadP(jmp_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
2768 __ LoadP(jmp_reg, | 2797 __ LoadP(jmp_reg, |
2769 FieldMemOperand(jmp_reg, SharedFunctionInfo::kConstructStubOffset)); | 2798 FieldMemOperand(jmp_reg, SharedFunctionInfo::kConstructStubOffset)); |
2770 __ addi(ip, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2799 __ addi(ip, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |
2771 __ JumpToJSEntry(ip); | 2800 __ JumpToJSEntry(ip); |
2772 | 2801 |
2773 // r3: number of arguments | 2802 // r3: number of arguments |
(...skipping 2498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5272 kStackUnwindSpace, NULL, | 5301 kStackUnwindSpace, NULL, |
5273 MemOperand(fp, 6 * kPointerSize), NULL); | 5302 MemOperand(fp, 6 * kPointerSize), NULL); |
5274 } | 5303 } |
5275 | 5304 |
5276 | 5305 |
5277 #undef __ | 5306 #undef __ |
5278 } | 5307 } |
5279 } // namespace v8::internal | 5308 } // namespace v8::internal |
5280 | 5309 |
5281 #endif // V8_TARGET_ARCH_PPC | 5310 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |