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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 case EQUAL: return NOT_EQUAL; | 114 case EQUAL: return NOT_EQUAL; |
115 case NOT_EQUAL: return EQUAL; | 115 case NOT_EQUAL: return EQUAL; |
116 case LESS: return GREATER_EQUAL; | 116 case LESS: return GREATER_EQUAL; |
117 case LESS_EQUAL: return GREATER; | 117 case LESS_EQUAL: return GREATER; |
118 case GREATER: return LESS_EQUAL; | 118 case GREATER: return LESS_EQUAL; |
119 case GREATER_EQUAL: return LESS; | 119 case GREATER_EQUAL: return LESS; |
120 case BELOW: return ABOVE_EQUAL; | 120 case BELOW: return ABOVE_EQUAL; |
121 case BELOW_EQUAL: return ABOVE; | 121 case BELOW_EQUAL: return ABOVE; |
122 case ABOVE: return BELOW_EQUAL; | 122 case ABOVE: return BELOW_EQUAL; |
123 case ABOVE_EQUAL: return BELOW; | 123 case ABOVE_EQUAL: return BELOW; |
| 124 case PARITY_EVEN: return PARITY_ODD; |
| 125 case PARITY_ODD: return PARITY_EVEN; |
124 default: | 126 default: |
125 UNIMPLEMENTED(); | 127 UNIMPLEMENTED(); |
126 return EQUAL; | 128 return EQUAL; |
127 } | 129 } |
128 } | 130 } |
129 | 131 |
130 | 132 |
131 // Detect pattern when one value is zero and another is a power of 2. | 133 // Detect pattern when one value is zero and another is a power of 2. |
132 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 134 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
133 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 135 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
(...skipping 3622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3756 case Token::kMUL: __ mulsd(left, right); break; | 3758 case Token::kMUL: __ mulsd(left, right); break; |
3757 case Token::kDIV: __ divsd(left, right); break; | 3759 case Token::kDIV: __ divsd(left, right); break; |
3758 default: UNREACHABLE(); | 3760 default: UNREACHABLE(); |
3759 } | 3761 } |
3760 } | 3762 } |
3761 | 3763 |
3762 | 3764 |
3763 LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone, | 3765 LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone, |
3764 bool opt) const { | 3766 bool opt) const { |
3765 const intptr_t kNumInputs = 1; | 3767 const intptr_t kNumInputs = 1; |
3766 const intptr_t kNumTemps = 0; | 3768 const intptr_t kNumTemps = |
| 3769 (op_kind() == MethodRecognizer::kDouble_getIsInfinite) ? 1 : 0; |
3767 LocationSummary* summary = new(zone) LocationSummary( | 3770 LocationSummary* summary = new(zone) LocationSummary( |
3768 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3771 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3769 summary->set_in(0, Location::RequiresFpuRegister()); | 3772 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3773 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { |
| 3774 summary->set_temp(0, Location::RequiresRegister()); |
| 3775 } |
3770 summary->set_out(0, Location::RequiresRegister()); | 3776 summary->set_out(0, Location::RequiresRegister()); |
3771 return summary; | 3777 return summary; |
3772 } | 3778 } |
3773 | 3779 |
3774 | 3780 |
3775 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3781 Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 3782 BranchLabels labels) { |
3776 ASSERT(compiler->is_optimizing()); | 3783 ASSERT(compiler->is_optimizing()); |
3777 const XmmRegister value = locs()->in(0).fpu_reg(); | 3784 const XmmRegister value = locs()->in(0).fpu_reg(); |
3778 const Register result = locs()->out(0).reg(); | 3785 const bool is_negated = kind() != Token::kEQ; |
3779 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) { | 3786 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) { |
3780 Label is_nan; | 3787 Label is_nan; |
3781 __ LoadObject(result, Bool::True()); | |
3782 __ comisd(value, value); | 3788 __ comisd(value, value); |
3783 __ j(PARITY_EVEN, &is_nan, Assembler::kNearJump); | 3789 return is_negated ? PARITY_ODD : PARITY_EVEN; |
3784 __ LoadObject(result, Bool::False()); | |
3785 __ Bind(&is_nan); | |
3786 } else { | 3790 } else { |
3787 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite); | 3791 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite); |
3788 Label is_inf, done; | 3792 const Register temp = locs()->temp(0).reg(); |
3789 __ AddImmediate(RSP, Immediate(-kDoubleSize)); | 3793 __ AddImmediate(RSP, Immediate(-kDoubleSize)); |
3790 __ movsd(Address(RSP, 0), value); | 3794 __ movsd(Address(RSP, 0), value); |
3791 __ movq(result, Address(RSP, 0)); | 3795 __ movq(temp, Address(RSP, 0)); |
| 3796 __ AddImmediate(RSP, Immediate(kDoubleSize)); |
3792 // Mask off the sign. | 3797 // Mask off the sign. |
3793 __ AndImmediate(result, Immediate(0x7FFFFFFFFFFFFFFFLL)); | 3798 __ AndImmediate(temp, Immediate(0x7FFFFFFFFFFFFFFFLL)); |
3794 // Compare with +infinity. | 3799 // Compare with +infinity. |
3795 __ CompareImmediate(result, Immediate(0x7FF0000000000000LL)); | 3800 __ CompareImmediate(temp, Immediate(0x7FF0000000000000LL)); |
3796 __ j(EQUAL, &is_inf, Assembler::kNearJump); | 3801 return is_negated ? NOT_EQUAL : EQUAL; |
3797 __ LoadObject(result, Bool::False()); | |
3798 __ jmp(&done); | |
3799 | |
3800 __ Bind(&is_inf); | |
3801 __ LoadObject(result, Bool::True()); | |
3802 | |
3803 __ Bind(&done); | |
3804 __ AddImmediate(RSP, Immediate(kDoubleSize)); | |
3805 } | 3802 } |
3806 } | 3803 } |
3807 | 3804 |
3808 | 3805 |
| 3806 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3807 BranchInstr* branch) { |
| 3808 ASSERT(compiler->is_optimizing()); |
| 3809 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3810 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3811 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3812 } |
| 3813 |
| 3814 |
| 3815 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3816 Label is_true, is_false; |
| 3817 BranchLabels labels = { &is_true, &is_false, &is_false }; |
| 3818 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3819 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3820 |
| 3821 Register result = locs()->out(0).reg(); |
| 3822 Label done; |
| 3823 __ Bind(&is_false); |
| 3824 __ LoadObject(result, Bool::False()); |
| 3825 __ jmp(&done); |
| 3826 __ Bind(&is_true); |
| 3827 __ LoadObject(result, Bool::True()); |
| 3828 __ Bind(&done); |
| 3829 } |
| 3830 |
| 3831 |
3809 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, | 3832 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, |
3810 bool opt) const { | 3833 bool opt) const { |
3811 const intptr_t kNumInputs = 2; | 3834 const intptr_t kNumInputs = 2; |
3812 const intptr_t kNumTemps = 0; | 3835 const intptr_t kNumTemps = 0; |
3813 LocationSummary* summary = new(zone) LocationSummary( | 3836 LocationSummary* summary = new(zone) LocationSummary( |
3814 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3837 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3815 summary->set_in(0, Location::RequiresFpuRegister()); | 3838 summary->set_in(0, Location::RequiresFpuRegister()); |
3816 summary->set_in(1, Location::RequiresFpuRegister()); | 3839 summary->set_in(1, Location::RequiresFpuRegister()); |
3817 summary->set_out(0, Location::SameAsFirstInput()); | 3840 summary->set_out(0, Location::SameAsFirstInput()); |
3818 return summary; | 3841 return summary; |
(...skipping 2864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6683 __ Drop(1); | 6706 __ Drop(1); |
6684 __ popq(result); | 6707 __ popq(result); |
6685 } | 6708 } |
6686 | 6709 |
6687 | 6710 |
6688 } // namespace dart | 6711 } // namespace dart |
6689 | 6712 |
6690 #undef __ | 6713 #undef __ |
6691 | 6714 |
6692 #endif // defined TARGET_ARCH_X64 | 6715 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |