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