Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 13470002: Test behavior of qNaN and sNaN (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/nans.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4507 matching lines...) Expand 10 before | Expand all | Expand 10 after
4518 __ bind(&smi_done); 4518 __ bind(&smi_done);
4519 __ mov(eax, edx); 4519 __ mov(eax, edx);
4520 __ ret(0); 4520 __ ret(0);
4521 __ bind(&non_smi); 4521 __ bind(&non_smi);
4522 4522
4523 // NOTICE! This code is only reached after a smi-fast-case check, so 4523 // NOTICE! This code is only reached after a smi-fast-case check, so
4524 // it is certain that at least one operand isn't a smi. 4524 // it is certain that at least one operand isn't a smi.
4525 4525
4526 // Identical objects can be compared fast, but there are some tricky cases 4526 // Identical objects can be compared fast, but there are some tricky cases
4527 // for NaN and undefined. 4527 // for NaN and undefined.
4528 Label generic_heap_number_comparison;
4528 { 4529 {
4529 Label not_identical; 4530 Label not_identical;
4530 __ cmp(eax, edx); 4531 __ cmp(eax, edx);
4531 __ j(not_equal, &not_identical); 4532 __ j(not_equal, &not_identical);
4532 4533
4533 if (cc != equal) { 4534 if (cc != equal) {
4534 // Check for undefined. undefined OP undefined is false even though 4535 // Check for undefined. undefined OP undefined is false even though
4535 // undefined == undefined. 4536 // undefined == undefined.
4536 Label check_for_nan; 4537 Label check_for_nan;
4537 __ cmp(edx, masm->isolate()->factory()->undefined_value()); 4538 __ cmp(edx, masm->isolate()->factory()->undefined_value());
4538 __ j(not_equal, &check_for_nan, Label::kNear); 4539 __ j(not_equal, &check_for_nan, Label::kNear);
4539 __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 4540 __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
4540 __ ret(0); 4541 __ ret(0);
4541 __ bind(&check_for_nan); 4542 __ bind(&check_for_nan);
4542 } 4543 }
4543 4544
4544 // Test for NaN. Sadly, we can't just compare to factory->nan_value(), 4545 // Test for NaN. Compare heap numbers in a general way,
4545 // so we do the second best thing - test it ourselves. 4546 // to hanlde NaNs correctly.
4546 Label heap_number;
4547 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 4547 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
4548 Immediate(masm->isolate()->factory()->heap_number_map())); 4548 Immediate(masm->isolate()->factory()->heap_number_map()));
4549 __ j(equal, &heap_number, Label::kNear); 4549 __ j(equal, &generic_heap_number_comparison, Label::kNear);
4550 if (cc != equal) { 4550 if (cc != equal) {
4551 // Call runtime on identical JSObjects. Otherwise return equal. 4551 // Call runtime on identical JSObjects. Otherwise return equal.
4552 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 4552 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
4553 __ j(above_equal, &not_identical); 4553 __ j(above_equal, &not_identical);
4554 } 4554 }
4555 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 4555 __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
4556 __ ret(0); 4556 __ ret(0);
4557 4557
4558 __ bind(&heap_number);
4559 // It is a heap number, so return non-equal if it's NaN and equal if
4560 // it's not NaN.
4561 // The representation of NaN values has all exponent bits (52..62) set,
4562 // and not all mantissa bits (0..51) clear.
4563 // We only accept QNaNs, which have bit 51 set.
4564 // Read top bits of double representation (second word of value).
4565
4566 // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
4567 // all bits in the mask are set. We only need to check the word
4568 // that contains the exponent and high bit of the mantissa.
4569 STATIC_ASSERT(((kQuietNaNHighBitsMask << 1) & 0x80000000u) != 0);
4570 __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
4571 __ Set(eax, Immediate(0));
4572 // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
4573 // bits.
4574 __ add(edx, edx);
4575 __ cmp(edx, kQuietNaNHighBitsMask << 1);
4576 if (cc == equal) {
4577 STATIC_ASSERT(EQUAL != 1);
4578 __ setcc(above_equal, eax);
4579 __ ret(0);
4580 } else {
4581 Label nan;
4582 __ j(above_equal, &nan, Label::kNear);
4583 __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
4584 __ ret(0);
4585 __ bind(&nan);
4586 __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
4587 __ ret(0);
4588 }
4589 4558
4590 __ bind(&not_identical); 4559 __ bind(&not_identical);
4591 } 4560 }
4592 4561
4593 // Strict equality can quickly decide whether objects are equal. 4562 // Strict equality can quickly decide whether objects are equal.
4594 // Non-strict object equality is slower, so it is handled later in the stub. 4563 // Non-strict object equality is slower, so it is handled later in the stub.
4595 if (cc == equal && strict()) { 4564 if (cc == equal && strict()) {
4596 Label slow; // Fallthrough label. 4565 Label slow; // Fallthrough label.
4597 Label not_smis; 4566 Label not_smis;
4598 // If we're doing a strict equality comparison, we don't have to do 4567 // If we're doing a strict equality comparison, we don't have to do
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4658 __ CmpInstanceType(ecx, ODDBALL_TYPE); 4627 __ CmpInstanceType(ecx, ODDBALL_TYPE);
4659 __ j(equal, &return_not_equal); 4628 __ j(equal, &return_not_equal);
4660 4629
4661 // Fall through to the general case. 4630 // Fall through to the general case.
4662 __ bind(&slow); 4631 __ bind(&slow);
4663 } 4632 }
4664 4633
4665 // Generate the number comparison code. 4634 // Generate the number comparison code.
4666 Label non_number_comparison; 4635 Label non_number_comparison;
4667 Label unordered; 4636 Label unordered;
4637 __ bind(&generic_heap_number_comparison);
4668 if (CpuFeatures::IsSupported(SSE2)) { 4638 if (CpuFeatures::IsSupported(SSE2)) {
4669 CpuFeatureScope use_sse2(masm, SSE2); 4639 CpuFeatureScope use_sse2(masm, SSE2);
4670 CpuFeatureScope use_cmov(masm, CMOV); 4640 CpuFeatureScope use_cmov(masm, CMOV);
4671 4641
4672 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); 4642 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
4673 __ ucomisd(xmm0, xmm1); 4643 __ ucomisd(xmm0, xmm1);
4674 4644
4675 // Don't base result on EFLAGS when a NaN is involved. 4645 // Don't base result on EFLAGS when a NaN is involved.
4676 __ j(parity_even, &unordered, Label::kNear); 4646 __ j(parity_even, &unordered, Label::kNear);
4677 // Return a result of -1, 0, or 1, based on EFLAGS. 4647 // Return a result of -1, 0, or 1, based on EFLAGS.
(...skipping 3184 matching lines...) Expand 10 before | Expand all | Expand 10 after
7862 // Restore ecx. 7832 // Restore ecx.
7863 __ pop(ecx); 7833 __ pop(ecx);
7864 __ ret(0); 7834 __ ret(0);
7865 } 7835 }
7866 7836
7867 #undef __ 7837 #undef __
7868 7838
7869 } } // namespace v8::internal 7839 } } // namespace v8::internal
7870 7840
7871 #endif // V8_TARGET_ARCH_IA32 7841 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/nans.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698