| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 Register result = locs()->out().reg(); | 265 Register result = locs()->out().reg(); |
| 266 | 266 |
| 267 __ TraceSimMsg("AssertBooleanInstr"); | 267 __ TraceSimMsg("AssertBooleanInstr"); |
| 268 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); | 268 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); |
| 269 ASSERT(obj == result); | 269 ASSERT(obj == result); |
| 270 } | 270 } |
| 271 | 271 |
| 272 | 272 |
| 273 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 273 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { |
| 274 const intptr_t kNumInputs = 2; | 274 const intptr_t kNumInputs = 2; |
| 275 if (receiver_class_id() == kMintCid) { | 275 if (operation_cid() == kMintCid) { |
| 276 const intptr_t kNumTemps = 1; | 276 const intptr_t kNumTemps = 1; |
| 277 LocationSummary* locs = | 277 LocationSummary* locs = |
| 278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 279 locs->set_in(0, Location::RequiresFpuRegister()); | 279 locs->set_in(0, Location::RequiresFpuRegister()); |
| 280 locs->set_in(1, Location::RequiresFpuRegister()); | 280 locs->set_in(1, Location::RequiresFpuRegister()); |
| 281 locs->set_temp(0, Location::RequiresRegister()); | 281 locs->set_temp(0, Location::RequiresRegister()); |
| 282 locs->set_out(Location::RequiresRegister()); | 282 locs->set_out(Location::RequiresRegister()); |
| 283 return locs; | 283 return locs; |
| 284 } | 284 } |
| 285 if (receiver_class_id() == kDoubleCid) { | 285 if (operation_cid() == kDoubleCid) { |
| 286 const intptr_t kNumTemps = 0; | 286 const intptr_t kNumTemps = 0; |
| 287 LocationSummary* locs = | 287 LocationSummary* locs = |
| 288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 289 locs->set_in(0, Location::RequiresFpuRegister()); | 289 locs->set_in(0, Location::RequiresFpuRegister()); |
| 290 locs->set_in(1, Location::RequiresFpuRegister()); | 290 locs->set_in(1, Location::RequiresFpuRegister()); |
| 291 locs->set_out(Location::RequiresRegister()); | 291 locs->set_out(Location::RequiresRegister()); |
| 292 return locs; | 292 return locs; |
| 293 } | 293 } |
| 294 if (receiver_class_id() == kSmiCid) { | 294 if (operation_cid() == kSmiCid) { |
| 295 const intptr_t kNumTemps = 0; | 295 const intptr_t kNumTemps = 0; |
| 296 LocationSummary* locs = | 296 LocationSummary* locs = |
| 297 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 297 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 298 locs->set_in(0, Location::RegisterOrConstant(left())); | 298 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 299 // Only one input can be a constant operand. The case of two constant | 299 // Only one input can be a constant operand. The case of two constant |
| 300 // operands should be handled by constant propagation. | 300 // operands should be handled by constant propagation. |
| 301 locs->set_in(1, locs->in(0).IsConstant() | 301 locs->set_in(1, locs->in(0).IsConstant() |
| 302 ? Location::RequiresRegister() | 302 ? Location::RequiresRegister() |
| 303 : Location::RegisterOrConstant(right())); | 303 : Location::RegisterOrConstant(right())); |
| 304 locs->set_out(Location::RequiresRegister()); | 304 locs->set_out(Location::RequiresRegister()); |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 compiler->EmitDoubleCompareBool( | 787 compiler->EmitDoubleCompareBool( |
| 788 true_condition, left, right, locs.out().reg()); | 788 true_condition, left, right, locs.out().reg()); |
| 789 } | 789 } |
| 790 } | 790 } |
| 791 | 791 |
| 792 | 792 |
| 793 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 793 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 794 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 794 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 795 BranchInstr* kNoBranch = NULL; | 795 BranchInstr* kNoBranch = NULL; |
| 796 __ Comment("EqualityCompareInstr"); | 796 __ Comment("EqualityCompareInstr"); |
| 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 15 matching lines...) Expand all Loading... |
| 831 *ic_data()); | 831 *ic_data()); |
| 832 ASSERT(locs()->out().reg() == V0); | 832 ASSERT(locs()->out().reg() == V0); |
| 833 } | 833 } |
| 834 | 834 |
| 835 | 835 |
| 836 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 836 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 837 BranchInstr* branch) { | 837 BranchInstr* branch) { |
| 838 __ TraceSimMsg("EqualityCompareInstr"); | 838 __ TraceSimMsg("EqualityCompareInstr"); |
| 839 __ Comment("EqualityCompareInstr:BranchCode"); | 839 __ Comment("EqualityCompareInstr:BranchCode"); |
| 840 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 840 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 841 if (receiver_class_id() == kSmiCid) { | 841 if (operation_cid() == kSmiCid) { |
| 842 // Deoptimizes if both arguments not Smi. | 842 // Deoptimizes if both arguments not Smi. |
| 843 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 843 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 844 return; | 844 return; |
| 845 } | 845 } |
| 846 if (receiver_class_id() == kMintCid) { | 846 if (operation_cid() == kMintCid) { |
| 847 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 847 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
| 848 return; | 848 return; |
| 849 } | 849 } |
| 850 if (receiver_class_id() == kDoubleCid) { | 850 if (operation_cid() == kDoubleCid) { |
| 851 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 851 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 852 return; | 852 return; |
| 853 } | 853 } |
| 854 if (IsCheckedStrictEqual()) { | 854 if (IsCheckedStrictEqual()) { |
| 855 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, | 855 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, |
| 856 deopt_id()); | 856 deopt_id()); |
| 857 return; | 857 return; |
| 858 } | 858 } |
| 859 if (IsPolymorphic()) { | 859 if (IsPolymorphic()) { |
| 860 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), | 860 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 879 } | 879 } |
| 880 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; | 880 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; |
| 881 __ CompareObject(CMPRES, TMP1, V0, Bool::True()); | 881 __ CompareObject(CMPRES, TMP1, V0, Bool::True()); |
| 882 branch->EmitBranchOnCondition(compiler, branch_condition); | 882 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 883 } | 883 } |
| 884 | 884 |
| 885 | 885 |
| 886 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 886 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 887 const intptr_t kNumInputs = 2; | 887 const intptr_t kNumInputs = 2; |
| 888 const intptr_t kNumTemps = 0; | 888 const intptr_t kNumTemps = 0; |
| 889 if (operands_class_id() == kMintCid) { | 889 if (operation_cid() == kMintCid) { |
| 890 const intptr_t kNumTemps = 2; | 890 const intptr_t kNumTemps = 2; |
| 891 LocationSummary* locs = | 891 LocationSummary* locs = |
| 892 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 892 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 893 locs->set_in(0, Location::RequiresFpuRegister()); | 893 locs->set_in(0, Location::RequiresFpuRegister()); |
| 894 locs->set_in(1, Location::RequiresFpuRegister()); | 894 locs->set_in(1, Location::RequiresFpuRegister()); |
| 895 locs->set_temp(0, Location::RequiresRegister()); | 895 locs->set_temp(0, Location::RequiresRegister()); |
| 896 locs->set_temp(1, Location::RequiresRegister()); | 896 locs->set_temp(1, Location::RequiresRegister()); |
| 897 locs->set_out(Location::RequiresRegister()); | 897 locs->set_out(Location::RequiresRegister()); |
| 898 return locs; | 898 return locs; |
| 899 } | 899 } |
| 900 if (operands_class_id() == kDoubleCid) { | 900 if (operation_cid() == kDoubleCid) { |
| 901 LocationSummary* summary = | 901 LocationSummary* summary = |
| 902 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 902 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 903 summary->set_in(0, Location::RequiresFpuRegister()); | 903 summary->set_in(0, Location::RequiresFpuRegister()); |
| 904 summary->set_in(1, Location::RequiresFpuRegister()); | 904 summary->set_in(1, Location::RequiresFpuRegister()); |
| 905 summary->set_out(Location::RequiresRegister()); | 905 summary->set_out(Location::RequiresRegister()); |
| 906 return summary; | 906 return summary; |
| 907 } else if (operands_class_id() == kSmiCid) { | 907 } else if (operation_cid() == kSmiCid) { |
| 908 LocationSummary* summary = | 908 LocationSummary* summary = |
| 909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 910 summary->set_in(0, Location::RegisterOrConstant(left())); | 910 summary->set_in(0, Location::RegisterOrConstant(left())); |
| 911 // Only one input can be a constant operand. The case of two constant | 911 // Only one input can be a constant operand. The case of two constant |
| 912 // operands should be handled by constant propagation. | 912 // operands should be handled by constant propagation. |
| 913 summary->set_in(1, summary->in(0).IsConstant() | 913 summary->set_in(1, summary->in(0).IsConstant() |
| 914 ? Location::RequiresRegister() | 914 ? Location::RequiresRegister() |
| 915 : Location::RegisterOrConstant(right())); | 915 : Location::RegisterOrConstant(right())); |
| 916 summary->set_out(Location::RequiresRegister()); | 916 summary->set_out(Location::RequiresRegister()); |
| 917 return summary; | 917 return summary; |
| 918 } | 918 } |
| 919 LocationSummary* locs = | 919 LocationSummary* locs = |
| 920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 921 // Pick arbitrary fixed input registers because this is a call. | 921 // Pick arbitrary fixed input registers because this is a call. |
| 922 locs->set_in(0, Location::RegisterLocation(A0)); | 922 locs->set_in(0, Location::RegisterLocation(A0)); |
| 923 locs->set_in(1, Location::RegisterLocation(A1)); | 923 locs->set_in(1, Location::RegisterLocation(A1)); |
| 924 locs->set_out(Location::RegisterLocation(V0)); | 924 locs->set_out(Location::RegisterLocation(V0)); |
| 925 return locs; | 925 return locs; |
| 926 } | 926 } |
| 927 | 927 |
| 928 | 928 |
| 929 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 929 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 930 __ TraceSimMsg("RelationalOpInstr"); | 930 __ TraceSimMsg("RelationalOpInstr"); |
| 931 if (operands_class_id() == kSmiCid) { | 931 if (operation_cid() == kSmiCid) { |
| 932 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 932 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 933 return; | 933 return; |
| 934 } | 934 } |
| 935 if (operands_class_id() == kMintCid) { | 935 if (operation_cid() == kMintCid) { |
| 936 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); | 936 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); |
| 937 return; | 937 return; |
| 938 } | 938 } |
| 939 if (operands_class_id() == kDoubleCid) { | 939 if (operation_cid() == kDoubleCid) { |
| 940 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 940 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 941 return; | 941 return; |
| 942 } | 942 } |
| 943 | 943 |
| 944 // Push arguments for the call. | 944 // Push arguments for the call. |
| 945 // TODO(fschneider): Split this instruction into different types to avoid | 945 // TODO(fschneider): Split this instruction into different types to avoid |
| 946 // explicitly pushing arguments to the call here. | 946 // explicitly pushing arguments to the call here. |
| 947 Register left = locs()->in(0).reg(); | 947 Register left = locs()->in(0).reg(); |
| 948 Register right = locs()->in(1).reg(); | 948 Register right = locs()->in(1).reg(); |
| 949 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 949 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 kNumArguments, | 998 kNumArguments, |
| 999 Object::null_array(), // No optional args. | 999 Object::null_array(), // No optional args. |
| 1000 locs(), | 1000 locs(), |
| 1001 relational_ic_data); | 1001 relational_ic_data); |
| 1002 } | 1002 } |
| 1003 | 1003 |
| 1004 | 1004 |
| 1005 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 1005 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 1006 BranchInstr* branch) { | 1006 BranchInstr* branch) { |
| 1007 __ TraceSimMsg("RelationalOpInstr"); | 1007 __ TraceSimMsg("RelationalOpInstr"); |
| 1008 if (operands_class_id() == kSmiCid) { | 1008 if (operation_cid() == kSmiCid) { |
| 1009 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 1009 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 1010 return; | 1010 return; |
| 1011 } | 1011 } |
| 1012 if (operands_class_id() == kMintCid) { | 1012 if (operation_cid() == kMintCid) { |
| 1013 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); | 1013 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); |
| 1014 return; | 1014 return; |
| 1015 } | 1015 } |
| 1016 if (operands_class_id() == kDoubleCid) { | 1016 if (operation_cid() == kDoubleCid) { |
| 1017 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 1017 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 1018 return; | 1018 return; |
| 1019 } | 1019 } |
| 1020 EmitNativeCode(compiler); | 1020 EmitNativeCode(compiler); |
| 1021 __ CompareObject(CMPRES, TMP1, V0, Bool::True()); | 1021 __ CompareObject(CMPRES, TMP1, V0, Bool::True()); |
| 1022 branch->EmitBranchOnCondition(compiler, EQ); | 1022 branch->EmitBranchOnCondition(compiler, EQ); |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 | 1025 |
| 1026 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 1026 LocationSummary* NativeCallInstr::MakeLocationSummary() const { |
| (...skipping 2837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3864 compiler->GenerateCall(token_pos(), | 3864 compiler->GenerateCall(token_pos(), |
| 3865 &label, | 3865 &label, |
| 3866 PcDescriptors::kOther, | 3866 PcDescriptors::kOther, |
| 3867 locs()); | 3867 locs()); |
| 3868 __ Drop(2); // Discard type arguments and receiver. | 3868 __ Drop(2); // Discard type arguments and receiver. |
| 3869 } | 3869 } |
| 3870 | 3870 |
| 3871 } // namespace dart | 3871 } // namespace dart |
| 3872 | 3872 |
| 3873 #endif // defined TARGET_ARCH_MIPS | 3873 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |