OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 3686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3697 const intptr_t kNumInputs = 1; | 3697 const intptr_t kNumInputs = 1; |
3698 const intptr_t kNumTemps = 0; | 3698 const intptr_t kNumTemps = 0; |
3699 LocationSummary* summary = new(zone) LocationSummary( | 3699 LocationSummary* summary = new(zone) LocationSummary( |
3700 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3700 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3701 summary->set_in(0, Location::RequiresFpuRegister()); | 3701 summary->set_in(0, Location::RequiresFpuRegister()); |
3702 summary->set_out(0, Location::RequiresRegister()); | 3702 summary->set_out(0, Location::RequiresRegister()); |
3703 return summary; | 3703 return summary; |
3704 } | 3704 } |
3705 | 3705 |
3706 | 3706 |
| 3707 Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 3708 BranchLabels labels) { |
| 3709 const DRegister value = locs()->in(0).fpu_reg(); |
| 3710 const bool is_negated = kind() != Token::kEQ; |
| 3711 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) { |
| 3712 __ cund(value, value); |
| 3713 if (labels.fall_through == labels.true_label) { |
| 3714 if (is_negated) { |
| 3715 __ bc1t(labels.false_label); |
| 3716 } else { |
| 3717 __ bc1f(labels.false_label); |
| 3718 } |
| 3719 } else if (labels.fall_through == labels.false_label) { |
| 3720 if (is_negated) { |
| 3721 __ bc1f(labels.true_label); |
| 3722 } else { |
| 3723 __ bc1t(labels.true_label); |
| 3724 } |
| 3725 } else { |
| 3726 if (is_negated) { |
| 3727 __ bc1t(labels.false_label); |
| 3728 } else { |
| 3729 __ bc1f(labels.false_label); |
| 3730 } |
| 3731 __ b(labels.true_label); |
| 3732 } |
| 3733 return Condition(); // Unused. |
| 3734 } else { |
| 3735 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite); |
| 3736 __ mfc1(CMPRES1, EvenFRegisterOf(value)); |
| 3737 // If the low word isn't zero, then it isn't infinity. |
| 3738 __ bne(CMPRES1, ZR, is_negated ? labels.true_label : labels.false_label); |
| 3739 __ mfc1(CMPRES1, OddFRegisterOf(value)); |
| 3740 // Mask off the sign bit. |
| 3741 __ AndImmediate(CMPRES1, CMPRES1, 0x7FFFFFFF); |
| 3742 // Compare with +infinity. |
| 3743 __ LoadImmediate(CMPRES2, 0x7FF00000); |
| 3744 return Condition(CMPRES1, CMPRES2, is_negated ? NE : EQ); |
| 3745 } |
| 3746 } |
| 3747 |
| 3748 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3749 BranchInstr* branch) { |
| 3750 ASSERT(compiler->is_optimizing()); |
| 3751 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3752 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3753 // Branches for isNaN are emitted in EmitComparisonCode already. |
| 3754 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { |
| 3755 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3756 } |
| 3757 } |
| 3758 |
| 3759 |
3707 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3760 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3708 ASSERT(compiler->is_optimizing()); | 3761 Label is_true, is_false; |
3709 const DRegister value = locs()->in(0).fpu_reg(); | 3762 BranchLabels labels = { &is_true, &is_false, &is_false }; |
| 3763 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3764 // Branches for isNaN are emitted in EmitComparisonCode already. |
| 3765 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { |
| 3766 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3767 } |
3710 const Register result = locs()->out(0).reg(); | 3768 const Register result = locs()->out(0).reg(); |
3711 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) { | 3769 Label done; |
3712 Label is_not_nan; | 3770 __ Comment("return bool"); |
3713 __ LoadObject(result, Bool::False()); | 3771 __ Bind(&is_false); |
3714 __ cund(value, value); | 3772 __ LoadObject(result, Bool::False()); |
3715 __ bc1f(&is_not_nan); | 3773 __ b(&done); |
3716 __ LoadObject(result, Bool::True()); | 3774 __ Bind(&is_true); |
3717 __ Bind(&is_not_nan); | 3775 __ LoadObject(result, Bool::True()); |
3718 } else { | 3776 __ Bind(&done); |
3719 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite); | |
3720 Label not_inf, done; | |
3721 __ mfc1(TMP, EvenFRegisterOf(value)); | |
3722 __ mfc1(result, OddFRegisterOf(value)); | |
3723 // If the low word isn't zero, then it isn't infinity. | |
3724 __ bne(TMP, ZR, ¬_inf); | |
3725 // Mask off the sign bit. | |
3726 __ AndImmediate(result, result, 0x7FFFFFFF); | |
3727 // Compare with +infinity. | |
3728 __ BranchNotEqual(result, Immediate(0x7FF00000), ¬_inf); | |
3729 | |
3730 __ LoadObject(result, Bool::True()); | |
3731 __ b(&done); | |
3732 | |
3733 __ Bind(¬_inf); | |
3734 __ LoadObject(result, Bool::False()); | |
3735 __ Bind(&done); | |
3736 } | |
3737 } | 3777 } |
3738 | 3778 |
3739 | 3779 |
3740 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, | 3780 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, |
3741 bool opt) const { | 3781 bool opt) const { |
3742 UNIMPLEMENTED(); | 3782 UNIMPLEMENTED(); |
3743 return NULL; | 3783 return NULL; |
3744 } | 3784 } |
3745 | 3785 |
3746 | 3786 |
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5832 1, | 5872 1, |
5833 locs()); | 5873 locs()); |
5834 __ lw(result, Address(SP, 1 * kWordSize)); | 5874 __ lw(result, Address(SP, 1 * kWordSize)); |
5835 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 5875 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
5836 } | 5876 } |
5837 | 5877 |
5838 | 5878 |
5839 } // namespace dart | 5879 } // namespace dart |
5840 | 5880 |
5841 #endif // defined TARGET_ARCH_MIPS | 5881 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |