| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 case Token::kGTE: return GE; | 276 case Token::kGTE: return GE; |
| 277 default: | 277 default: |
| 278 UNREACHABLE(); | 278 UNREACHABLE(); |
| 279 return VS; | 279 return VS; |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 | 282 |
| 283 | 283 |
| 284 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 284 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { |
| 285 const intptr_t kNumInputs = 2; | 285 const intptr_t kNumInputs = 2; |
| 286 if (receiver_class_id() == kMintCid) { | 286 if (operation_cid() == kMintCid) { |
| 287 const intptr_t kNumTemps = 1; | 287 const intptr_t kNumTemps = 1; |
| 288 LocationSummary* locs = | 288 LocationSummary* locs = |
| 289 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 289 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 290 locs->set_in(0, Location::RequiresFpuRegister()); | 290 locs->set_in(0, Location::RequiresFpuRegister()); |
| 291 locs->set_in(1, Location::RequiresFpuRegister()); | 291 locs->set_in(1, Location::RequiresFpuRegister()); |
| 292 locs->set_temp(0, Location::RequiresRegister()); | 292 locs->set_temp(0, Location::RequiresRegister()); |
| 293 locs->set_out(Location::RequiresRegister()); | 293 locs->set_out(Location::RequiresRegister()); |
| 294 return locs; | 294 return locs; |
| 295 } | 295 } |
| 296 if (receiver_class_id() == kDoubleCid) { | 296 if (operation_cid() == kDoubleCid) { |
| 297 const intptr_t kNumTemps = 0; | 297 const intptr_t kNumTemps = 0; |
| 298 LocationSummary* locs = | 298 LocationSummary* locs = |
| 299 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 299 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 300 locs->set_in(0, Location::RequiresFpuRegister()); | 300 locs->set_in(0, Location::RequiresFpuRegister()); |
| 301 locs->set_in(1, Location::RequiresFpuRegister()); | 301 locs->set_in(1, Location::RequiresFpuRegister()); |
| 302 locs->set_out(Location::RequiresRegister()); | 302 locs->set_out(Location::RequiresRegister()); |
| 303 return locs; | 303 return locs; |
| 304 } | 304 } |
| 305 if (receiver_class_id() == kSmiCid) { | 305 if (operation_cid() == kSmiCid) { |
| 306 const intptr_t kNumTemps = 0; | 306 const intptr_t kNumTemps = 0; |
| 307 LocationSummary* locs = | 307 LocationSummary* locs = |
| 308 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 308 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 309 locs->set_in(0, Location::RegisterOrConstant(left())); | 309 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 310 // Only one input can be a constant operand. The case of two constant | 310 // Only one input can be a constant operand. The case of two constant |
| 311 // operands should be handled by constant propagation. | 311 // operands should be handled by constant propagation. |
| 312 locs->set_in(1, locs->in(0).IsConstant() | 312 locs->set_in(1, locs->in(0).IsConstant() |
| 313 ? Location::RequiresRegister() | 313 ? Location::RequiresRegister() |
| 314 : Location::RegisterOrConstant(right())); | 314 : Location::RegisterOrConstant(right())); |
| 315 locs->set_out(Location::RequiresRegister()); | 315 locs->set_out(Location::RequiresRegister()); |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 } else { | 739 } else { |
| 740 compiler->EmitDoubleCompareBool( | 740 compiler->EmitDoubleCompareBool( |
| 741 true_condition, left, right, locs.out().reg()); | 741 true_condition, left, right, locs.out().reg()); |
| 742 } | 742 } |
| 743 } | 743 } |
| 744 | 744 |
| 745 | 745 |
| 746 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 746 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 747 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 747 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 748 BranchInstr* kNoBranch = NULL; | 748 BranchInstr* kNoBranch = NULL; |
| 749 if (receiver_class_id() == kSmiCid) { | 749 if (operation_cid() == kSmiCid) { |
| 750 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 750 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 751 return; | 751 return; |
| 752 } | 752 } |
| 753 if (receiver_class_id() == kMintCid) { | 753 if (operation_cid() == kMintCid) { |
| 754 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); | 754 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); |
| 755 return; | 755 return; |
| 756 } | 756 } |
| 757 if (receiver_class_id() == kDoubleCid) { | 757 if (operation_cid() == kDoubleCid) { |
| 758 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); | 758 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 759 return; | 759 return; |
| 760 } | 760 } |
| 761 if (IsCheckedStrictEqual()) { | 761 if (IsCheckedStrictEqual()) { |
| 762 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, | 762 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, |
| 763 deopt_id()); | 763 deopt_id()); |
| 764 return; | 764 return; |
| 765 } | 765 } |
| 766 if (IsPolymorphic()) { | 766 if (IsPolymorphic()) { |
| 767 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), | 767 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 779 kind(), | 779 kind(), |
| 780 locs(), | 780 locs(), |
| 781 *ic_data()); | 781 *ic_data()); |
| 782 ASSERT(locs()->out().reg() == R0); | 782 ASSERT(locs()->out().reg() == R0); |
| 783 } | 783 } |
| 784 | 784 |
| 785 | 785 |
| 786 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 786 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 787 BranchInstr* branch) { | 787 BranchInstr* branch) { |
| 788 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 788 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 789 if (receiver_class_id() == kSmiCid) { | 789 if (operation_cid() == kSmiCid) { |
| 790 // Deoptimizes if both arguments not Smi. | 790 // Deoptimizes if both arguments not Smi. |
| 791 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 791 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 792 return; | 792 return; |
| 793 } | 793 } |
| 794 if (receiver_class_id() == kMintCid) { | 794 if (operation_cid() == kMintCid) { |
| 795 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 795 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
| 796 return; | 796 return; |
| 797 } | 797 } |
| 798 if (receiver_class_id() == kDoubleCid) { | 798 if (operation_cid() == kDoubleCid) { |
| 799 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 799 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 800 return; | 800 return; |
| 801 } | 801 } |
| 802 if (IsCheckedStrictEqual()) { | 802 if (IsCheckedStrictEqual()) { |
| 803 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, | 803 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, |
| 804 deopt_id()); | 804 deopt_id()); |
| 805 return; | 805 return; |
| 806 } | 806 } |
| 807 if (IsPolymorphic()) { | 807 if (IsPolymorphic()) { |
| 808 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), | 808 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 825 } | 825 } |
| 826 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; | 826 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; |
| 827 __ CompareObject(R0, Bool::True()); | 827 __ CompareObject(R0, Bool::True()); |
| 828 branch->EmitBranchOnCondition(compiler, branch_condition); | 828 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| 832 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 832 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 833 const intptr_t kNumInputs = 2; | 833 const intptr_t kNumInputs = 2; |
| 834 const intptr_t kNumTemps = 0; | 834 const intptr_t kNumTemps = 0; |
| 835 if (operands_class_id() == kMintCid) { | 835 if (operation_cid() == kMintCid) { |
| 836 const intptr_t kNumTemps = 2; | 836 const intptr_t kNumTemps = 2; |
| 837 LocationSummary* locs = | 837 LocationSummary* locs = |
| 838 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 838 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 839 locs->set_in(0, Location::RequiresFpuRegister()); | 839 locs->set_in(0, Location::RequiresFpuRegister()); |
| 840 locs->set_in(1, Location::RequiresFpuRegister()); | 840 locs->set_in(1, Location::RequiresFpuRegister()); |
| 841 locs->set_temp(0, Location::RequiresRegister()); | 841 locs->set_temp(0, Location::RequiresRegister()); |
| 842 locs->set_temp(1, Location::RequiresRegister()); | 842 locs->set_temp(1, Location::RequiresRegister()); |
| 843 locs->set_out(Location::RequiresRegister()); | 843 locs->set_out(Location::RequiresRegister()); |
| 844 return locs; | 844 return locs; |
| 845 } | 845 } |
| 846 if (operands_class_id() == kDoubleCid) { | 846 if (operation_cid() == kDoubleCid) { |
| 847 LocationSummary* summary = | 847 LocationSummary* summary = |
| 848 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 848 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 849 summary->set_in(0, Location::RequiresFpuRegister()); | 849 summary->set_in(0, Location::RequiresFpuRegister()); |
| 850 summary->set_in(1, Location::RequiresFpuRegister()); | 850 summary->set_in(1, Location::RequiresFpuRegister()); |
| 851 summary->set_out(Location::RequiresRegister()); | 851 summary->set_out(Location::RequiresRegister()); |
| 852 return summary; | 852 return summary; |
| 853 } else if (operands_class_id() == kSmiCid) { | 853 } else if (operation_cid() == kSmiCid) { |
| 854 LocationSummary* summary = | 854 LocationSummary* summary = |
| 855 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 855 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 856 summary->set_in(0, Location::RegisterOrConstant(left())); | 856 summary->set_in(0, Location::RegisterOrConstant(left())); |
| 857 // Only one input can be a constant operand. The case of two constant | 857 // Only one input can be a constant operand. The case of two constant |
| 858 // operands should be handled by constant propagation. | 858 // operands should be handled by constant propagation. |
| 859 summary->set_in(1, summary->in(0).IsConstant() | 859 summary->set_in(1, summary->in(0).IsConstant() |
| 860 ? Location::RequiresRegister() | 860 ? Location::RequiresRegister() |
| 861 : Location::RegisterOrConstant(right())); | 861 : Location::RegisterOrConstant(right())); |
| 862 summary->set_out(Location::RequiresRegister()); | 862 summary->set_out(Location::RequiresRegister()); |
| 863 return summary; | 863 return summary; |
| 864 } | 864 } |
| 865 LocationSummary* locs = | 865 LocationSummary* locs = |
| 866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 867 // Pick arbitrary fixed input registers because this is a call. | 867 // Pick arbitrary fixed input registers because this is a call. |
| 868 locs->set_in(0, Location::RegisterLocation(R0)); | 868 locs->set_in(0, Location::RegisterLocation(R0)); |
| 869 locs->set_in(1, Location::RegisterLocation(R1)); | 869 locs->set_in(1, Location::RegisterLocation(R1)); |
| 870 locs->set_out(Location::RegisterLocation(R0)); | 870 locs->set_out(Location::RegisterLocation(R0)); |
| 871 return locs; | 871 return locs; |
| 872 } | 872 } |
| 873 | 873 |
| 874 | 874 |
| 875 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 875 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 876 if (operands_class_id() == kSmiCid) { | 876 if (operation_cid() == kSmiCid) { |
| 877 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 877 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 878 return; | 878 return; |
| 879 } | 879 } |
| 880 if (operands_class_id() == kMintCid) { | 880 if (operation_cid() == kMintCid) { |
| 881 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); | 881 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); |
| 882 return; | 882 return; |
| 883 } | 883 } |
| 884 if (operands_class_id() == kDoubleCid) { | 884 if (operation_cid() == kDoubleCid) { |
| 885 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 885 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 886 return; | 886 return; |
| 887 } | 887 } |
| 888 | 888 |
| 889 // Push arguments for the call. | 889 // Push arguments for the call. |
| 890 // TODO(fschneider): Split this instruction into different types to avoid | 890 // TODO(fschneider): Split this instruction into different types to avoid |
| 891 // explicitly pushing arguments to the call here. | 891 // explicitly pushing arguments to the call here. |
| 892 Register left = locs()->in(0).reg(); | 892 Register left = locs()->in(0).reg(); |
| 893 Register right = locs()->in(1).reg(); | 893 Register right = locs()->in(1).reg(); |
| 894 __ Push(left); | 894 __ Push(left); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 token_pos(), | 943 token_pos(), |
| 944 kNumArguments, | 944 kNumArguments, |
| 945 Object::null_array(), // No optional args. | 945 Object::null_array(), // No optional args. |
| 946 locs(), | 946 locs(), |
| 947 relational_ic_data); | 947 relational_ic_data); |
| 948 } | 948 } |
| 949 | 949 |
| 950 | 950 |
| 951 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 951 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 952 BranchInstr* branch) { | 952 BranchInstr* branch) { |
| 953 if (operands_class_id() == kSmiCid) { | 953 if (operation_cid() == kSmiCid) { |
| 954 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 954 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 955 return; | 955 return; |
| 956 } | 956 } |
| 957 if (operands_class_id() == kMintCid) { | 957 if (operation_cid() == kMintCid) { |
| 958 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); | 958 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); |
| 959 return; | 959 return; |
| 960 } | 960 } |
| 961 if (operands_class_id() == kDoubleCid) { | 961 if (operation_cid() == kDoubleCid) { |
| 962 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 962 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 963 return; | 963 return; |
| 964 } | 964 } |
| 965 EmitNativeCode(compiler); | 965 EmitNativeCode(compiler); |
| 966 __ CompareObject(R0, Bool::True()); | 966 __ CompareObject(R0, Bool::True()); |
| 967 branch->EmitBranchOnCondition(compiler, EQ); | 967 branch->EmitBranchOnCondition(compiler, EQ); |
| 968 } | 968 } |
| 969 | 969 |
| 970 | 970 |
| 971 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 971 LocationSummary* NativeCallInstr::MakeLocationSummary() const { |
| (...skipping 3395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4367 compiler->GenerateCall(token_pos(), | 4367 compiler->GenerateCall(token_pos(), |
| 4368 &label, | 4368 &label, |
| 4369 PcDescriptors::kOther, | 4369 PcDescriptors::kOther, |
| 4370 locs()); | 4370 locs()); |
| 4371 __ Drop(2); // Discard type arguments and receiver. | 4371 __ Drop(2); // Discard type arguments and receiver. |
| 4372 } | 4372 } |
| 4373 | 4373 |
| 4374 } // namespace dart | 4374 } // namespace dart |
| 4375 | 4375 |
| 4376 #endif // defined TARGET_ARCH_ARM | 4376 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |