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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
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 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | 1373 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { |
1374 // Return address is in ra. | 1374 // Return address is in ra. |
1375 Label miss; | 1375 Label miss; |
1376 | 1376 |
1377 Register receiver = LoadDescriptor::ReceiverRegister(); | 1377 Register receiver = LoadDescriptor::ReceiverRegister(); |
1378 Register index = LoadDescriptor::NameRegister(); | 1378 Register index = LoadDescriptor::NameRegister(); |
1379 Register scratch = t1; | 1379 Register scratch = t1; |
1380 Register result = v0; | 1380 Register result = v0; |
1381 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 1381 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
1382 DCHECK(!FLAG_vector_ics || | 1382 DCHECK(!FLAG_vector_ics || |
1383 (!scratch.is(VectorLoadICDescriptor::VectorRegister()) && | 1383 !scratch.is(VectorLoadICDescriptor::VectorRegister())); |
1384 result.is(VectorLoadICDescriptor::SlotRegister()))); | |
1385 | 1384 |
1386 // StringCharAtGenerator doesn't use the result register until it's passed | |
1387 // the different miss possibilities. If it did, we would have a conflict | |
1388 // when FLAG_vector_ics is true. | |
1389 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 1385 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
1390 &miss, // When not a string. | 1386 &miss, // When not a string. |
1391 &miss, // When not a number. | 1387 &miss, // When not a number. |
1392 &miss, // When index out of range. | 1388 &miss, // When index out of range. |
1393 STRING_INDEX_IS_ARRAY_INDEX, | 1389 STRING_INDEX_IS_ARRAY_INDEX, |
1394 RECEIVER_IS_STRING); | 1390 RECEIVER_IS_STRING); |
1395 char_at_generator.GenerateFast(masm); | 1391 char_at_generator.GenerateFast(masm); |
1396 __ Ret(); | 1392 __ Ret(); |
1397 | 1393 |
1398 StubRuntimeCallHelper call_helper; | 1394 StubRuntimeCallHelper call_helper; |
1399 char_at_generator.GenerateSlow(masm, call_helper); | 1395 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); |
1400 | 1396 |
1401 __ bind(&miss); | 1397 __ bind(&miss); |
1402 PropertyAccessCompiler::TailCallBuiltin( | 1398 PropertyAccessCompiler::TailCallBuiltin( |
1403 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 1399 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
1404 } | 1400 } |
1405 | 1401 |
1406 | 1402 |
1407 // Uses registers a0 to t0. | 1403 // Uses registers a0 to t0. |
1408 // Expected input (depending on whether args are in registers or on the stack): | 1404 // Expected input (depending on whether args are in registers or on the stack): |
1409 // * object: a0 or at sp + 1 * kPointerSize. | 1405 // * object: a0 or at sp + 1 * kPointerSize. |
(...skipping 1633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 index_, | 3039 index_, |
3044 result_, | 3040 result_, |
3045 &call_runtime_); | 3041 &call_runtime_); |
3046 | 3042 |
3047 __ sll(result_, result_, kSmiTagSize); | 3043 __ sll(result_, result_, kSmiTagSize); |
3048 __ bind(&exit_); | 3044 __ bind(&exit_); |
3049 } | 3045 } |
3050 | 3046 |
3051 | 3047 |
3052 void StringCharCodeAtGenerator::GenerateSlow( | 3048 void StringCharCodeAtGenerator::GenerateSlow( |
3053 MacroAssembler* masm, | 3049 MacroAssembler* masm, EmbedMode embed_mode, |
3054 const RuntimeCallHelper& call_helper) { | 3050 const RuntimeCallHelper& call_helper) { |
3055 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); | 3051 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); |
3056 | 3052 |
3057 // Index is not a smi. | 3053 // Index is not a smi. |
3058 __ bind(&index_not_smi_); | 3054 __ bind(&index_not_smi_); |
3059 // If index is a heap number, try converting it to an integer. | 3055 // If index is a heap number, try converting it to an integer. |
3060 __ CheckMap(index_, | 3056 __ CheckMap(index_, |
3061 result_, | 3057 result_, |
3062 Heap::kHeapNumberMapRootIndex, | 3058 Heap::kHeapNumberMapRootIndex, |
3063 index_not_number_, | 3059 index_not_number_, |
3064 DONT_DO_SMI_CHECK); | 3060 DONT_DO_SMI_CHECK); |
3065 call_helper.BeforeCall(masm); | 3061 call_helper.BeforeCall(masm); |
3066 // Consumed by runtime conversion function: | 3062 // Consumed by runtime conversion function: |
3067 __ Push(object_, index_); | 3063 if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) { |
| 3064 __ Push(VectorLoadICDescriptor::VectorRegister(), |
| 3065 VectorLoadICDescriptor::SlotRegister(), object_, index_); |
| 3066 } else { |
| 3067 __ Push(object_, index_); |
| 3068 } |
3068 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 3069 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
3069 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 3070 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
3070 } else { | 3071 } else { |
3071 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 3072 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
3072 // NumberToSmi discards numbers that are not exact integers. | 3073 // NumberToSmi discards numbers that are not exact integers. |
3073 __ CallRuntime(Runtime::kNumberToSmi, 1); | 3074 __ CallRuntime(Runtime::kNumberToSmi, 1); |
3074 } | 3075 } |
3075 | 3076 |
3076 // Save the conversion result before the pop instructions below | 3077 // Save the conversion result before the pop instructions below |
3077 // have a chance to overwrite it. | 3078 // have a chance to overwrite it. |
3078 | |
3079 __ Move(index_, v0); | 3079 __ Move(index_, v0); |
3080 __ pop(object_); | 3080 if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) { |
| 3081 __ Pop(VectorLoadICDescriptor::SlotRegister(), |
| 3082 VectorLoadICDescriptor::VectorRegister(), object_); |
| 3083 } else { |
| 3084 __ pop(object_); |
| 3085 } |
3081 // Reload the instance type. | 3086 // Reload the instance type. |
3082 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | 3087 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
3083 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | 3088 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
3084 call_helper.AfterCall(masm); | 3089 call_helper.AfterCall(masm); |
3085 // If index is still not a smi, it must be out of range. | 3090 // If index is still not a smi, it must be out of range. |
3086 __ JumpIfNotSmi(index_, index_out_of_range_); | 3091 __ JumpIfNotSmi(index_, index_out_of_range_); |
3087 // Otherwise, return to the fast path. | 3092 // Otherwise, return to the fast path. |
3088 __ Branch(&got_smi_index_); | 3093 __ Branch(&got_smi_index_); |
3089 | 3094 |
3090 // Call runtime. We get here when the receiver is a string and the | 3095 // Call runtime. We get here when the receiver is a string and the |
(...skipping 2404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5495 kStackUnwindSpace, kInvalidStackOffset, | 5500 kStackUnwindSpace, kInvalidStackOffset, |
5496 MemOperand(fp, 6 * kPointerSize), NULL); | 5501 MemOperand(fp, 6 * kPointerSize), NULL); |
5497 } | 5502 } |
5498 | 5503 |
5499 | 5504 |
5500 #undef __ | 5505 #undef __ |
5501 | 5506 |
5502 } } // namespace v8::internal | 5507 } } // namespace v8::internal |
5503 | 5508 |
5504 #endif // V8_TARGET_ARCH_MIPS | 5509 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |