| 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
| (...skipping 2560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 MoveHeapObject(kScratchRegister, source); | 2571 MoveHeapObject(kScratchRegister, source); |
| 2572 movp(dst, kScratchRegister); | 2572 movp(dst, kScratchRegister); |
| 2573 } | 2573 } |
| 2574 } | 2574 } |
| 2575 | 2575 |
| 2576 | 2576 |
| 2577 void MacroAssembler::Move(XMMRegister dst, uint32_t src) { | 2577 void MacroAssembler::Move(XMMRegister dst, uint32_t src) { |
| 2578 if (src == 0) { | 2578 if (src == 0) { |
| 2579 xorps(dst, dst); | 2579 xorps(dst, dst); |
| 2580 } else { | 2580 } else { |
| 2581 unsigned cnt = base::bits::CountPopulation32(src); | 2581 movl(kScratchRegister, Immediate(src)); |
| 2582 unsigned nlz = base::bits::CountLeadingZeros32(src); | 2582 movq(dst, kScratchRegister); |
| 2583 unsigned ntz = base::bits::CountTrailingZeros32(src); | |
| 2584 if (nlz + cnt + ntz == 32) { | |
| 2585 pcmpeqd(dst, dst); | |
| 2586 if (ntz == 0) { | |
| 2587 psrld(dst, 32 - cnt); | |
| 2588 } else { | |
| 2589 pslld(dst, 32 - cnt); | |
| 2590 if (nlz != 0) psrld(dst, nlz); | |
| 2591 } | |
| 2592 } else { | |
| 2593 movl(kScratchRegister, Immediate(src)); | |
| 2594 movq(dst, kScratchRegister); | |
| 2595 } | |
| 2596 } | 2583 } |
| 2597 } | 2584 } |
| 2598 | 2585 |
| 2599 | 2586 |
| 2600 void MacroAssembler::Move(XMMRegister dst, uint64_t src) { | 2587 void MacroAssembler::Move(XMMRegister dst, uint64_t src) { |
| 2601 uint32_t lower = static_cast<uint32_t>(src); | 2588 uint32_t lower = static_cast<uint32_t>(src); |
| 2602 uint32_t upper = static_cast<uint32_t>(src >> 32); | 2589 uint32_t upper = static_cast<uint32_t>(src >> 32); |
| 2603 if (upper == 0) { | 2590 if (upper == 0) { |
| 2604 Move(dst, lower); | 2591 Move(dst, lower); |
| 2605 } else { | 2592 } else { |
| 2606 unsigned cnt = base::bits::CountPopulation64(src); | 2593 if (lower == 0) { |
| 2607 unsigned nlz = base::bits::CountLeadingZeros64(src); | |
| 2608 unsigned ntz = base::bits::CountTrailingZeros64(src); | |
| 2609 if (nlz + cnt + ntz == 64) { | |
| 2610 pcmpeqd(dst, dst); | |
| 2611 if (ntz == 0) { | |
| 2612 psrlq(dst, 64 - cnt); | |
| 2613 } else { | |
| 2614 psllq(dst, 64 - cnt); | |
| 2615 if (nlz != 0) psrlq(dst, nlz); | |
| 2616 } | |
| 2617 } else if (lower == 0) { | |
| 2618 Move(dst, upper); | 2594 Move(dst, upper); |
| 2619 psllq(dst, 32); | 2595 psllq(dst, 32); |
| 2620 } else { | 2596 } else { |
| 2621 movq(kScratchRegister, src); | 2597 movq(kScratchRegister, src); |
| 2622 movq(dst, kScratchRegister); | 2598 movq(dst, kScratchRegister); |
| 2623 } | 2599 } |
| 2624 } | 2600 } |
| 2625 } | 2601 } |
| 2626 | 2602 |
| 2627 | 2603 |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3244 } | 3220 } |
| 3245 | 3221 |
| 3246 | 3222 |
| 3247 void MacroAssembler::StoreNumberToDoubleElements( | 3223 void MacroAssembler::StoreNumberToDoubleElements( |
| 3248 Register maybe_number, | 3224 Register maybe_number, |
| 3249 Register elements, | 3225 Register elements, |
| 3250 Register index, | 3226 Register index, |
| 3251 XMMRegister xmm_scratch, | 3227 XMMRegister xmm_scratch, |
| 3252 Label* fail, | 3228 Label* fail, |
| 3253 int elements_offset) { | 3229 int elements_offset) { |
| 3254 Label smi_value, is_nan, maybe_nan, not_nan, have_double_value, done; | 3230 Label smi_value, done; |
| 3255 | 3231 |
| 3256 JumpIfSmi(maybe_number, &smi_value, Label::kNear); | 3232 JumpIfSmi(maybe_number, &smi_value, Label::kNear); |
| 3257 | 3233 |
| 3258 CheckMap(maybe_number, | 3234 CheckMap(maybe_number, |
| 3259 isolate()->factory()->heap_number_map(), | 3235 isolate()->factory()->heap_number_map(), |
| 3260 fail, | 3236 fail, |
| 3261 DONT_DO_SMI_CHECK); | 3237 DONT_DO_SMI_CHECK); |
| 3262 | 3238 |
| 3263 // Double value, canonicalize NaN. | 3239 // Double value, turn potential sNaN into qNaN. |
| 3264 uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); | 3240 Move(xmm_scratch, 1.0); |
| 3265 cmpl(FieldOperand(maybe_number, offset), | 3241 mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); |
| 3266 Immediate(kNaNOrInfinityLowerBoundUpper32)); | 3242 jmp(&done, Label::kNear); |
| 3267 j(greater_equal, &maybe_nan, Label::kNear); | |
| 3268 | |
| 3269 bind(¬_nan); | |
| 3270 movsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); | |
| 3271 bind(&have_double_value); | |
| 3272 movsd(FieldOperand(elements, index, times_8, | |
| 3273 FixedDoubleArray::kHeaderSize - elements_offset), | |
| 3274 xmm_scratch); | |
| 3275 jmp(&done); | |
| 3276 | |
| 3277 bind(&maybe_nan); | |
| 3278 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise | |
| 3279 // it's an Infinity, and the non-NaN code path applies. | |
| 3280 j(greater, &is_nan, Label::kNear); | |
| 3281 cmpl(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); | |
| 3282 j(zero, ¬_nan); | |
| 3283 bind(&is_nan); | |
| 3284 // Convert all NaNs to the same canonical NaN value when they are stored in | |
| 3285 // the double array. | |
| 3286 Set(kScratchRegister, | |
| 3287 bit_cast<uint64_t>( | |
| 3288 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | |
| 3289 movq(xmm_scratch, kScratchRegister); | |
| 3290 jmp(&have_double_value, Label::kNear); | |
| 3291 | 3243 |
| 3292 bind(&smi_value); | 3244 bind(&smi_value); |
| 3293 // Value is a smi. convert to a double and store. | 3245 // Value is a smi. convert to a double and store. |
| 3294 // Preserve original value. | 3246 // Preserve original value. |
| 3295 SmiToInteger32(kScratchRegister, maybe_number); | 3247 SmiToInteger32(kScratchRegister, maybe_number); |
| 3296 Cvtlsi2sd(xmm_scratch, kScratchRegister); | 3248 Cvtlsi2sd(xmm_scratch, kScratchRegister); |
| 3249 bind(&done); |
| 3297 movsd(FieldOperand(elements, index, times_8, | 3250 movsd(FieldOperand(elements, index, times_8, |
| 3298 FixedDoubleArray::kHeaderSize - elements_offset), | 3251 FixedDoubleArray::kHeaderSize - elements_offset), |
| 3299 xmm_scratch); | 3252 xmm_scratch); |
| 3300 bind(&done); | |
| 3301 } | 3253 } |
| 3302 | 3254 |
| 3303 | 3255 |
| 3304 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { | 3256 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { |
| 3305 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); | 3257 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); |
| 3306 } | 3258 } |
| 3307 | 3259 |
| 3308 | 3260 |
| 3309 void MacroAssembler::CheckMap(Register obj, | 3261 void MacroAssembler::CheckMap(Register obj, |
| 3310 Handle<Map> map, | 3262 Handle<Map> map, |
| (...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5227 if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); | 5179 if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); |
| 5228 movl(rax, dividend); | 5180 movl(rax, dividend); |
| 5229 shrl(rax, Immediate(31)); | 5181 shrl(rax, Immediate(31)); |
| 5230 addl(rdx, rax); | 5182 addl(rdx, rax); |
| 5231 } | 5183 } |
| 5232 | 5184 |
| 5233 | 5185 |
| 5234 } } // namespace v8::internal | 5186 } } // namespace v8::internal |
| 5235 | 5187 |
| 5236 #endif // V8_TARGET_ARCH_X64 | 5188 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |