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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 // If argv_in_register(): | 1066 // If argv_in_register(): |
1067 // a2: pointer to the first argument | 1067 // a2: pointer to the first argument |
1068 | 1068 |
1069 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1069 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
1070 | 1070 |
1071 if (argv_in_register()) { | 1071 if (argv_in_register()) { |
1072 // Move argv into the correct register. | 1072 // Move argv into the correct register. |
1073 __ mov(s1, a2); | 1073 __ mov(s1, a2); |
1074 } else { | 1074 } else { |
1075 // Compute the argv pointer in a callee-saved register. | 1075 // Compute the argv pointer in a callee-saved register. |
1076 __ dsll(s1, a0, kPointerSizeLog2); | 1076 __ Dlsa(s1, sp, a0, kPointerSizeLog2); |
1077 __ Daddu(s1, sp, s1); | |
1078 __ Dsubu(s1, s1, kPointerSize); | 1077 __ Dsubu(s1, s1, kPointerSize); |
1079 } | 1078 } |
1080 | 1079 |
1081 // Enter the exit frame that transitions from JavaScript to C++. | 1080 // Enter the exit frame that transitions from JavaScript to C++. |
1082 FrameScope scope(masm, StackFrame::MANUAL); | 1081 FrameScope scope(masm, StackFrame::MANUAL); |
1083 __ EnterExitFrame(save_doubles()); | 1082 __ EnterExitFrame(save_doubles()); |
1084 | 1083 |
1085 // s0: number of arguments including receiver (C callee-saved) | 1084 // s0: number of arguments including receiver (C callee-saved) |
1086 // s1: pointer to first argument (C callee-saved) | 1085 // s1: pointer to first argument (C callee-saved) |
1087 // s2: pointer to builtin function (C callee-saved) | 1086 // s2: pointer to builtin function (C callee-saved) |
(...skipping 2097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3185 StringHelper::GenerateCopyCharacters( | 3184 StringHelper::GenerateCopyCharacters( |
3186 masm, a1, a5, a2, a3, String::ONE_BYTE_ENCODING); | 3185 masm, a1, a5, a2, a3, String::ONE_BYTE_ENCODING); |
3187 __ jmp(&return_v0); | 3186 __ jmp(&return_v0); |
3188 | 3187 |
3189 // Allocate and copy the resulting two-byte string. | 3188 // Allocate and copy the resulting two-byte string. |
3190 __ bind(&two_byte_sequential); | 3189 __ bind(&two_byte_sequential); |
3191 __ AllocateTwoByteString(v0, a2, a4, a6, a7, &runtime); | 3190 __ AllocateTwoByteString(v0, a2, a4, a6, a7, &runtime); |
3192 | 3191 |
3193 // Locate first character of substring to copy. | 3192 // Locate first character of substring to copy. |
3194 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 3193 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
3195 __ dsll(a4, a3, 1); | 3194 __ Dlsa(a5, a5, a3, 1); |
3196 __ Daddu(a5, a5, a4); | |
3197 // Locate first character of result. | 3195 // Locate first character of result. |
3198 __ Daddu(a1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 3196 __ Daddu(a1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
3199 | 3197 |
3200 // v0: result string. | 3198 // v0: result string. |
3201 // a1: first character of result. | 3199 // a1: first character of result. |
3202 // a2: result length. | 3200 // a2: result length. |
3203 // a5: first character of substring to copy. | 3201 // a5: first character of substring to copy. |
3204 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 3202 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
3205 StringHelper::GenerateCopyCharacters( | 3203 StringHelper::GenerateCopyCharacters( |
3206 masm, a1, a5, a2, a3, String::TWO_BYTE_ENCODING); | 3204 masm, a1, a5, a2, a3, String::TWO_BYTE_ENCODING); |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3921 // Compute the masked index: (hash + i + i * i) & mask. | 3919 // Compute the masked index: (hash + i + i * i) & mask. |
3922 Register index = scratch0; | 3920 Register index = scratch0; |
3923 // Capacity is smi 2^n. | 3921 // Capacity is smi 2^n. |
3924 __ SmiLoadUntag(index, FieldMemOperand(properties, kCapacityOffset)); | 3922 __ SmiLoadUntag(index, FieldMemOperand(properties, kCapacityOffset)); |
3925 __ Dsubu(index, index, Operand(1)); | 3923 __ Dsubu(index, index, Operand(1)); |
3926 __ And(index, index, | 3924 __ And(index, index, |
3927 Operand(name->Hash() + NameDictionary::GetProbeOffset(i))); | 3925 Operand(name->Hash() + NameDictionary::GetProbeOffset(i))); |
3928 | 3926 |
3929 // Scale the index by multiplying by the entry size. | 3927 // Scale the index by multiplying by the entry size. |
3930 STATIC_ASSERT(NameDictionary::kEntrySize == 3); | 3928 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
3931 __ dsll(at, index, 1); | 3929 __ Dlsa(index, index, index, 1); // index *= 3. |
3932 __ Daddu(index, index, at); // index *= 3. | |
3933 | 3930 |
3934 Register entity_name = scratch0; | 3931 Register entity_name = scratch0; |
3935 // Having undefined at this place means the name is not contained. | 3932 // Having undefined at this place means the name is not contained. |
3936 STATIC_ASSERT(kSmiTagSize == 1); | 3933 STATIC_ASSERT(kSmiTagSize == 1); |
3937 Register tmp = properties; | 3934 Register tmp = properties; |
3938 | 3935 |
3939 __ dsll(scratch0, index, kPointerSizeLog2); | 3936 __ Dlsa(tmp, properties, index, kPointerSizeLog2); |
3940 __ Daddu(tmp, properties, scratch0); | |
3941 __ ld(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); | 3937 __ ld(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); |
3942 | 3938 |
3943 DCHECK(!tmp.is(entity_name)); | 3939 DCHECK(!tmp.is(entity_name)); |
3944 __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex); | 3940 __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex); |
3945 __ Branch(done, eq, entity_name, Operand(tmp)); | 3941 __ Branch(done, eq, entity_name, Operand(tmp)); |
3946 | 3942 |
3947 // Load the hole ready for use below: | 3943 // Load the hole ready for use below: |
3948 __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); | 3944 __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); |
3949 | 3945 |
3950 // Stop if found the property. | 3946 // Stop if found the property. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4019 1 << (32 - Name::kHashFieldOffset)); | 4015 1 << (32 - Name::kHashFieldOffset)); |
4020 __ Daddu(scratch2, scratch2, Operand( | 4016 __ Daddu(scratch2, scratch2, Operand( |
4021 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); | 4017 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); |
4022 } | 4018 } |
4023 __ dsrl(scratch2, scratch2, Name::kHashShift); | 4019 __ dsrl(scratch2, scratch2, Name::kHashShift); |
4024 __ And(scratch2, scratch1, scratch2); | 4020 __ And(scratch2, scratch1, scratch2); |
4025 | 4021 |
4026 // Scale the index by multiplying by the entry size. | 4022 // Scale the index by multiplying by the entry size. |
4027 STATIC_ASSERT(NameDictionary::kEntrySize == 3); | 4023 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
4028 // scratch2 = scratch2 * 3. | 4024 // scratch2 = scratch2 * 3. |
4029 | 4025 __ Dlsa(scratch2, scratch2, scratch2, 1); |
4030 __ dsll(at, scratch2, 1); | |
4031 __ Daddu(scratch2, scratch2, at); | |
4032 | 4026 |
4033 // Check if the key is identical to the name. | 4027 // Check if the key is identical to the name. |
4034 __ dsll(at, scratch2, kPointerSizeLog2); | 4028 __ Dlsa(scratch2, elements, scratch2, kPointerSizeLog2); |
4035 __ Daddu(scratch2, elements, at); | |
4036 __ ld(at, FieldMemOperand(scratch2, kElementsStartOffset)); | 4029 __ ld(at, FieldMemOperand(scratch2, kElementsStartOffset)); |
4037 __ Branch(done, eq, name, Operand(at)); | 4030 __ Branch(done, eq, name, Operand(at)); |
4038 } | 4031 } |
4039 | 4032 |
4040 const int spill_mask = | 4033 const int spill_mask = |
4041 (ra.bit() | a6.bit() | a5.bit() | a4.bit() | | 4034 (ra.bit() | a6.bit() | a5.bit() | a4.bit() | |
4042 a3.bit() | a2.bit() | a1.bit() | a0.bit() | v0.bit()) & | 4035 a3.bit() | a2.bit() | a1.bit() | a0.bit() | v0.bit()) & |
4043 ~(scratch1.bit() | scratch2.bit()); | 4036 ~(scratch1.bit() | scratch2.bit()); |
4044 | 4037 |
4045 __ MultiPush(spill_mask); | 4038 __ MultiPush(spill_mask); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4106 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); | 4099 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); |
4107 } else { | 4100 } else { |
4108 __ mov(index, hash); | 4101 __ mov(index, hash); |
4109 } | 4102 } |
4110 __ dsrl(index, index, Name::kHashShift); | 4103 __ dsrl(index, index, Name::kHashShift); |
4111 __ And(index, mask, index); | 4104 __ And(index, mask, index); |
4112 | 4105 |
4113 // Scale the index by multiplying by the entry size. | 4106 // Scale the index by multiplying by the entry size. |
4114 STATIC_ASSERT(NameDictionary::kEntrySize == 3); | 4107 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
4115 // index *= 3. | 4108 // index *= 3. |
4116 __ mov(at, index); | 4109 __ Dlsa(index, index, index, 1); |
4117 __ dsll(index, index, 1); | |
4118 __ Daddu(index, index, at); | |
4119 | |
4120 | 4110 |
4121 STATIC_ASSERT(kSmiTagSize == 1); | 4111 STATIC_ASSERT(kSmiTagSize == 1); |
4122 __ dsll(index, index, kPointerSizeLog2); | 4112 __ Dlsa(index, dictionary, index, kPointerSizeLog2); |
4123 __ Daddu(index, index, dictionary); | |
4124 __ ld(entry_key, FieldMemOperand(index, kElementsStartOffset)); | 4113 __ ld(entry_key, FieldMemOperand(index, kElementsStartOffset)); |
4125 | 4114 |
4126 // Having undefined at this place means the name is not contained. | 4115 // Having undefined at this place means the name is not contained. |
4127 __ Branch(¬_in_dictionary, eq, entry_key, Operand(undefined)); | 4116 __ Branch(¬_in_dictionary, eq, entry_key, Operand(undefined)); |
4128 | 4117 |
4129 // Stop if found the property. | 4118 // Stop if found the property. |
4130 __ Branch(&in_dictionary, eq, entry_key, Operand(key)); | 4119 __ Branch(&in_dictionary, eq, entry_key, Operand(key)); |
4131 | 4120 |
4132 if (i != kTotalProbes - 1 && mode() == NEGATIVE_LOOKUP) { | 4121 if (i != kTotalProbes - 1 && mode() == NEGATIVE_LOOKUP) { |
4133 // Check if the entry name is not a unique name. | 4122 // Check if the entry name is not a unique name. |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5098 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 5087 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
5099 | 5088 |
5100 __ bind(&no_info); | 5089 __ bind(&no_info); |
5101 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 5090 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
5102 | 5091 |
5103 // Subclassing. | 5092 // Subclassing. |
5104 __ bind(&subclassing); | 5093 __ bind(&subclassing); |
5105 switch (argument_count()) { | 5094 switch (argument_count()) { |
5106 case ANY: | 5095 case ANY: |
5107 case MORE_THAN_ONE: | 5096 case MORE_THAN_ONE: |
5108 __ dsll(at, a0, kPointerSizeLog2); | 5097 __ Dlsa(at, sp, a0, kPointerSizeLog2); |
5109 __ Daddu(at, sp, at); | |
5110 __ sd(a1, MemOperand(at)); | 5098 __ sd(a1, MemOperand(at)); |
5111 __ li(at, Operand(3)); | 5099 __ li(at, Operand(3)); |
5112 __ Daddu(a0, a0, at); | 5100 __ Daddu(a0, a0, at); |
5113 break; | 5101 break; |
5114 case NONE: | 5102 case NONE: |
5115 __ sd(a1, MemOperand(sp, 0 * kPointerSize)); | 5103 __ sd(a1, MemOperand(sp, 0 * kPointerSize)); |
5116 __ li(a0, Operand(3)); | 5104 __ li(a0, Operand(3)); |
5117 break; | 5105 break; |
5118 case ONE: | 5106 case ONE: |
5119 __ sd(a1, MemOperand(sp, 1 * kPointerSize)); | 5107 __ sd(a1, MemOperand(sp, 1 * kPointerSize)); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5205 Register result_reg = v0; | 5193 Register result_reg = v0; |
5206 Label slow_case; | 5194 Label slow_case; |
5207 | 5195 |
5208 // Go up context chain to the script context. | 5196 // Go up context chain to the script context. |
5209 for (int i = 0; i < depth(); ++i) { | 5197 for (int i = 0; i < depth(); ++i) { |
5210 __ ld(result_reg, ContextMemOperand(context_reg, Context::PREVIOUS_INDEX)); | 5198 __ ld(result_reg, ContextMemOperand(context_reg, Context::PREVIOUS_INDEX)); |
5211 context_reg = result_reg; | 5199 context_reg = result_reg; |
5212 } | 5200 } |
5213 | 5201 |
5214 // Load the PropertyCell value at the specified slot. | 5202 // Load the PropertyCell value at the specified slot. |
5215 __ dsll(at, slot_reg, kPointerSizeLog2); | 5203 __ Dlsa(at, context_reg, slot_reg, kPointerSizeLog2); |
5216 __ Daddu(at, at, Operand(context_reg)); | |
5217 __ ld(result_reg, ContextMemOperand(at, 0)); | 5204 __ ld(result_reg, ContextMemOperand(at, 0)); |
5218 __ ld(result_reg, FieldMemOperand(result_reg, PropertyCell::kValueOffset)); | 5205 __ ld(result_reg, FieldMemOperand(result_reg, PropertyCell::kValueOffset)); |
5219 | 5206 |
5220 // Check that value is not the_hole. | 5207 // Check that value is not the_hole. |
5221 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 5208 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
5222 __ Branch(&slow_case, eq, result_reg, Operand(at)); | 5209 __ Branch(&slow_case, eq, result_reg, Operand(at)); |
5223 __ Ret(); | 5210 __ Ret(); |
5224 | 5211 |
5225 // Fallback to the runtime. | 5212 // Fallback to the runtime. |
5226 __ bind(&slow_case); | 5213 __ bind(&slow_case); |
(...skipping 17 matching lines...) Expand all Loading... |
5244 __ Check(ne, kUnexpectedValue, value_reg, Operand(at)); | 5231 __ Check(ne, kUnexpectedValue, value_reg, Operand(at)); |
5245 } | 5232 } |
5246 | 5233 |
5247 // Go up context chain to the script context. | 5234 // Go up context chain to the script context. |
5248 for (int i = 0; i < depth(); ++i) { | 5235 for (int i = 0; i < depth(); ++i) { |
5249 __ ld(cell_reg, ContextMemOperand(context_reg, Context::PREVIOUS_INDEX)); | 5236 __ ld(cell_reg, ContextMemOperand(context_reg, Context::PREVIOUS_INDEX)); |
5250 context_reg = cell_reg; | 5237 context_reg = cell_reg; |
5251 } | 5238 } |
5252 | 5239 |
5253 // Load the PropertyCell at the specified slot. | 5240 // Load the PropertyCell at the specified slot. |
5254 __ dsll(at, slot_reg, kPointerSizeLog2); | 5241 __ Dlsa(at, context_reg, slot_reg, kPointerSizeLog2); |
5255 __ Daddu(at, at, Operand(context_reg)); | |
5256 __ ld(cell_reg, ContextMemOperand(at, 0)); | 5242 __ ld(cell_reg, ContextMemOperand(at, 0)); |
5257 | 5243 |
5258 // Load PropertyDetails for the cell (actually only the cell_type and kind). | 5244 // Load PropertyDetails for the cell (actually only the cell_type and kind). |
5259 __ ld(cell_details_reg, | 5245 __ ld(cell_details_reg, |
5260 FieldMemOperand(cell_reg, PropertyCell::kDetailsOffset)); | 5246 FieldMemOperand(cell_reg, PropertyCell::kDetailsOffset)); |
5261 __ SmiUntag(cell_details_reg); | 5247 __ SmiUntag(cell_details_reg); |
5262 __ And(cell_details_reg, cell_details_reg, | 5248 __ And(cell_details_reg, cell_details_reg, |
5263 PropertyDetails::PropertyCellTypeField::kMask | | 5249 PropertyDetails::PropertyCellTypeField::kMask | |
5264 PropertyDetails::KindField::kMask | | 5250 PropertyDetails::KindField::kMask | |
5265 PropertyDetails::kAttributesReadOnlyMask); | 5251 PropertyDetails::kAttributesReadOnlyMask); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5651 MemOperand(fp, 6 * kPointerSize), NULL); | 5637 MemOperand(fp, 6 * kPointerSize), NULL); |
5652 } | 5638 } |
5653 | 5639 |
5654 | 5640 |
5655 #undef __ | 5641 #undef __ |
5656 | 5642 |
5657 } // namespace internal | 5643 } // namespace internal |
5658 } // namespace v8 | 5644 } // namespace v8 |
5659 | 5645 |
5660 #endif // V8_TARGET_ARCH_MIPS64 | 5646 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |