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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 2576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2587 Register scratch, | 2587 Register scratch, |
2588 int power) { | 2588 int power) { |
2589 DCHECK(is_uintn(power + HeapNumber::kExponentBias, | 2589 DCHECK(is_uintn(power + HeapNumber::kExponentBias, |
2590 HeapNumber::kExponentBits)); | 2590 HeapNumber::kExponentBits)); |
2591 mov(scratch, Immediate(power + HeapNumber::kExponentBias)); | 2591 mov(scratch, Immediate(power + HeapNumber::kExponentBias)); |
2592 movd(dst, scratch); | 2592 movd(dst, scratch); |
2593 psllq(dst, HeapNumber::kMantissaBits); | 2593 psllq(dst, HeapNumber::kMantissaBits); |
2594 } | 2594 } |
2595 | 2595 |
2596 | 2596 |
2597 void MacroAssembler::LookupNumberStringCache(Register object, | |
2598 Register result, | |
2599 Register scratch1, | |
2600 Register scratch2, | |
2601 Label* not_found) { | |
2602 // Use of registers. Register result is used as a temporary. | |
2603 Register number_string_cache = result; | |
2604 Register mask = scratch1; | |
2605 Register scratch = scratch2; | |
2606 | |
2607 // Load the number string cache. | |
2608 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
2609 // Make the hash mask from the length of the number string cache. It | |
2610 // contains two elements (number and string) for each cache entry. | |
2611 mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | |
2612 shr(mask, kSmiTagSize + 1); // Untag length and divide it by two. | |
2613 sub(mask, Immediate(1)); // Make mask. | |
2614 | |
2615 // Calculate the entry in the number string cache. The hash value in the | |
2616 // number string cache for smis is just the smi value, and the hash for | |
2617 // doubles is the xor of the upper and lower words. See | |
2618 // Heap::GetNumberStringCache. | |
2619 Label smi_hash_calculated; | |
2620 Label load_result_from_cache; | |
2621 Label not_smi; | |
2622 STATIC_ASSERT(kSmiTag == 0); | |
2623 JumpIfNotSmi(object, ¬_smi, Label::kNear); | |
2624 mov(scratch, object); | |
2625 SmiUntag(scratch); | |
2626 jmp(&smi_hash_calculated, Label::kNear); | |
2627 bind(¬_smi); | |
2628 cmp(FieldOperand(object, HeapObject::kMapOffset), | |
2629 isolate()->factory()->heap_number_map()); | |
2630 j(not_equal, not_found); | |
2631 STATIC_ASSERT(8 == kDoubleSize); | |
2632 mov(scratch, FieldOperand(object, HeapNumber::kValueOffset)); | |
2633 xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); | |
2634 // Object is heap number and hash is now in scratch. Calculate cache index. | |
2635 and_(scratch, mask); | |
2636 Register index = scratch; | |
2637 Register probe = mask; | |
2638 mov(probe, | |
2639 FieldOperand(number_string_cache, | |
2640 index, | |
2641 times_twice_pointer_size, | |
2642 FixedArray::kHeaderSize)); | |
2643 JumpIfSmi(probe, not_found); | |
2644 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | |
2645 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); | |
2646 j(parity_even, not_found); // Bail out if NaN is involved. | |
2647 j(not_equal, not_found); // The cache did not contain this value. | |
2648 jmp(&load_result_from_cache, Label::kNear); | |
2649 | |
2650 bind(&smi_hash_calculated); | |
2651 // Object is smi and hash is now in scratch. Calculate cache index. | |
2652 and_(scratch, mask); | |
2653 // Check if the entry is the smi we are looking for. | |
2654 cmp(object, | |
2655 FieldOperand(number_string_cache, | |
2656 index, | |
2657 times_twice_pointer_size, | |
2658 FixedArray::kHeaderSize)); | |
2659 j(not_equal, not_found); | |
2660 | |
2661 // Get the result from the cache. | |
2662 bind(&load_result_from_cache); | |
2663 mov(result, | |
2664 FieldOperand(number_string_cache, | |
2665 index, | |
2666 times_twice_pointer_size, | |
2667 FixedArray::kHeaderSize + kPointerSize)); | |
2668 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); | |
2669 } | |
2670 | |
2671 | |
2672 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( | 2597 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( |
2673 Register instance_type, Register scratch, Label* failure) { | 2598 Register instance_type, Register scratch, Label* failure) { |
2674 if (!scratch.is(instance_type)) { | 2599 if (!scratch.is(instance_type)) { |
2675 mov(scratch, instance_type); | 2600 mov(scratch, instance_type); |
2676 } | 2601 } |
2677 and_(scratch, | 2602 and_(scratch, |
2678 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); | 2603 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); |
2679 cmp(scratch, kStringTag | kSeqStringTag | kOneByteStringTag); | 2604 cmp(scratch, kStringTag | kSeqStringTag | kOneByteStringTag); |
2680 j(not_equal, failure); | 2605 j(not_equal, failure); |
2681 } | 2606 } |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3189 mov(eax, dividend); | 3114 mov(eax, dividend); |
3190 shr(eax, 31); | 3115 shr(eax, 31); |
3191 add(edx, eax); | 3116 add(edx, eax); |
3192 } | 3117 } |
3193 | 3118 |
3194 | 3119 |
3195 } // namespace internal | 3120 } // namespace internal |
3196 } // namespace v8 | 3121 } // namespace v8 |
3197 | 3122 |
3198 #endif // V8_TARGET_ARCH_IA32 | 3123 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |