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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4723 and_(overflow_dst, overflow_dst, scratch); | 4723 and_(overflow_dst, overflow_dst, scratch); |
4724 } else { | 4724 } else { |
4725 daddu(dst, left, right); | 4725 daddu(dst, left, right); |
4726 xor_(overflow_dst, dst, left); | 4726 xor_(overflow_dst, dst, left); |
4727 xor_(scratch, dst, right); | 4727 xor_(scratch, dst, right); |
4728 and_(overflow_dst, scratch, overflow_dst); | 4728 and_(overflow_dst, scratch, overflow_dst); |
4729 } | 4729 } |
4730 } | 4730 } |
4731 | 4731 |
4732 | 4732 |
| 4733 static inline void BranchOvfHelper(MacroAssembler* masm, Register overflow_dst, |
| 4734 Label* overflow_label, |
| 4735 Label* no_overflow_label) { |
| 4736 DCHECK(overflow_label || no_overflow_label); |
| 4737 if (!overflow_label) { |
| 4738 DCHECK(no_overflow_label); |
| 4739 masm->Branch(no_overflow_label, ge, overflow_dst, Operand(zero_reg)); |
| 4740 } else { |
| 4741 masm->Branch(overflow_label, lt, overflow_dst, Operand(zero_reg)); |
| 4742 if (no_overflow_label) masm->Branch(no_overflow_label); |
| 4743 } |
| 4744 } |
| 4745 |
| 4746 |
| 4747 void MacroAssembler::DaddBranchOvf(Register dst, Register left, |
| 4748 const Operand& right, Label* overflow_label, |
| 4749 Label* no_overflow_label, Register scratch) { |
| 4750 if (right.is_reg()) { |
| 4751 DaddBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 4752 scratch); |
| 4753 } else { |
| 4754 Register overflow_dst = t9; |
| 4755 DCHECK(!dst.is(scratch)); |
| 4756 DCHECK(!dst.is(overflow_dst)); |
| 4757 DCHECK(!scratch.is(overflow_dst)); |
| 4758 DCHECK(!left.is(overflow_dst)); |
| 4759 li(overflow_dst, right); // Load right. |
| 4760 if (dst.is(left)) { |
| 4761 mov(scratch, left); // Preserve left. |
| 4762 Daddu(dst, left, overflow_dst); // Left is overwritten. |
| 4763 xor_(scratch, dst, scratch); // Original left. |
| 4764 xor_(overflow_dst, dst, overflow_dst); |
| 4765 and_(overflow_dst, overflow_dst, scratch); |
| 4766 } else { |
| 4767 Daddu(dst, left, overflow_dst); |
| 4768 xor_(scratch, dst, overflow_dst); |
| 4769 xor_(overflow_dst, dst, left); |
| 4770 and_(overflow_dst, scratch, overflow_dst); |
| 4771 } |
| 4772 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 4773 } |
| 4774 } |
| 4775 |
| 4776 |
| 4777 void MacroAssembler::DaddBranchOvf(Register dst, Register left, Register right, |
| 4778 Label* overflow_label, |
| 4779 Label* no_overflow_label, Register scratch) { |
| 4780 Register overflow_dst = t9; |
| 4781 DCHECK(!dst.is(scratch)); |
| 4782 DCHECK(!dst.is(overflow_dst)); |
| 4783 DCHECK(!scratch.is(overflow_dst)); |
| 4784 DCHECK(!left.is(overflow_dst)); |
| 4785 DCHECK(!right.is(overflow_dst)); |
| 4786 DCHECK(!left.is(scratch)); |
| 4787 DCHECK(!right.is(scratch)); |
| 4788 |
| 4789 if (left.is(right) && dst.is(left)) { |
| 4790 mov(overflow_dst, right); |
| 4791 right = overflow_dst; |
| 4792 } |
| 4793 |
| 4794 if (dst.is(left)) { |
| 4795 mov(scratch, left); // Preserve left. |
| 4796 daddu(dst, left, right); // Left is overwritten. |
| 4797 xor_(scratch, dst, scratch); // Original left. |
| 4798 xor_(overflow_dst, dst, right); |
| 4799 and_(overflow_dst, overflow_dst, scratch); |
| 4800 } else if (dst.is(right)) { |
| 4801 mov(scratch, right); // Preserve right. |
| 4802 daddu(dst, left, right); // Right is overwritten. |
| 4803 xor_(scratch, dst, scratch); // Original right. |
| 4804 xor_(overflow_dst, dst, left); |
| 4805 and_(overflow_dst, overflow_dst, scratch); |
| 4806 } else { |
| 4807 daddu(dst, left, right); |
| 4808 xor_(overflow_dst, dst, left); |
| 4809 xor_(scratch, dst, right); |
| 4810 and_(overflow_dst, scratch, overflow_dst); |
| 4811 } |
| 4812 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 4813 } |
| 4814 |
| 4815 |
4733 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, | 4816 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, |
4734 const Operand& right, | 4817 const Operand& right, |
4735 Register overflow_dst, | 4818 Register overflow_dst, |
4736 Register scratch) { | 4819 Register scratch) { |
4737 if (right.is_reg()) { | 4820 if (right.is_reg()) { |
4738 SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | 4821 SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); |
4739 } else { | 4822 } else { |
4740 if (dst.is(left)) { | 4823 if (dst.is(left)) { |
4741 li(t9, right); // Load right. | 4824 li(t9, right); // Load right. |
4742 mov(scratch, left); // Preserve left. | 4825 mov(scratch, left); // Preserve left. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4854 xor_(scratch, left, scratch); // Original right. | 4937 xor_(scratch, left, scratch); // Original right. |
4855 and_(overflow_dst, scratch, overflow_dst); | 4938 and_(overflow_dst, scratch, overflow_dst); |
4856 } else { | 4939 } else { |
4857 dsubu(dst, left, right); | 4940 dsubu(dst, left, right); |
4858 xor_(overflow_dst, dst, left); | 4941 xor_(overflow_dst, dst, left); |
4859 xor_(scratch, left, right); | 4942 xor_(scratch, left, right); |
4860 and_(overflow_dst, scratch, overflow_dst); | 4943 and_(overflow_dst, scratch, overflow_dst); |
4861 } | 4944 } |
4862 } | 4945 } |
4863 | 4946 |
| 4947 |
| 4948 void MacroAssembler::DsubBranchOvf(Register dst, Register left, |
| 4949 const Operand& right, Label* overflow_label, |
| 4950 Label* no_overflow_label, Register scratch) { |
| 4951 DCHECK(overflow_label || no_overflow_label); |
| 4952 if (right.is_reg()) { |
| 4953 DsubBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 4954 scratch); |
| 4955 } else { |
| 4956 Register overflow_dst = t9; |
| 4957 DCHECK(!dst.is(scratch)); |
| 4958 DCHECK(!dst.is(overflow_dst)); |
| 4959 DCHECK(!scratch.is(overflow_dst)); |
| 4960 DCHECK(!left.is(overflow_dst)); |
| 4961 DCHECK(!left.is(scratch)); |
| 4962 li(overflow_dst, right); // Load right. |
| 4963 if (dst.is(left)) { |
| 4964 mov(scratch, left); // Preserve left. |
| 4965 Dsubu(dst, left, overflow_dst); // Left is overwritten. |
| 4966 xor_(overflow_dst, scratch, overflow_dst); // scratch is original left. |
| 4967 xor_(scratch, dst, scratch); // scratch is original left. |
| 4968 and_(overflow_dst, scratch, overflow_dst); |
| 4969 } else { |
| 4970 Dsubu(dst, left, overflow_dst); |
| 4971 xor_(scratch, left, overflow_dst); |
| 4972 xor_(overflow_dst, dst, left); |
| 4973 and_(overflow_dst, scratch, overflow_dst); |
| 4974 } |
| 4975 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 4976 } |
| 4977 } |
| 4978 |
| 4979 |
| 4980 void MacroAssembler::DsubBranchOvf(Register dst, Register left, Register right, |
| 4981 Label* overflow_label, |
| 4982 Label* no_overflow_label, Register scratch) { |
| 4983 DCHECK(overflow_label || no_overflow_label); |
| 4984 Register overflow_dst = t9; |
| 4985 DCHECK(!dst.is(scratch)); |
| 4986 DCHECK(!dst.is(overflow_dst)); |
| 4987 DCHECK(!scratch.is(overflow_dst)); |
| 4988 DCHECK(!overflow_dst.is(left)); |
| 4989 DCHECK(!overflow_dst.is(right)); |
| 4990 DCHECK(!scratch.is(left)); |
| 4991 DCHECK(!scratch.is(right)); |
| 4992 |
| 4993 // This happens with some crankshaft code. Since Subu works fine if |
| 4994 // left == right, let's not make that restriction here. |
| 4995 if (left.is(right)) { |
| 4996 mov(dst, zero_reg); |
| 4997 if (no_overflow_label) { |
| 4998 Branch(no_overflow_label); |
| 4999 } |
| 5000 } |
| 5001 |
| 5002 if (dst.is(left)) { |
| 5003 mov(scratch, left); // Preserve left. |
| 5004 dsubu(dst, left, right); // Left is overwritten. |
| 5005 xor_(overflow_dst, dst, scratch); // scratch is original left. |
| 5006 xor_(scratch, scratch, right); // scratch is original left. |
| 5007 and_(overflow_dst, scratch, overflow_dst); |
| 5008 } else if (dst.is(right)) { |
| 5009 mov(scratch, right); // Preserve right. |
| 5010 dsubu(dst, left, right); // Right is overwritten. |
| 5011 xor_(overflow_dst, dst, left); |
| 5012 xor_(scratch, left, scratch); // Original right. |
| 5013 and_(overflow_dst, scratch, overflow_dst); |
| 5014 } else { |
| 5015 dsubu(dst, left, right); |
| 5016 xor_(overflow_dst, dst, left); |
| 5017 xor_(scratch, left, right); |
| 5018 and_(overflow_dst, scratch, overflow_dst); |
| 5019 } |
| 5020 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 5021 } |
| 5022 |
| 5023 |
4864 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, | 5024 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, |
4865 SaveFPRegsMode save_doubles, | 5025 SaveFPRegsMode save_doubles, |
4866 BranchDelaySlot bd) { | 5026 BranchDelaySlot bd) { |
4867 // All parameters are on the stack. v0 has the return value after call. | 5027 // All parameters are on the stack. v0 has the return value after call. |
4868 | 5028 |
4869 // If the expected number of arguments of the runtime function is | 5029 // If the expected number of arguments of the runtime function is |
4870 // constant, we check that the actual number of arguments match the | 5030 // constant, we check that the actual number of arguments match the |
4871 // expectation. | 5031 // expectation. |
4872 CHECK(f->nargs < 0 || f->nargs == num_arguments); | 5032 CHECK(f->nargs < 0 || f->nargs == num_arguments); |
4873 | 5033 |
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6208 if (mag.shift > 0) sra(result, result, mag.shift); | 6368 if (mag.shift > 0) sra(result, result, mag.shift); |
6209 srl(at, dividend, 31); | 6369 srl(at, dividend, 31); |
6210 Addu(result, result, Operand(at)); | 6370 Addu(result, result, Operand(at)); |
6211 } | 6371 } |
6212 | 6372 |
6213 | 6373 |
6214 } // namespace internal | 6374 } // namespace internal |
6215 } // namespace v8 | 6375 } // namespace v8 |
6216 | 6376 |
6217 #endif // V8_TARGET_ARCH_MIPS64 | 6377 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |