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" |
11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
12 #include "src/codegen.h" | 12 #include "src/codegen.h" |
13 #include "src/debug/debug.h" | 13 #include "src/debug/debug.h" |
14 #include "src/mips/macro-assembler-mips.h" | 14 #include "src/mips/macro-assembler-mips.h" |
15 #include "src/register-configuration.h" | 15 #include "src/register-configuration.h" |
16 #include "src/runtime/runtime.h" | 16 #include "src/runtime/runtime.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 | 20 |
| 21 // Floating point constants. |
| 22 const uint32_t kDoubleSignMask = HeapNumber::kSignMask; |
| 23 const uint32_t kDoubleExponentShift = HeapNumber::kExponentShift; |
| 24 const uint32_t kDoubleNaNShift = kDoubleExponentShift - 1; |
| 25 const uint32_t kDoubleNaNMask = |
| 26 kDoubleSignMask | HeapNumber::kExponentMask | (1 << kDoubleNaNShift); |
| 27 |
| 28 const uint32_t kSingleSignMask = kBinary32SignMask; |
| 29 const uint32_t kSingleExponentMask = kBinary32ExponentMask; |
| 30 const uint32_t kSingleExponentShift = kBinary32ExponentShift; |
| 31 const uint32_t kSingleNaNShift = kSingleExponentShift - 1; |
| 32 const uint32_t kSingleNaNMask = |
| 33 kSingleSignMask | kSingleExponentMask | (1 << kSingleNaNShift); |
| 34 |
21 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size, | 35 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size, |
22 CodeObjectRequired create_code_object) | 36 CodeObjectRequired create_code_object) |
23 : Assembler(arg_isolate, buffer, size), | 37 : Assembler(arg_isolate, buffer, size), |
24 generating_stub_(false), | 38 generating_stub_(false), |
25 has_frame_(false), | 39 has_frame_(false), |
26 has_double_zero_reg_set_(false) { | 40 has_double_zero_reg_set_(false) { |
27 if (create_code_object == CodeObjectRequired::kYes) { | 41 if (create_code_object == CodeObjectRequired::kYes) { |
28 code_object_ = | 42 code_object_ = |
29 Handle<Object>::New(isolate()->heap()->undefined_value(), isolate()); | 43 Handle<Object>::New(isolate()->heap()->undefined_value(), isolate()); |
30 } | 44 } |
(...skipping 4677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4708 // scratch1 is now effective address of the double element | 4722 // scratch1 is now effective address of the double element |
4709 | 4723 |
4710 Register untagged_value = scratch2; | 4724 Register untagged_value = scratch2; |
4711 SmiUntag(untagged_value, value_reg); | 4725 SmiUntag(untagged_value, value_reg); |
4712 mtc1(untagged_value, f2); | 4726 mtc1(untagged_value, f2); |
4713 cvt_d_w(f0, f2); | 4727 cvt_d_w(f0, f2); |
4714 sdc1(f0, MemOperand(scratch1, 0)); | 4728 sdc1(f0, MemOperand(scratch1, 0)); |
4715 bind(&done); | 4729 bind(&done); |
4716 } | 4730 } |
4717 | 4731 |
| 4732 void MacroAssembler::SubNanPreservePayloadAndSign_s(FloatRegister fd, |
| 4733 FloatRegister fs, |
| 4734 FloatRegister ft) { |
| 4735 FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; |
| 4736 Label check_nan, save_payload, done; |
| 4737 Register scratch1 = t8; |
| 4738 Register scratch2 = t9; |
| 4739 |
| 4740 sub_s(dest, fs, ft); |
| 4741 // Check if the result of subtraction is NaN. |
| 4742 BranchF32(nullptr, &check_nan, eq, fs, ft); |
| 4743 Branch(USE_DELAY_SLOT, &done); |
| 4744 dest.is(fd) ? nop() : mov_s(fd, dest); |
| 4745 |
| 4746 bind(&check_nan); |
| 4747 // Check if first operand is a NaN. |
| 4748 mfc1(scratch1, fs); |
| 4749 BranchF32(nullptr, &save_payload, eq, fs, fs); |
| 4750 // Second operand must be a NaN. |
| 4751 mfc1(scratch1, ft); |
| 4752 |
| 4753 bind(&save_payload); |
| 4754 // Reserve payload. |
| 4755 And(scratch1, scratch1, |
| 4756 Operand(kSingleSignMask | ((1 << kSingleNaNShift) - 1))); |
| 4757 mfc1(scratch2, dest); |
| 4758 And(scratch2, scratch2, Operand(kSingleNaNMask)); |
| 4759 Or(scratch2, scratch2, scratch1); |
| 4760 mtc1(scratch2, fd); |
| 4761 |
| 4762 bind(&done); |
| 4763 } |
| 4764 |
| 4765 void MacroAssembler::SubNanPreservePayloadAndSign_d(DoubleRegister fd, |
| 4766 DoubleRegister fs, |
| 4767 DoubleRegister ft) { |
| 4768 FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; |
| 4769 Label check_nan, save_payload, done; |
| 4770 Register scratch1 = t8; |
| 4771 Register scratch2 = t9; |
| 4772 |
| 4773 sub_d(dest, fs, ft); |
| 4774 // Check if the result of subtraction is NaN. |
| 4775 BranchF64(nullptr, &check_nan, eq, fs, ft); |
| 4776 Branch(USE_DELAY_SLOT, &done); |
| 4777 dest.is(fd) ? nop() : mov_d(fd, dest); |
| 4778 |
| 4779 bind(&check_nan); |
| 4780 // Check if first operand is a NaN. |
| 4781 Mfhc1(scratch1, fs); |
| 4782 mov_s(dest, fs); |
| 4783 BranchF64(nullptr, &save_payload, eq, fs, fs); |
| 4784 // Second operand must be a NaN. |
| 4785 Mfhc1(scratch1, ft); |
| 4786 mov_s(dest, ft); |
| 4787 |
| 4788 bind(&save_payload); |
| 4789 // Reserve payload. |
| 4790 And(scratch1, scratch1, |
| 4791 Operand(kDoubleSignMask | ((1 << kDoubleNaNShift) - 1))); |
| 4792 Mfhc1(scratch2, dest); |
| 4793 And(scratch2, scratch2, Operand(kDoubleNaNMask)); |
| 4794 Or(scratch2, scratch2, scratch1); |
| 4795 Move_s(fd, dest); |
| 4796 Mthc1(scratch2, fd); |
| 4797 |
| 4798 bind(&done); |
| 4799 } |
4718 | 4800 |
4719 void MacroAssembler::CompareMapAndBranch(Register obj, | 4801 void MacroAssembler::CompareMapAndBranch(Register obj, |
4720 Register scratch, | 4802 Register scratch, |
4721 Handle<Map> map, | 4803 Handle<Map> map, |
4722 Label* early_success, | 4804 Label* early_success, |
4723 Condition cond, | 4805 Condition cond, |
4724 Label* branch_to) { | 4806 Label* branch_to) { |
4725 lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); | 4807 lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); |
4726 CompareMapAndBranch(scratch, map, early_success, cond, branch_to); | 4808 CompareMapAndBranch(scratch, map, early_success, cond, branch_to); |
4727 } | 4809 } |
(...skipping 2067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6795 if (mag.shift > 0) sra(result, result, mag.shift); | 6877 if (mag.shift > 0) sra(result, result, mag.shift); |
6796 srl(at, dividend, 31); | 6878 srl(at, dividend, 31); |
6797 Addu(result, result, Operand(at)); | 6879 Addu(result, result, Operand(at)); |
6798 } | 6880 } |
6799 | 6881 |
6800 | 6882 |
6801 } // namespace internal | 6883 } // namespace internal |
6802 } // namespace v8 | 6884 } // namespace v8 |
6803 | 6885 |
6804 #endif // V8_TARGET_ARCH_MIPS | 6886 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |