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 <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
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 4648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4659 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, | 4659 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, |
4660 Register key_reg, | 4660 Register key_reg, |
4661 Register elements_reg, | 4661 Register elements_reg, |
4662 Register scratch1, | 4662 Register scratch1, |
4663 Register scratch2, | 4663 Register scratch2, |
4664 Register scratch3, | 4664 Register scratch3, |
4665 Label* fail, | 4665 Label* fail, |
4666 int elements_offset) { | 4666 int elements_offset) { |
4667 DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2, | 4667 DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2, |
4668 scratch3)); | 4668 scratch3)); |
4669 Label smi_value, maybe_nan, have_double_value, is_nan, done; | 4669 Label smi_value, done; |
4670 Register mantissa_reg = scratch2; | |
4671 Register exponent_reg = scratch3; | |
4672 | 4670 |
4673 // Handle smi values specially. | 4671 // Handle smi values specially. |
4674 JumpIfSmi(value_reg, &smi_value); | 4672 JumpIfSmi(value_reg, &smi_value); |
4675 | 4673 |
4676 // Ensure that the object is a heap number | 4674 // Ensure that the object is a heap number |
4677 CheckMap(value_reg, | 4675 CheckMap(value_reg, |
4678 scratch1, | 4676 scratch1, |
4679 Heap::kHeapNumberMapRootIndex, | 4677 Heap::kHeapNumberMapRootIndex, |
4680 fail, | 4678 fail, |
4681 DONT_DO_SMI_CHECK); | 4679 DONT_DO_SMI_CHECK); |
4682 | 4680 |
4683 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 | 4681 // Double value, turn potential sNaN into qNan. |
4684 // in the exponent. | 4682 DoubleRegister double_result = f0; |
4685 li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask)); | 4683 DoubleRegister double_scratch = f2; |
4686 lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); | |
4687 Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); | |
4688 | 4684 |
4689 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | 4685 ldc1(double_result, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
4690 | 4686 Branch(USE_DELAY_SLOT, &done); // Canonicalization is one instruction. |
4691 bind(&have_double_value); | 4687 FPUCanonicalizeNaN(double_result, double_result); |
4692 Lsa(scratch1, elements_reg, key_reg, kDoubleSizeLog2 - kSmiTagSize); | |
4693 sw(mantissa_reg, | |
4694 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset | |
4695 + kHoleNanLower32Offset)); | |
4696 sw(exponent_reg, | |
4697 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset | |
4698 + kHoleNanUpper32Offset)); | |
4699 jmp(&done); | |
4700 | |
4701 bind(&maybe_nan); | |
4702 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise | |
4703 // it's an Infinity, and the non-NaN code path applies. | |
4704 Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); | |
4705 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | |
4706 Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); | |
4707 bind(&is_nan); | |
4708 // Load canonical NaN for storing into the double array. | |
4709 LoadRoot(at, Heap::kNanValueRootIndex); | |
4710 lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset)); | |
4711 lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset)); | |
4712 jmp(&have_double_value); | |
4713 | 4688 |
4714 bind(&smi_value); | 4689 bind(&smi_value); |
| 4690 Register untagged_value = scratch2; |
| 4691 SmiUntag(untagged_value, value_reg); |
| 4692 mtc1(untagged_value, double_scratch); |
| 4693 cvt_d_w(double_result, double_scratch); |
| 4694 |
| 4695 bind(&done); |
4715 Addu(scratch1, elements_reg, | 4696 Addu(scratch1, elements_reg, |
4716 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - | 4697 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - |
4717 elements_offset)); | 4698 elements_offset)); |
4718 Lsa(scratch1, scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); | 4699 Lsa(scratch1, scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
4719 // scratch1 is now effective address of the double element | 4700 // scratch1 is now effective address of the double element |
4720 | 4701 sdc1(double_result, MemOperand(scratch1, 0)); |
4721 Register untagged_value = scratch2; | |
4722 SmiUntag(untagged_value, value_reg); | |
4723 mtc1(untagged_value, f2); | |
4724 cvt_d_w(f0, f2); | |
4725 sdc1(f0, MemOperand(scratch1, 0)); | |
4726 bind(&done); | |
4727 } | 4702 } |
4728 | 4703 |
4729 void MacroAssembler::SubNanPreservePayloadAndSign_s(FloatRegister fd, | 4704 void MacroAssembler::SubNanPreservePayloadAndSign_s(FloatRegister fd, |
4730 FloatRegister fs, | 4705 FloatRegister fs, |
4731 FloatRegister ft) { | 4706 FloatRegister ft) { |
4732 FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; | 4707 FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; |
4733 Label check_nan, save_payload, done; | 4708 Label check_nan, save_payload, done; |
4734 Register scratch1 = t8; | 4709 Register scratch1 = t8; |
4735 Register scratch2 = t9; | 4710 Register scratch2 = t9; |
4736 | 4711 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4850 Label* fail, | 4825 Label* fail, |
4851 SmiCheckType smi_check_type) { | 4826 SmiCheckType smi_check_type) { |
4852 if (smi_check_type == DO_SMI_CHECK) { | 4827 if (smi_check_type == DO_SMI_CHECK) { |
4853 JumpIfSmi(obj, fail); | 4828 JumpIfSmi(obj, fail); |
4854 } | 4829 } |
4855 lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); | 4830 lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); |
4856 LoadRoot(at, index); | 4831 LoadRoot(at, index); |
4857 Branch(fail, ne, scratch, Operand(at)); | 4832 Branch(fail, ne, scratch, Operand(at)); |
4858 } | 4833 } |
4859 | 4834 |
| 4835 void MacroAssembler::FPUCanonicalizeNaN(const DoubleRegister dst, |
| 4836 const DoubleRegister src) { |
| 4837 sub_d(dst, src, kDoubleRegZero); |
| 4838 } |
4860 | 4839 |
4861 void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { | 4840 void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { |
4862 li(value, Operand(cell)); | 4841 li(value, Operand(cell)); |
4863 lw(value, FieldMemOperand(value, WeakCell::kValueOffset)); | 4842 lw(value, FieldMemOperand(value, WeakCell::kValueOffset)); |
4864 } | 4843 } |
4865 | 4844 |
4866 | 4845 |
4867 void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, | 4846 void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, |
4868 Label* miss) { | 4847 Label* miss) { |
4869 GetWeakValue(value, cell); | 4848 GetWeakValue(value, cell); |
(...skipping 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6874 if (mag.shift > 0) sra(result, result, mag.shift); | 6853 if (mag.shift > 0) sra(result, result, mag.shift); |
6875 srl(at, dividend, 31); | 6854 srl(at, dividend, 31); |
6876 Addu(result, result, Operand(at)); | 6855 Addu(result, result, Operand(at)); |
6877 } | 6856 } |
6878 | 6857 |
6879 | 6858 |
6880 } // namespace internal | 6859 } // namespace internal |
6881 } // namespace v8 | 6860 } // namespace v8 |
6882 | 6861 |
6883 #endif // V8_TARGET_ARCH_MIPS | 6862 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |