| 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 4697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4708 // scratch1 is now effective address of the double element | 4708 // scratch1 is now effective address of the double element |
| 4709 | 4709 |
| 4710 Register untagged_value = scratch2; | 4710 Register untagged_value = scratch2; |
| 4711 SmiUntag(untagged_value, value_reg); | 4711 SmiUntag(untagged_value, value_reg); |
| 4712 mtc1(untagged_value, f2); | 4712 mtc1(untagged_value, f2); |
| 4713 cvt_d_w(f0, f2); | 4713 cvt_d_w(f0, f2); |
| 4714 sdc1(f0, MemOperand(scratch1, 0)); | 4714 sdc1(f0, MemOperand(scratch1, 0)); |
| 4715 bind(&done); | 4715 bind(&done); |
| 4716 } | 4716 } |
| 4717 | 4717 |
| 4718 void MacroAssembler::SubNanPreservePayloadAndSign_s(FPURegister fd, |
| 4719 FPURegister fs, |
| 4720 FPURegister ft) { |
| 4721 Label maybe_nan, not_nan2008, nan2008, done; |
| 4722 Register scratch1 = t8; |
| 4723 Register scratch2 = t9; |
| 4724 DoubleRegister double_scratch = f8; |
| 4725 |
| 4726 sub_s(fd, fs, ft); |
| 4727 // Check if the result of subtraction is NaN or infinity. |
| 4728 sub_s(double_scratch, fd, fd); |
| 4729 BranchF32(&done, nullptr, eq, double_scratch, kDoubleRegZero); |
| 4730 |
| 4731 // Check if first operand is a possible NaN. |
| 4732 mfc1(scratch1, fs); |
| 4733 And(scratch2, scratch1, Operand(FloatConstants::kExponentMask)); |
| 4734 Branch(&maybe_nan, eq, scratch2, Operand(FloatConstants::kExponentMask)); |
| 4735 // Check if second operand is a possible NaN. |
| 4736 mfc1(scratch1, ft); |
| 4737 And(scratch2, scratch1, Operand(FloatConstants::kExponentMask)); |
| 4738 Branch(&done, ne, scratch2, Operand(FloatConstants::kExponentMask)); |
| 4739 |
| 4740 // Check if possible NaN is actually NaN. |
| 4741 bind(&maybe_nan); |
| 4742 And(scratch2, scratch1, Operand(FloatConstants::kMantissaMask)); |
| 4743 Branch(&done, eq, scratch2, Operand(zero_reg)); |
| 4744 // If NaN is found, return it as qNaN with same payload. |
| 4745 // Determine the qNaN encoding for the current architecture. |
| 4746 LoadRoot(scratch2, Heap::kNanValueRootIndex); |
| 4747 ldc1(double_scratch, FieldMemOperand(scratch2, HeapNumber::kValueOffset)); |
| 4748 Mfhc1(scratch2, double_scratch); |
| 4749 And(scratch2, scratch2, Operand(DoubleConstants::kNanTypeMask)); |
| 4750 // Make NaN quiet. |
| 4751 Branch(&nan2008, gt, scratch2, Operand(zero_reg)); |
| 4752 And(scratch1, scratch1, Operand(~FloatConstants::kNanTypeMask)); |
| 4753 Branch(¬_nan2008); |
| 4754 bind(&nan2008); |
| 4755 Or(scratch1, scratch1, Operand(FloatConstants::kNanTypeMask)); |
| 4756 bind(¬_nan2008); |
| 4757 mtc1(scratch1, fd); |
| 4758 bind(&done); |
| 4759 } |
| 4760 |
| 4761 void MacroAssembler::SubNanPreservePayloadAndSign_d(FPURegister fd, |
| 4762 FPURegister fs, |
| 4763 FPURegister ft) { |
| 4764 Label maybe_nan, is_nan, not_nan2008, nan2008, done; |
| 4765 Register scratch1 = t7; |
| 4766 Register scratch2 = t8; |
| 4767 Register scratch3 = t9; |
| 4768 DoubleRegister double_scratch = f8; |
| 4769 |
| 4770 sub_d(fd, fs, ft); |
| 4771 // Check if the result of subtraction is NaN or infinity. |
| 4772 sub_d(double_scratch, fd, fd); |
| 4773 BranchF64(&done, nullptr, eq, double_scratch, kDoubleRegZero); |
| 4774 |
| 4775 // Check if first operand is a possible NaN. |
| 4776 Mfhc1(scratch1, fs); |
| 4777 And(scratch2, scratch1, Operand(~DoubleConstants::kSignMask)); |
| 4778 mfc1(scratch3, fs); |
| 4779 Branch(&is_nan, gt, scratch2, Operand(DoubleConstants::kExponentMask)); |
| 4780 Branch(&maybe_nan, eq, scratch2, Operand(DoubleConstants::kExponentMask)); |
| 4781 // Check if second operand is a possible NaN. |
| 4782 Mfhc1(scratch1, ft); |
| 4783 And(scratch2, scratch1, Operand(~DoubleConstants::kSignMask)); |
| 4784 mfc1(scratch3, ft); |
| 4785 Branch(&is_nan, gt, scratch2, Operand(DoubleConstants::kExponentMask)); |
| 4786 Branch(&done, ne, scratch2, Operand(DoubleConstants::kExponentMask)); |
| 4787 |
| 4788 // Check if possible NaN is actually NaN. |
| 4789 bind(&maybe_nan); |
| 4790 Branch(&done, eq, scratch3, Operand(zero_reg)); |
| 4791 // If NaN is found, return it as qNaN with same payload. |
| 4792 bind(&is_nan); |
| 4793 // Determine the qNaN encoding for the current architecture. |
| 4794 LoadRoot(scratch2, Heap::kNanValueRootIndex); |
| 4795 ldc1(double_scratch, FieldMemOperand(scratch2, HeapNumber::kValueOffset)); |
| 4796 Mfhc1(scratch2, double_scratch); |
| 4797 And(scratch2, scratch2, Operand(DoubleConstants::kNanTypeMask)); |
| 4798 // Make NaN quiet. |
| 4799 Branch(&nan2008, gt, scratch2, Operand(zero_reg)); |
| 4800 And(scratch1, scratch1, Operand(~DoubleConstants::kNanTypeMask)); |
| 4801 Branch(¬_nan2008); |
| 4802 bind(&nan2008); |
| 4803 Or(scratch1, scratch1, Operand(DoubleConstants::kNanTypeMask)); |
| 4804 bind(¬_nan2008); |
| 4805 mtc1(scratch3, fd); |
| 4806 Mthc1(scratch1, fd); |
| 4807 bind(&done); |
| 4808 } |
| 4718 | 4809 |
| 4719 void MacroAssembler::CompareMapAndBranch(Register obj, | 4810 void MacroAssembler::CompareMapAndBranch(Register obj, |
| 4720 Register scratch, | 4811 Register scratch, |
| 4721 Handle<Map> map, | 4812 Handle<Map> map, |
| 4722 Label* early_success, | 4813 Label* early_success, |
| 4723 Condition cond, | 4814 Condition cond, |
| 4724 Label* branch_to) { | 4815 Label* branch_to) { |
| 4725 lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); | 4816 lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); |
| 4726 CompareMapAndBranch(scratch, map, early_success, cond, branch_to); | 4817 CompareMapAndBranch(scratch, map, early_success, cond, branch_to); |
| 4727 } | 4818 } |
| (...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6792 if (mag.shift > 0) sra(result, result, mag.shift); | 6883 if (mag.shift > 0) sra(result, result, mag.shift); |
| 6793 srl(at, dividend, 31); | 6884 srl(at, dividend, 31); |
| 6794 Addu(result, result, Operand(at)); | 6885 Addu(result, result, Operand(at)); |
| 6795 } | 6886 } |
| 6796 | 6887 |
| 6797 | 6888 |
| 6798 } // namespace internal | 6889 } // namespace internal |
| 6799 } // namespace v8 | 6890 } // namespace v8 |
| 6800 | 6891 |
| 6801 #endif // V8_TARGET_ARCH_MIPS | 6892 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |