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 3409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3420 } | 3420 } |
3421 | 3421 |
3422 | 3422 |
3423 void MacroAssembler::StoreNumberToDoubleElements( | 3423 void MacroAssembler::StoreNumberToDoubleElements( |
3424 Register maybe_number, | 3424 Register maybe_number, |
3425 Register elements, | 3425 Register elements, |
3426 Register index, | 3426 Register index, |
3427 XMMRegister xmm_scratch, | 3427 XMMRegister xmm_scratch, |
3428 Label* fail, | 3428 Label* fail, |
3429 int elements_offset) { | 3429 int elements_offset) { |
3430 Label smi_value, is_nan, maybe_nan, not_nan, have_double_value, done; | 3430 Label smi_value, done; |
3431 | 3431 |
3432 JumpIfSmi(maybe_number, &smi_value, Label::kNear); | 3432 JumpIfSmi(maybe_number, &smi_value, Label::kNear); |
3433 | 3433 |
3434 CheckMap(maybe_number, | 3434 CheckMap(maybe_number, |
3435 isolate()->factory()->heap_number_map(), | 3435 isolate()->factory()->heap_number_map(), |
3436 fail, | 3436 fail, |
3437 DONT_DO_SMI_CHECK); | 3437 DONT_DO_SMI_CHECK); |
3438 | 3438 |
3439 // Double value, canonicalize NaN. | 3439 // Double value, turn potential sNaN into qNaN. |
3440 uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); | 3440 Move(xmm_scratch, 1.0); |
3441 cmpl(FieldOperand(maybe_number, offset), | 3441 mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); |
3442 Immediate(kNaNOrInfinityLowerBoundUpper32)); | 3442 jmp(&done, Label::kNear); |
3443 j(greater_equal, &maybe_nan, Label::kNear); | |
3444 | |
3445 bind(¬_nan); | |
3446 movsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); | |
3447 bind(&have_double_value); | |
3448 movsd(FieldOperand(elements, index, times_8, | |
3449 FixedDoubleArray::kHeaderSize - elements_offset), | |
3450 xmm_scratch); | |
3451 jmp(&done); | |
3452 | |
3453 bind(&maybe_nan); | |
3454 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise | |
3455 // it's an Infinity, and the non-NaN code path applies. | |
3456 j(greater, &is_nan, Label::kNear); | |
3457 cmpl(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); | |
3458 j(zero, ¬_nan); | |
3459 bind(&is_nan); | |
3460 // Convert all NaNs to the same canonical NaN value when they are stored in | |
3461 // the double array. | |
3462 Set(kScratchRegister, | |
3463 bit_cast<uint64_t>( | |
3464 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | |
3465 movq(xmm_scratch, kScratchRegister); | |
3466 jmp(&have_double_value, Label::kNear); | |
3467 | 3443 |
3468 bind(&smi_value); | 3444 bind(&smi_value); |
3469 // Value is a smi. convert to a double and store. | 3445 // Value is a smi. convert to a double and store. |
3470 // Preserve original value. | 3446 // Preserve original value. |
3471 SmiToInteger32(kScratchRegister, maybe_number); | 3447 SmiToInteger32(kScratchRegister, maybe_number); |
3472 Cvtlsi2sd(xmm_scratch, kScratchRegister); | 3448 Cvtlsi2sd(xmm_scratch, kScratchRegister); |
| 3449 bind(&done); |
3473 movsd(FieldOperand(elements, index, times_8, | 3450 movsd(FieldOperand(elements, index, times_8, |
3474 FixedDoubleArray::kHeaderSize - elements_offset), | 3451 FixedDoubleArray::kHeaderSize - elements_offset), |
3475 xmm_scratch); | 3452 xmm_scratch); |
3476 bind(&done); | |
3477 } | 3453 } |
3478 | 3454 |
3479 | 3455 |
3480 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { | 3456 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { |
3481 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); | 3457 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); |
3482 } | 3458 } |
3483 | 3459 |
3484 | 3460 |
3485 void MacroAssembler::CheckMap(Register obj, | 3461 void MacroAssembler::CheckMap(Register obj, |
3486 Handle<Map> map, | 3462 Handle<Map> map, |
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5403 if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); | 5379 if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); |
5404 movl(rax, dividend); | 5380 movl(rax, dividend); |
5405 shrl(rax, Immediate(31)); | 5381 shrl(rax, Immediate(31)); |
5406 addl(rdx, rax); | 5382 addl(rdx, rax); |
5407 } | 5383 } |
5408 | 5384 |
5409 | 5385 |
5410 } } // namespace v8::internal | 5386 } } // namespace v8::internal |
5411 | 5387 |
5412 #endif // V8_TARGET_ARCH_X64 | 5388 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |