| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 case Token::kGTE: return GREATER_EQUAL; | 223 case Token::kGTE: return GREATER_EQUAL; |
| 224 default: | 224 default: |
| 225 UNREACHABLE(); | 225 UNREACHABLE(); |
| 226 return OVERFLOW; | 226 return OVERFLOW; |
| 227 } | 227 } |
| 228 } | 228 } |
| 229 | 229 |
| 230 | 230 |
| 231 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 231 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { |
| 232 const intptr_t kNumInputs = 2; | 232 const intptr_t kNumInputs = 2; |
| 233 if (receiver_class_id() == kMintCid) { | 233 if (operation_cid() == kMintCid) { |
| 234 const intptr_t kNumTemps = 1; | 234 const intptr_t kNumTemps = 1; |
| 235 LocationSummary* locs = | 235 LocationSummary* locs = |
| 236 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 236 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 237 locs->set_in(0, Location::RequiresFpuRegister()); | 237 locs->set_in(0, Location::RequiresFpuRegister()); |
| 238 locs->set_in(1, Location::RequiresFpuRegister()); | 238 locs->set_in(1, Location::RequiresFpuRegister()); |
| 239 locs->set_temp(0, Location::RequiresRegister()); | 239 locs->set_temp(0, Location::RequiresRegister()); |
| 240 locs->set_out(Location::RequiresRegister()); | 240 locs->set_out(Location::RequiresRegister()); |
| 241 return locs; | 241 return locs; |
| 242 } | 242 } |
| 243 if (receiver_class_id() == kDoubleCid) { | 243 if (operation_cid() == kDoubleCid) { |
| 244 const intptr_t kNumTemps = 0; | 244 const intptr_t kNumTemps = 0; |
| 245 LocationSummary* locs = | 245 LocationSummary* locs = |
| 246 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 246 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 247 locs->set_in(0, Location::RequiresFpuRegister()); | 247 locs->set_in(0, Location::RequiresFpuRegister()); |
| 248 locs->set_in(1, Location::RequiresFpuRegister()); | 248 locs->set_in(1, Location::RequiresFpuRegister()); |
| 249 locs->set_out(Location::RequiresRegister()); | 249 locs->set_out(Location::RequiresRegister()); |
| 250 return locs; | 250 return locs; |
| 251 } | 251 } |
| 252 if (receiver_class_id() == kSmiCid) { | 252 if (operation_cid() == kSmiCid) { |
| 253 const intptr_t kNumTemps = 0; | 253 const intptr_t kNumTemps = 0; |
| 254 LocationSummary* locs = | 254 LocationSummary* locs = |
| 255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 256 locs->set_in(0, Location::RegisterOrConstant(left())); | 256 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 257 // Only one input can be a constant operand. The case of two constant | 257 // Only one input can be a constant operand. The case of two constant |
| 258 // operands should be handled by constant propagation. | 258 // operands should be handled by constant propagation. |
| 259 // Only right can be a stack slot. | 259 // Only right can be a stack slot. |
| 260 locs->set_in(1, locs->in(0).IsConstant() | 260 locs->set_in(1, locs->in(0).IsConstant() |
| 261 ? Location::RequiresRegister() | 261 ? Location::RequiresRegister() |
| 262 : Location::RegisterOrConstant(right())); | 262 : Location::RegisterOrConstant(right())); |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 } else { | 787 } else { |
| 788 compiler->EmitDoubleCompareBool( | 788 compiler->EmitDoubleCompareBool( |
| 789 true_condition, left, right, locs.out().reg()); | 789 true_condition, left, right, locs.out().reg()); |
| 790 } | 790 } |
| 791 } | 791 } |
| 792 | 792 |
| 793 | 793 |
| 794 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 794 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 795 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 795 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 796 BranchInstr* kNoBranch = NULL; | 796 BranchInstr* kNoBranch = NULL; |
| 797 if (receiver_class_id() == kSmiCid) { | 797 if (operation_cid() == kSmiCid) { |
| 798 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 798 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 799 return; | 799 return; |
| 800 } | 800 } |
| 801 if (receiver_class_id() == kMintCid) { | 801 if (operation_cid() == kMintCid) { |
| 802 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); | 802 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); |
| 803 return; | 803 return; |
| 804 } | 804 } |
| 805 if (receiver_class_id() == kDoubleCid) { | 805 if (operation_cid() == kDoubleCid) { |
| 806 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); | 806 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 807 return; | 807 return; |
| 808 } | 808 } |
| 809 if (IsCheckedStrictEqual()) { | 809 if (IsCheckedStrictEqual()) { |
| 810 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, | 810 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, |
| 811 deopt_id()); | 811 deopt_id()); |
| 812 return; | 812 return; |
| 813 } | 813 } |
| 814 if (IsPolymorphic()) { | 814 if (IsPolymorphic()) { |
| 815 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), | 815 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 826 kind(), | 826 kind(), |
| 827 locs(), | 827 locs(), |
| 828 *ic_data()); | 828 *ic_data()); |
| 829 ASSERT(locs()->out().reg() == EAX); | 829 ASSERT(locs()->out().reg() == EAX); |
| 830 } | 830 } |
| 831 | 831 |
| 832 | 832 |
| 833 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 833 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 834 BranchInstr* branch) { | 834 BranchInstr* branch) { |
| 835 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 835 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 836 if (receiver_class_id() == kSmiCid) { | 836 if (operation_cid() == kSmiCid) { |
| 837 // Deoptimizes if both arguments not Smi. | 837 // Deoptimizes if both arguments not Smi. |
| 838 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 838 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 839 return; | 839 return; |
| 840 } | 840 } |
| 841 if (receiver_class_id() == kMintCid) { | 841 if (operation_cid() == kMintCid) { |
| 842 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 842 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
| 843 return; | 843 return; |
| 844 } | 844 } |
| 845 if (receiver_class_id() == kDoubleCid) { | 845 if (operation_cid() == kDoubleCid) { |
| 846 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 846 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 847 return; | 847 return; |
| 848 } | 848 } |
| 849 if (IsCheckedStrictEqual()) { | 849 if (IsCheckedStrictEqual()) { |
| 850 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, | 850 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, |
| 851 deopt_id()); | 851 deopt_id()); |
| 852 return; | 852 return; |
| 853 } | 853 } |
| 854 if (IsPolymorphic()) { | 854 if (IsPolymorphic()) { |
| 855 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), | 855 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 871 } | 871 } |
| 872 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 872 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 873 __ CompareObject(EAX, Bool::True()); | 873 __ CompareObject(EAX, Bool::True()); |
| 874 branch->EmitBranchOnCondition(compiler, branch_condition); | 874 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 875 } | 875 } |
| 876 | 876 |
| 877 | 877 |
| 878 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 878 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 879 const intptr_t kNumInputs = 2; | 879 const intptr_t kNumInputs = 2; |
| 880 const intptr_t kNumTemps = 0; | 880 const intptr_t kNumTemps = 0; |
| 881 if (operands_class_id() == kMintCid) { | 881 if (operation_cid() == kMintCid) { |
| 882 const intptr_t kNumTemps = 2; | 882 const intptr_t kNumTemps = 2; |
| 883 LocationSummary* locs = | 883 LocationSummary* locs = |
| 884 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 884 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 885 locs->set_in(0, Location::RequiresFpuRegister()); | 885 locs->set_in(0, Location::RequiresFpuRegister()); |
| 886 locs->set_in(1, Location::RequiresFpuRegister()); | 886 locs->set_in(1, Location::RequiresFpuRegister()); |
| 887 locs->set_temp(0, Location::RequiresRegister()); | 887 locs->set_temp(0, Location::RequiresRegister()); |
| 888 locs->set_temp(1, Location::RequiresRegister()); | 888 locs->set_temp(1, Location::RequiresRegister()); |
| 889 locs->set_out(Location::RequiresRegister()); | 889 locs->set_out(Location::RequiresRegister()); |
| 890 return locs; | 890 return locs; |
| 891 } | 891 } |
| 892 if (operands_class_id() == kDoubleCid) { | 892 if (operation_cid() == kDoubleCid) { |
| 893 LocationSummary* summary = | 893 LocationSummary* summary = |
| 894 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 894 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 895 summary->set_in(0, Location::RequiresFpuRegister()); | 895 summary->set_in(0, Location::RequiresFpuRegister()); |
| 896 summary->set_in(1, Location::RequiresFpuRegister()); | 896 summary->set_in(1, Location::RequiresFpuRegister()); |
| 897 summary->set_out(Location::RequiresRegister()); | 897 summary->set_out(Location::RequiresRegister()); |
| 898 return summary; | 898 return summary; |
| 899 } else if (operands_class_id() == kSmiCid) { | 899 } else if (operation_cid() == kSmiCid) { |
| 900 LocationSummary* summary = | 900 LocationSummary* summary = |
| 901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 902 summary->set_in(0, Location::RegisterOrConstant(left())); | 902 summary->set_in(0, Location::RegisterOrConstant(left())); |
| 903 // Only one input can be a constant operand. The case of two constant | 903 // Only one input can be a constant operand. The case of two constant |
| 904 // operands should be handled by constant propagation. | 904 // operands should be handled by constant propagation. |
| 905 summary->set_in(1, summary->in(0).IsConstant() | 905 summary->set_in(1, summary->in(0).IsConstant() |
| 906 ? Location::RequiresRegister() | 906 ? Location::RequiresRegister() |
| 907 : Location::RegisterOrConstant(right())); | 907 : Location::RegisterOrConstant(right())); |
| 908 summary->set_out(Location::RequiresRegister()); | 908 summary->set_out(Location::RequiresRegister()); |
| 909 return summary; | 909 return summary; |
| 910 } | 910 } |
| 911 LocationSummary* locs = | 911 LocationSummary* locs = |
| 912 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 912 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 913 // Pick arbitrary fixed input registers because this is a call. | 913 // Pick arbitrary fixed input registers because this is a call. |
| 914 locs->set_in(0, Location::RegisterLocation(EAX)); | 914 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 915 locs->set_in(1, Location::RegisterLocation(ECX)); | 915 locs->set_in(1, Location::RegisterLocation(ECX)); |
| 916 locs->set_out(Location::RegisterLocation(EAX)); | 916 locs->set_out(Location::RegisterLocation(EAX)); |
| 917 return locs; | 917 return locs; |
| 918 } | 918 } |
| 919 | 919 |
| 920 | 920 |
| 921 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 921 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 922 if (operands_class_id() == kSmiCid) { | 922 if (operation_cid() == kSmiCid) { |
| 923 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 923 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 924 return; | 924 return; |
| 925 } | 925 } |
| 926 if (operands_class_id() == kMintCid) { | 926 if (operation_cid() == kMintCid) { |
| 927 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); | 927 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); |
| 928 return; | 928 return; |
| 929 } | 929 } |
| 930 if (operands_class_id() == kDoubleCid) { | 930 if (operation_cid() == kDoubleCid) { |
| 931 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 931 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 932 return; | 932 return; |
| 933 } | 933 } |
| 934 | 934 |
| 935 // Push arguments for the call. | 935 // Push arguments for the call. |
| 936 // TODO(fschneider): Split this instruction into different types to avoid | 936 // TODO(fschneider): Split this instruction into different types to avoid |
| 937 // explicitly pushing arguments to the call here. | 937 // explicitly pushing arguments to the call here. |
| 938 Register left = locs()->in(0).reg(); | 938 Register left = locs()->in(0).reg(); |
| 939 Register right = locs()->in(1).reg(); | 939 Register right = locs()->in(1).reg(); |
| 940 __ pushl(left); | 940 __ pushl(left); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 token_pos(), | 989 token_pos(), |
| 990 kNumArguments, | 990 kNumArguments, |
| 991 Object::null_array(), // No optional args. | 991 Object::null_array(), // No optional args. |
| 992 locs(), | 992 locs(), |
| 993 relational_ic_data); | 993 relational_ic_data); |
| 994 } | 994 } |
| 995 | 995 |
| 996 | 996 |
| 997 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 997 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 998 BranchInstr* branch) { | 998 BranchInstr* branch) { |
| 999 if (operands_class_id() == kSmiCid) { | 999 if (operation_cid() == kSmiCid) { |
| 1000 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 1000 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 1001 return; | 1001 return; |
| 1002 } | 1002 } |
| 1003 if (operands_class_id() == kMintCid) { | 1003 if (operation_cid() == kMintCid) { |
| 1004 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); | 1004 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); |
| 1005 return; | 1005 return; |
| 1006 } | 1006 } |
| 1007 if (operands_class_id() == kDoubleCid) { | 1007 if (operation_cid() == kDoubleCid) { |
| 1008 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 1008 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 1009 return; | 1009 return; |
| 1010 } | 1010 } |
| 1011 EmitNativeCode(compiler); | 1011 EmitNativeCode(compiler); |
| 1012 __ CompareObject(EAX, Bool::True()); | 1012 __ CompareObject(EAX, Bool::True()); |
| 1013 branch->EmitBranchOnCondition(compiler, EQUAL); | 1013 branch->EmitBranchOnCondition(compiler, EQUAL); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 | 1016 |
| 1017 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 1017 LocationSummary* NativeCallInstr::MakeLocationSummary() const { |
| (...skipping 3600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4618 return true; | 4618 return true; |
| 4619 } | 4619 } |
| 4620 | 4620 |
| 4621 | 4621 |
| 4622 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, | 4622 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, |
| 4623 Value* v1, | 4623 Value* v1, |
| 4624 Value* v2) { | 4624 Value* v2) { |
| 4625 if (!(comparison->IsStrictCompare() && | 4625 if (!(comparison->IsStrictCompare() && |
| 4626 !comparison->AsStrictCompare()->needs_number_check()) && | 4626 !comparison->AsStrictCompare()->needs_number_check()) && |
| 4627 !(comparison->IsEqualityCompare() && | 4627 !(comparison->IsEqualityCompare() && |
| 4628 (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) { | 4628 (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) { |
| 4629 return false; | 4629 return false; |
| 4630 } | 4630 } |
| 4631 | 4631 |
| 4632 intptr_t v1_value, v2_value; | 4632 intptr_t v1_value, v2_value; |
| 4633 | 4633 |
| 4634 if (!BindsToSmiConstant(v1, &v1_value) || | 4634 if (!BindsToSmiConstant(v1, &v1_value) || |
| 4635 !BindsToSmiConstant(v2, &v2_value)) { | 4635 !BindsToSmiConstant(v2, &v2_value)) { |
| 4636 return false; | 4636 return false; |
| 4637 } | 4637 } |
| 4638 | 4638 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4839 PcDescriptors::kOther, | 4839 PcDescriptors::kOther, |
| 4840 locs()); | 4840 locs()); |
| 4841 __ Drop(2); // Discard type arguments and receiver. | 4841 __ Drop(2); // Discard type arguments and receiver. |
| 4842 } | 4842 } |
| 4843 | 4843 |
| 4844 } // namespace dart | 4844 } // namespace dart |
| 4845 | 4845 |
| 4846 #undef __ | 4846 #undef __ |
| 4847 | 4847 |
| 4848 #endif // defined TARGET_ARCH_IA32 | 4848 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |