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 |