| 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 |