| 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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 intptr_t temp = true_value; | 171 intptr_t temp = true_value; |
| 172 true_value = false_value; | 172 true_value = false_value; |
| 173 false_value = temp; | 173 false_value = temp; |
| 174 swapped = true; | 174 swapped = true; |
| 175 } | 175 } |
| 176 | 176 |
| 177 // Initialize result with the true value. | 177 // Initialize result with the true value. |
| 178 __ LoadImmediate(result, Smi::RawValue(true_value)); | 178 __ LoadImmediate(result, Smi::RawValue(true_value)); |
| 179 | 179 |
| 180 // Emit comparison code. This must not overwrite the result register. | 180 // Emit comparison code. This must not overwrite the result register. |
| 181 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using |
| 182 // the labels or returning an invalid condition. |
| 181 BranchLabels labels = {NULL, NULL, NULL}; // Emit branch-free code. | 183 BranchLabels labels = {NULL, NULL, NULL}; // Emit branch-free code. |
| 182 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); | 184 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); |
| 185 ASSERT(true_condition != kInvalidCondition); |
| 183 if (swapped) { | 186 if (swapped) { |
| 184 true_condition = NegateCondition(true_condition); | 187 true_condition = NegateCondition(true_condition); |
| 185 } | 188 } |
| 186 | 189 |
| 187 // Evaluate condition and provide result in CMPRES1. | 190 // Evaluate condition and provide result in CMPRES1. |
| 188 Register left = true_condition.left(); | 191 Register left = true_condition.left(); |
| 189 Register right = true_condition.right(); | 192 Register right = true_condition.right(); |
| 190 bool zero_is_false = true; // Zero in CMPRES1 indicates a false condition. | 193 bool zero_is_false = true; // Zero in CMPRES1 indicates a false condition. |
| 191 switch (true_condition.rel_op()) { | 194 switch (true_condition.rel_op()) { |
| 192 case AL: | 195 case AL: |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 return EmitSmiComparisonOp(compiler, *locs(), kind()); | 777 return EmitSmiComparisonOp(compiler, *locs(), kind()); |
| 775 } else if (operation_cid() == kMintCid) { | 778 } else if (operation_cid() == kMintCid) { |
| 776 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels); | 779 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels); |
| 777 } else { | 780 } else { |
| 778 ASSERT(operation_cid() == kDoubleCid); | 781 ASSERT(operation_cid() == kDoubleCid); |
| 779 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); | 782 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); |
| 780 } | 783 } |
| 781 } | 784 } |
| 782 | 785 |
| 783 | 786 |
| 784 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 787 // IA32 compiler needs this to link (for the simmips config). |
| 785 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 788 template <> |
| 786 __ Comment("EqualityCompareInstr"); | 789 void TemplateComparison<2, Throws, NoCSE>::EmitNativeCode( |
| 790 FlowGraphCompiler* compiler) { |
| 791 UNREACHABLE(); |
| 792 } |
| 787 | 793 |
| 794 |
| 795 template <intptr_t N, |
| 796 typename ThrowsTrait, |
| 797 template <typename Impure, typename Pure> class CSETrait> |
| 798 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitNativeCode( |
| 799 FlowGraphCompiler* compiler) { |
| 788 Label is_true, is_false; | 800 Label is_true, is_false; |
| 789 BranchLabels labels = {&is_true, &is_false, &is_false}; | 801 BranchLabels labels = {&is_true, &is_false, &is_false}; |
| 790 Condition true_condition = EmitComparisonCode(compiler, labels); | 802 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 791 EmitBranchOnCondition(compiler, true_condition, labels); | 803 if (true_condition.IsValid()) { |
| 804 EmitBranchOnCondition(compiler, true_condition, labels); |
| 805 } |
| 792 | 806 |
| 793 Register result = locs()->out(0).reg(); | 807 Register result = this->locs()->out(0).reg(); |
| 794 Label done; | 808 Label done; |
| 795 __ Bind(&is_false); | 809 __ Bind(&is_false); |
| 796 __ LoadObject(result, Bool::False()); | 810 __ LoadObject(result, Bool::False()); |
| 797 __ b(&done); | 811 __ b(&done); |
| 798 __ Bind(&is_true); | 812 __ Bind(&is_true); |
| 799 __ LoadObject(result, Bool::True()); | 813 __ LoadObject(result, Bool::True()); |
| 800 __ Bind(&done); | 814 __ Bind(&done); |
| 801 } | 815 } |
| 802 | 816 |
| 803 | 817 |
| 804 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 818 template <intptr_t N, |
| 805 BranchInstr* branch) { | 819 typename ThrowsTrait, |
| 806 __ Comment("EqualityCompareInstr::EmitBranchCode"); | 820 template <typename Impure, typename Pure> class CSETrait> |
| 807 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 821 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitBranchCode( |
| 808 | 822 FlowGraphCompiler* compiler, |
| 823 BranchInstr* branch) { |
| 809 BranchLabels labels = compiler->CreateBranchLabels(branch); | 824 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 810 Condition true_condition = EmitComparisonCode(compiler, labels); | 825 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 811 EmitBranchOnCondition(compiler, true_condition, labels); | 826 if (true_condition.IsValid()) { |
| 827 EmitBranchOnCondition(compiler, true_condition, labels); |
| 828 } |
| 812 } | 829 } |
| 813 | 830 |
| 814 | 831 |
| 832 // IA32 compiler needs this to link (for the simmips config). |
| 833 template <> |
| 834 void TemplateComparison<2, Throws, NoCSE>::EmitBranchCode( |
| 835 FlowGraphCompiler* compiler, |
| 836 BranchInstr* branch) { |
| 837 UNREACHABLE(); |
| 838 } |
| 839 |
| 840 |
| 841 // Explicit template instantiations. |
| 842 template void TemplateComparison<1, NoThrow, Pure>::EmitNativeCode( |
| 843 FlowGraphCompiler*); |
| 844 template void TemplateComparison<2, NoThrow, Pure>::EmitNativeCode( |
| 845 FlowGraphCompiler*); |
| 846 template void TemplateComparison<1, NoThrow, Pure>::EmitBranchCode( |
| 847 FlowGraphCompiler* compiler, |
| 848 BranchInstr* branch); |
| 849 template void TemplateComparison<2, NoThrow, Pure>::EmitBranchCode( |
| 850 FlowGraphCompiler* compiler, |
| 851 BranchInstr* branch); |
| 852 |
| 853 |
| 815 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { | 854 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { |
| 816 const intptr_t kNumInputs = 2; | 855 const intptr_t kNumInputs = 2; |
| 817 const intptr_t kNumTemps = 0; | 856 const intptr_t kNumTemps = 0; |
| 818 LocationSummary* locs = new (zone) | 857 LocationSummary* locs = new (zone) |
| 819 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 858 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 820 locs->set_in(0, Location::RequiresRegister()); | 859 locs->set_in(0, Location::RequiresRegister()); |
| 821 // Only one input can be a constant operand. The case of two constant | 860 // Only one input can be a constant operand. The case of two constant |
| 822 // operands should be handled by constant propagation. | 861 // operands should be handled by constant propagation. |
| 823 locs->set_in(1, Location::RegisterOrConstant(right())); | 862 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 824 return locs; | 863 return locs; |
| 825 } | 864 } |
| 826 | 865 |
| 827 | 866 |
| 828 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 867 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 829 BranchLabels labels) { | 868 BranchLabels labels) { |
| 830 Register left = locs()->in(0).reg(); | 869 Register left = locs()->in(0).reg(); |
| 831 Location right = locs()->in(1); | 870 Location right = locs()->in(1); |
| 832 if (right.IsConstant()) { | 871 if (right.IsConstant()) { |
| 833 ASSERT(right.constant().IsSmi()); | 872 ASSERT(right.constant().IsSmi()); |
| 834 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); | 873 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); |
| 835 __ AndImmediate(CMPRES1, left, imm); | 874 __ AndImmediate(CMPRES1, left, imm); |
| 836 } else { | 875 } else { |
| 837 __ and_(CMPRES1, left, right.reg()); | 876 __ and_(CMPRES1, left, right.reg()); |
| 838 } | 877 } |
| 839 return Condition(CMPRES1, ZR, (kind() == Token::kNE) ? NE : EQ); | 878 return Condition(CMPRES1, ZR, (kind() == Token::kNE) ? NE : EQ); |
| 840 } | 879 } |
| 841 | 880 |
| 842 | 881 |
| 843 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 844 // Never emitted outside of the BranchInstr. | |
| 845 UNREACHABLE(); | |
| 846 } | |
| 847 | |
| 848 | |
| 849 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 850 BranchInstr* branch) { | |
| 851 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 852 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 853 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 854 } | |
| 855 | |
| 856 | |
| 857 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, | 882 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, |
| 858 bool opt) const { | 883 bool opt) const { |
| 859 const intptr_t kNumInputs = 1; | 884 const intptr_t kNumInputs = 1; |
| 860 const intptr_t kNumTemps = 1; | 885 const intptr_t kNumTemps = 1; |
| 861 LocationSummary* locs = new (zone) | 886 LocationSummary* locs = new (zone) |
| 862 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 887 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 863 locs->set_in(0, Location::RequiresRegister()); | 888 locs->set_in(0, Location::RequiresRegister()); |
| 864 locs->set_temp(0, Location::RequiresRegister()); | 889 locs->set_temp(0, Location::RequiresRegister()); |
| 865 locs->set_out(0, Location::RequiresRegister()); | 890 locs->set_out(0, Location::RequiresRegister()); |
| 866 return locs; | 891 return locs; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 // If the cid is not in the list, jump to the opposite label from the cids | 924 // If the cid is not in the list, jump to the opposite label from the cids |
| 900 // that are in the list. These must be all the same (see asserts in the | 925 // that are in the list. These must be all the same (see asserts in the |
| 901 // constructor). | 926 // constructor). |
| 902 Label* target = result ? labels.false_label : labels.true_label; | 927 Label* target = result ? labels.false_label : labels.true_label; |
| 903 if (target != labels.fall_through) { | 928 if (target != labels.fall_through) { |
| 904 __ b(target); | 929 __ b(target); |
| 905 } | 930 } |
| 906 } else { | 931 } else { |
| 907 __ b(deopt); | 932 __ b(deopt); |
| 908 } | 933 } |
| 909 // Dummy result as the last instruction is a jump or fall through. | 934 // Dummy result as this method already did the jump, there's no need |
| 910 return Condition(CMPRES1, ZR, AL); | 935 // for the caller to branch on a condition. |
| 936 return Condition(ZR, ZR, INVALID_RELATION); |
| 911 } | 937 } |
| 912 | 938 |
| 913 | 939 |
| 914 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 915 BranchInstr* branch) { | |
| 916 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 917 EmitComparisonCode(compiler, labels); | |
| 918 } | |
| 919 | |
| 920 | |
| 921 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 922 Register result_reg = locs()->out(0).reg(); | |
| 923 Label is_true, is_false, done; | |
| 924 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 925 EmitComparisonCode(compiler, labels); | |
| 926 __ Bind(&is_false); | |
| 927 __ LoadObject(result_reg, Bool::False()); | |
| 928 __ b(&done); | |
| 929 __ Bind(&is_true); | |
| 930 __ LoadObject(result_reg, Bool::True()); | |
| 931 __ Bind(&done); | |
| 932 } | |
| 933 | |
| 934 | |
| 935 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, | 940 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, |
| 936 bool opt) const { | 941 bool opt) const { |
| 937 const intptr_t kNumInputs = 2; | 942 const intptr_t kNumInputs = 2; |
| 938 const intptr_t kNumTemps = 0; | 943 const intptr_t kNumTemps = 0; |
| 939 if (operation_cid() == kMintCid) { | 944 if (operation_cid() == kMintCid) { |
| 940 const intptr_t kNumTemps = 0; | 945 const intptr_t kNumTemps = 0; |
| 941 LocationSummary* locs = new (zone) | 946 LocationSummary* locs = new (zone) |
| 942 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 947 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 943 locs->set_in(0, Location::Pair(Location::RequiresRegister(), | 948 locs->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 944 Location::RequiresRegister())); | 949 Location::RequiresRegister())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 975 return EmitSmiComparisonOp(compiler, *locs(), kind()); | 980 return EmitSmiComparisonOp(compiler, *locs(), kind()); |
| 976 } else if (operation_cid() == kMintCid) { | 981 } else if (operation_cid() == kMintCid) { |
| 977 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); | 982 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); |
| 978 } else { | 983 } else { |
| 979 ASSERT(operation_cid() == kDoubleCid); | 984 ASSERT(operation_cid() == kDoubleCid); |
| 980 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); | 985 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); |
| 981 } | 986 } |
| 982 } | 987 } |
| 983 | 988 |
| 984 | 989 |
| 985 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 986 __ Comment("RelationalOpInstr"); | |
| 987 | |
| 988 Label is_true, is_false; | |
| 989 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 990 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 991 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 992 | |
| 993 Register result = locs()->out(0).reg(); | |
| 994 Label done; | |
| 995 __ Bind(&is_false); | |
| 996 __ LoadObject(result, Bool::False()); | |
| 997 __ b(&done); | |
| 998 __ Bind(&is_true); | |
| 999 __ LoadObject(result, Bool::True()); | |
| 1000 __ Bind(&done); | |
| 1001 } | |
| 1002 | |
| 1003 | |
| 1004 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 1005 BranchInstr* branch) { | |
| 1006 __ Comment("RelationalOpInstr"); | |
| 1007 | |
| 1008 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 1009 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 1010 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 1011 } | |
| 1012 | |
| 1013 | |
| 1014 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, | 990 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, |
| 1015 bool opt) const { | 991 bool opt) const { |
| 1016 return MakeCallSummary(zone); | 992 return MakeCallSummary(zone); |
| 1017 } | 993 } |
| 1018 | 994 |
| 1019 | 995 |
| 1020 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 996 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1021 SetupNative(); | 997 SetupNative(); |
| 1022 __ Comment("NativeCallInstr"); | 998 __ Comment("NativeCallInstr"); |
| 1023 Register result = locs()->out(0).reg(); | 999 Register result = locs()->out(0).reg(); |
| (...skipping 2216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3240 | 3216 |
| 3241 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 3217 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3242 BranchInstr* branch) { | 3218 BranchInstr* branch) { |
| 3243 BranchLabels labels = compiler->CreateBranchLabels(branch); | 3219 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3244 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( | 3220 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( |
| 3245 this, compiler->CurrentTryIndex(), labels, | 3221 this, compiler->CurrentTryIndex(), labels, |
| 3246 /* merged = */ true); | 3222 /* merged = */ true); |
| 3247 compiler->AddSlowPathCode(slow_path); | 3223 compiler->AddSlowPathCode(slow_path); |
| 3248 EMIT_SMI_CHECK; | 3224 EMIT_SMI_CHECK; |
| 3249 Condition true_condition = EmitComparisonCode(compiler, labels); | 3225 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3226 ASSERT(true_condition != kInvalidCondition); |
| 3250 EmitBranchOnCondition(compiler, true_condition, labels); | 3227 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3251 __ Bind(slow_path->exit_label()); | 3228 __ Bind(slow_path->exit_label()); |
| 3252 } | 3229 } |
| 3253 | 3230 |
| 3254 | 3231 |
| 3255 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3232 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3256 Label true_label, false_label, done; | 3233 Label true_label, false_label, done; |
| 3257 BranchLabels labels = {&true_label, &false_label, &false_label}; | 3234 BranchLabels labels = {&true_label, &false_label, &false_label}; |
| 3258 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( | 3235 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( |
| 3259 this, compiler->CurrentTryIndex(), labels, | 3236 this, compiler->CurrentTryIndex(), labels, |
| 3260 /* merged = */ false); | 3237 /* merged = */ false); |
| 3261 compiler->AddSlowPathCode(slow_path); | 3238 compiler->AddSlowPathCode(slow_path); |
| 3262 EMIT_SMI_CHECK; | 3239 EMIT_SMI_CHECK; |
| 3263 Condition true_condition = EmitComparisonCode(compiler, labels); | 3240 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3241 ASSERT(true_condition != kInvalidCondition); |
| 3264 EmitBranchOnCondition(compiler, true_condition, labels); | 3242 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3265 Register result = locs()->out(0).reg(); | 3243 Register result = locs()->out(0).reg(); |
| 3266 __ Bind(&false_label); | 3244 __ Bind(&false_label); |
| 3267 __ LoadObject(result, Bool::False()); | 3245 __ LoadObject(result, Bool::False()); |
| 3268 __ b(&done); | 3246 __ b(&done); |
| 3269 __ Bind(&true_label); | 3247 __ Bind(&true_label); |
| 3270 __ LoadObject(result, Bool::True()); | 3248 __ LoadObject(result, Bool::True()); |
| 3271 __ Bind(&done); | 3249 __ Bind(&done); |
| 3272 __ Bind(slow_path->exit_label()); | 3250 __ Bind(slow_path->exit_label()); |
| 3273 } | 3251 } |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3968 __ bc1t(labels.true_label); | 3946 __ bc1t(labels.true_label); |
| 3969 } | 3947 } |
| 3970 } else { | 3948 } else { |
| 3971 if (is_negated) { | 3949 if (is_negated) { |
| 3972 __ bc1t(labels.false_label); | 3950 __ bc1t(labels.false_label); |
| 3973 } else { | 3951 } else { |
| 3974 __ bc1f(labels.false_label); | 3952 __ bc1f(labels.false_label); |
| 3975 } | 3953 } |
| 3976 __ b(labels.true_label); | 3954 __ b(labels.true_label); |
| 3977 } | 3955 } |
| 3978 return Condition(); // Unused. | 3956 return Condition(ZR, ZR, INVALID_RELATION); // Unused. |
| 3979 } else { | 3957 } else { |
| 3980 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite); | 3958 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite); |
| 3981 __ mfc1(CMPRES1, EvenFRegisterOf(value)); | 3959 __ mfc1(CMPRES1, EvenFRegisterOf(value)); |
| 3982 // If the low word isn't zero, then it isn't infinity. | 3960 // If the low word isn't zero, then it isn't infinity. |
| 3983 __ bne(CMPRES1, ZR, is_negated ? labels.true_label : labels.false_label); | 3961 __ bne(CMPRES1, ZR, is_negated ? labels.true_label : labels.false_label); |
| 3984 __ mfc1(CMPRES1, OddFRegisterOf(value)); | 3962 __ mfc1(CMPRES1, OddFRegisterOf(value)); |
| 3985 // Mask off the sign bit. | 3963 // Mask off the sign bit. |
| 3986 __ AndImmediate(CMPRES1, CMPRES1, 0x7FFFFFFF); | 3964 __ AndImmediate(CMPRES1, CMPRES1, 0x7FFFFFFF); |
| 3987 // Compare with +infinity. | 3965 // Compare with +infinity. |
| 3988 __ LoadImmediate(CMPRES2, 0x7FF00000); | 3966 __ LoadImmediate(CMPRES2, 0x7FF00000); |
| 3989 return Condition(CMPRES1, CMPRES2, is_negated ? NE : EQ); | 3967 return Condition(CMPRES1, CMPRES2, is_negated ? NE : EQ); |
| 3990 } | 3968 } |
| 3991 } | 3969 } |
| 3992 | 3970 |
| 3993 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 3994 BranchInstr* branch) { | |
| 3995 ASSERT(compiler->is_optimizing()); | |
| 3996 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 3997 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 3998 // Branches for isNaN are emitted in EmitComparisonCode already. | |
| 3999 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { | |
| 4000 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 4001 } | |
| 4002 } | |
| 4003 | |
| 4004 | |
| 4005 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4006 Label is_true, is_false; | |
| 4007 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 4008 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 4009 // Branches for isNaN are emitted in EmitComparisonCode already. | |
| 4010 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { | |
| 4011 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 4012 } | |
| 4013 const Register result = locs()->out(0).reg(); | |
| 4014 Label done; | |
| 4015 __ Comment("return bool"); | |
| 4016 __ Bind(&is_false); | |
| 4017 __ LoadObject(result, Bool::False()); | |
| 4018 __ b(&done); | |
| 4019 __ Bind(&is_true); | |
| 4020 __ LoadObject(result, Bool::True()); | |
| 4021 __ Bind(&done); | |
| 4022 } | |
| 4023 | |
| 4024 | |
| 4025 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, | 3971 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, |
| 4026 bool opt) const { | 3972 bool opt) const { |
| 4027 UNIMPLEMENTED(); | 3973 UNIMPLEMENTED(); |
| 4028 return NULL; | 3974 return NULL; |
| 4029 } | 3975 } |
| 4030 | 3976 |
| 4031 | 3977 |
| 4032 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3978 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4033 UNIMPLEMENTED(); | 3979 UNIMPLEMENTED(); |
| 4034 } | 3980 } |
| (...skipping 1944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5979 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); | 5925 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); |
| 5980 } | 5926 } |
| 5981 if (kind() != Token::kEQ_STRICT) { | 5927 if (kind() != Token::kEQ_STRICT) { |
| 5982 ASSERT(kind() == Token::kNE_STRICT); | 5928 ASSERT(kind() == Token::kNE_STRICT); |
| 5983 true_condition = NegateCondition(true_condition); | 5929 true_condition = NegateCondition(true_condition); |
| 5984 } | 5930 } |
| 5985 return true_condition; | 5931 return true_condition; |
| 5986 } | 5932 } |
| 5987 | 5933 |
| 5988 | 5934 |
| 5989 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5990 __ Comment("StrictCompareInstr"); | |
| 5991 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
| 5992 | |
| 5993 Label is_true, is_false; | |
| 5994 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 5995 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 5996 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 5997 | |
| 5998 Register result = locs()->out(0).reg(); | |
| 5999 Label done; | |
| 6000 __ Bind(&is_false); | |
| 6001 __ LoadObject(result, Bool::False()); | |
| 6002 __ b(&done); | |
| 6003 __ Bind(&is_true); | |
| 6004 __ LoadObject(result, Bool::True()); | |
| 6005 __ Bind(&done); | |
| 6006 } | |
| 6007 | |
| 6008 | |
| 6009 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 6010 BranchInstr* branch) { | |
| 6011 __ Comment("StrictCompareInstr::EmitBranchCode"); | |
| 6012 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
| 6013 | |
| 6014 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 6015 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 6016 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 6017 } | |
| 6018 | |
| 6019 | |
| 6020 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone, | 5935 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone, |
| 6021 bool opt) const { | 5936 bool opt) const { |
| 6022 return LocationSummary::Make(zone, 1, Location::RequiresRegister(), | 5937 return LocationSummary::Make(zone, 1, Location::RequiresRegister(), |
| 6023 LocationSummary::kNoCall); | 5938 LocationSummary::kNoCall); |
| 6024 } | 5939 } |
| 6025 | 5940 |
| 6026 | 5941 |
| 6027 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5942 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6028 Register value = locs()->in(0).reg(); | 5943 Register value = locs()->in(0).reg(); |
| 6029 Register result = locs()->out(0).reg(); | 5944 Register result = locs()->out(0).reg(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6084 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 5999 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
| 6085 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6000 kGrowRegExpStackRuntimeEntry, 1, locs()); |
| 6086 __ lw(result, Address(SP, 1 * kWordSize)); | 6001 __ lw(result, Address(SP, 1 * kWordSize)); |
| 6087 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 6002 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 6088 } | 6003 } |
| 6089 | 6004 |
| 6090 | 6005 |
| 6091 } // namespace dart | 6006 } // namespace dart |
| 6092 | 6007 |
| 6093 #endif // defined TARGET_ARCH_MIPS | 6008 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |