OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 2047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 | 2058 |
2059 AssertNotSmi(object); | 2059 AssertNotSmi(object); |
2060 | 2060 |
2061 UseScratchRegisterScope temps(this); | 2061 UseScratchRegisterScope temps(this); |
2062 Register temp = temps.AcquireX(); | 2062 Register temp = temps.AcquireX(); |
2063 Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); | 2063 Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); |
2064 JumpIfNotRoot(temp, Heap::kHeapNumberMapRootIndex, on_not_heap_number); | 2064 JumpIfNotRoot(temp, Heap::kHeapNumberMapRootIndex, on_not_heap_number); |
2065 } | 2065 } |
2066 | 2066 |
2067 | 2067 |
2068 void MacroAssembler::LookupNumberStringCache(Register object, | |
2069 Register result, | |
2070 Register scratch1, | |
2071 Register scratch2, | |
2072 Register scratch3, | |
2073 Label* not_found) { | |
2074 DCHECK(!AreAliased(object, result, scratch1, scratch2, scratch3)); | |
2075 | |
2076 // Use of registers. Register result is used as a temporary. | |
2077 Register number_string_cache = result; | |
2078 Register mask = scratch3; | |
2079 | |
2080 // Load the number string cache. | |
2081 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
2082 | |
2083 // Make the hash mask from the length of the number string cache. It | |
2084 // contains two elements (number and string) for each cache entry. | |
2085 Ldrsw(mask, UntagSmiFieldMemOperand(number_string_cache, | |
2086 FixedArray::kLengthOffset)); | |
2087 Asr(mask, mask, 1); // Divide length by two. | |
2088 Sub(mask, mask, 1); // Make mask. | |
2089 | |
2090 // Calculate the entry in the number string cache. The hash value in the | |
2091 // number string cache for smis is just the smi value, and the hash for | |
2092 // doubles is the xor of the upper and lower words. See | |
2093 // Heap::GetNumberStringCache. | |
2094 Label is_smi; | |
2095 Label load_result_from_cache; | |
2096 | |
2097 JumpIfSmi(object, &is_smi); | |
2098 JumpIfNotHeapNumber(object, not_found); | |
2099 | |
2100 STATIC_ASSERT(kDoubleSize == (kWRegSize * 2)); | |
2101 Add(scratch1, object, HeapNumber::kValueOffset - kHeapObjectTag); | |
2102 Ldp(scratch1.W(), scratch2.W(), MemOperand(scratch1)); | |
2103 Eor(scratch1, scratch1, scratch2); | |
2104 And(scratch1, scratch1, mask); | |
2105 | |
2106 // Calculate address of entry in string cache: each entry consists of two | |
2107 // pointer sized fields. | |
2108 Add(scratch1, number_string_cache, | |
2109 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); | |
2110 | |
2111 Register probe = mask; | |
2112 Ldr(probe, FieldMemOperand(scratch1, FixedArray::kHeaderSize)); | |
2113 JumpIfSmi(probe, not_found); | |
2114 Ldr(d0, FieldMemOperand(object, HeapNumber::kValueOffset)); | |
2115 Ldr(d1, FieldMemOperand(probe, HeapNumber::kValueOffset)); | |
2116 Fcmp(d0, d1); | |
2117 B(ne, not_found); | |
2118 B(&load_result_from_cache); | |
2119 | |
2120 Bind(&is_smi); | |
2121 Register scratch = scratch1; | |
2122 And(scratch, mask, Operand::UntagSmi(object)); | |
2123 // Calculate address of entry in string cache: each entry consists | |
2124 // of two pointer sized fields. | |
2125 Add(scratch, number_string_cache, | |
2126 Operand(scratch, LSL, kPointerSizeLog2 + 1)); | |
2127 | |
2128 // Check if the entry is the smi we are looking for. | |
2129 Ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | |
2130 Cmp(object, probe); | |
2131 B(ne, not_found); | |
2132 | |
2133 // Get the result from the cache. | |
2134 Bind(&load_result_from_cache); | |
2135 Ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); | |
2136 IncrementCounter(isolate()->counters()->number_to_string_native(), 1, | |
2137 scratch1, scratch2); | |
2138 } | |
2139 | |
2140 | |
2141 void MacroAssembler::TryRepresentDoubleAsInt(Register as_int, | 2068 void MacroAssembler::TryRepresentDoubleAsInt(Register as_int, |
2142 FPRegister value, | 2069 FPRegister value, |
2143 FPRegister scratch_d, | 2070 FPRegister scratch_d, |
2144 Label* on_successful_conversion, | 2071 Label* on_successful_conversion, |
2145 Label* on_failed_conversion) { | 2072 Label* on_failed_conversion) { |
2146 // Convert to an int and back again, then compare with the original value. | 2073 // Convert to an int and back again, then compare with the original value. |
2147 Fcvtzs(as_int, value); | 2074 Fcvtzs(as_int, value); |
2148 Scvtf(scratch_d, as_int); | 2075 Scvtf(scratch_d, as_int); |
2149 Fcmp(value, scratch_d); | 2076 Fcmp(value, scratch_d); |
2150 | 2077 |
(...skipping 2969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5120 } | 5047 } |
5121 | 5048 |
5122 | 5049 |
5123 #undef __ | 5050 #undef __ |
5124 | 5051 |
5125 | 5052 |
5126 } // namespace internal | 5053 } // namespace internal |
5127 } // namespace v8 | 5054 } // namespace v8 |
5128 | 5055 |
5129 #endif // V8_TARGET_ARCH_ARM64 | 5056 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |