| 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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 locs->set_out(Location::RequiresRegister()); | 841 locs->set_out(Location::RequiresRegister()); |
| 842 return locs; | 842 return locs; |
| 843 } | 843 } |
| 844 if (operation_cid() == kDoubleCid) { | 844 if (operation_cid() == kDoubleCid) { |
| 845 LocationSummary* summary = | 845 LocationSummary* summary = |
| 846 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 846 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 847 summary->set_in(0, Location::RequiresFpuRegister()); | 847 summary->set_in(0, Location::RequiresFpuRegister()); |
| 848 summary->set_in(1, Location::RequiresFpuRegister()); | 848 summary->set_in(1, Location::RequiresFpuRegister()); |
| 849 summary->set_out(Location::RequiresRegister()); | 849 summary->set_out(Location::RequiresRegister()); |
| 850 return summary; | 850 return summary; |
| 851 } else if (operation_cid() == kSmiCid) { | |
| 852 LocationSummary* summary = | |
| 853 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 854 summary->set_in(0, Location::RegisterOrConstant(left())); | |
| 855 // Only one input can be a constant operand. The case of two constant | |
| 856 // operands should be handled by constant propagation. | |
| 857 summary->set_in(1, summary->in(0).IsConstant() | |
| 858 ? Location::RequiresRegister() | |
| 859 : Location::RegisterOrConstant(right())); | |
| 860 summary->set_out(Location::RequiresRegister()); | |
| 861 return summary; | |
| 862 } | 851 } |
| 863 LocationSummary* locs = | 852 ASSERT(operation_cid() == kSmiCid); |
| 864 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 853 LocationSummary* summary = |
| 865 // Pick arbitrary fixed input registers because this is a call. | 854 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 866 locs->set_in(0, Location::RegisterLocation(R0)); | 855 summary->set_in(0, Location::RegisterOrConstant(left())); |
| 867 locs->set_in(1, Location::RegisterLocation(R1)); | 856 // Only one input can be a constant operand. The case of two constant |
| 868 locs->set_out(Location::RegisterLocation(R0)); | 857 // operands should be handled by constant propagation. |
| 869 return locs; | 858 summary->set_in(1, summary->in(0).IsConstant() |
| 859 ? Location::RequiresRegister() |
| 860 : Location::RegisterOrConstant(right())); |
| 861 summary->set_out(Location::RequiresRegister()); |
| 862 return summary; |
| 870 } | 863 } |
| 871 | 864 |
| 872 | 865 |
| 873 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 866 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 874 if (operation_cid() == kSmiCid) { | 867 if (operation_cid() == kSmiCid) { |
| 875 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 868 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 876 return; | 869 return; |
| 877 } | 870 } |
| 878 if (operation_cid() == kMintCid) { | 871 if (operation_cid() == kMintCid) { |
| 879 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); | 872 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); |
| 880 return; | 873 return; |
| 881 } | 874 } |
| 882 if (operation_cid() == kDoubleCid) { | 875 ASSERT(operation_cid() == kDoubleCid); |
| 883 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 876 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 884 return; | |
| 885 } | |
| 886 | |
| 887 // Push arguments for the call. | |
| 888 // TODO(fschneider): Split this instruction into different types to avoid | |
| 889 // explicitly pushing arguments to the call here. | |
| 890 Register left = locs()->in(0).reg(); | |
| 891 Register right = locs()->in(1).reg(); | |
| 892 __ Push(left); | |
| 893 __ Push(right); | |
| 894 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | |
| 895 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp); | |
| 896 // Load class into R2. Since this is a call, any register except | |
| 897 // the fixed input registers would be ok. | |
| 898 ASSERT((left != R2) && (right != R2)); | |
| 899 const intptr_t kNumArguments = 2; | |
| 900 LoadValueCid(compiler, R2, left); | |
| 901 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), | |
| 902 R2, // Class id register. | |
| 903 kNumArguments, | |
| 904 Object::null_array(), // No named arguments. | |
| 905 deopt, // Deoptimize target. | |
| 906 deopt_id(), | |
| 907 token_pos(), | |
| 908 locs()); | |
| 909 return; | |
| 910 } | |
| 911 const String& function_name = | |
| 912 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | |
| 913 if (!compiler->is_optimizing()) { | |
| 914 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 915 deopt_id(), | |
| 916 token_pos()); | |
| 917 } | |
| 918 const intptr_t kNumArguments = 2; | |
| 919 const intptr_t kNumArgsChecked = 2; // Type-feedback. | |
| 920 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); | |
| 921 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | |
| 922 ASSERT(!ic_data()->IsNull()); | |
| 923 if (ic_data()->NumberOfChecks() == 0) { | |
| 924 // IC call for reoptimization populates original ICData. | |
| 925 relational_ic_data = ic_data()->raw(); | |
| 926 } else { | |
| 927 // Megamorphic call. | |
| 928 relational_ic_data = ic_data()->AsUnaryClassChecks(); | |
| 929 } | |
| 930 } else { | |
| 931 const Array& arguments_descriptor = | |
| 932 Array::Handle(ArgumentsDescriptor::New(kNumArguments, | |
| 933 Object::null_array())); | |
| 934 relational_ic_data = ICData::New(compiler->parsed_function().function(), | |
| 935 function_name, | |
| 936 arguments_descriptor, | |
| 937 deopt_id(), | |
| 938 kNumArgsChecked); | |
| 939 } | |
| 940 compiler->GenerateInstanceCall(deopt_id(), | |
| 941 token_pos(), | |
| 942 kNumArguments, | |
| 943 Object::null_array(), // No optional args. | |
| 944 locs(), | |
| 945 relational_ic_data); | |
| 946 } | 877 } |
| 947 | 878 |
| 948 | 879 |
| 949 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 880 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 950 BranchInstr* branch) { | 881 BranchInstr* branch) { |
| 951 if (operation_cid() == kSmiCid) { | 882 if (operation_cid() == kSmiCid) { |
| 952 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 883 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 953 return; | 884 return; |
| 954 } | 885 } |
| 955 if (operation_cid() == kMintCid) { | 886 if (operation_cid() == kMintCid) { |
| 956 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); | 887 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); |
| 957 return; | 888 return; |
| 958 } | 889 } |
| 959 if (operation_cid() == kDoubleCid) { | 890 ASSERT(operation_cid() == kDoubleCid); |
| 960 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 891 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 961 return; | |
| 962 } | |
| 963 EmitNativeCode(compiler); | |
| 964 __ CompareObject(R0, Bool::True()); | |
| 965 branch->EmitBranchOnCondition(compiler, EQ); | |
| 966 } | 892 } |
| 967 | 893 |
| 968 | 894 |
| 969 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 895 LocationSummary* NativeCallInstr::MakeLocationSummary() const { |
| 970 const intptr_t kNumInputs = 0; | 896 const intptr_t kNumInputs = 0; |
| 971 const intptr_t kNumTemps = 3; | 897 const intptr_t kNumTemps = 3; |
| 972 LocationSummary* locs = | 898 LocationSummary* locs = |
| 973 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 974 locs->set_temp(0, Location::RegisterLocation(R1)); | 900 locs->set_temp(0, Location::RegisterLocation(R1)); |
| 975 locs->set_temp(1, Location::RegisterLocation(R2)); | 901 locs->set_temp(1, Location::RegisterLocation(R2)); |
| (...skipping 3724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4700 compiler->GenerateCall(token_pos(), | 4626 compiler->GenerateCall(token_pos(), |
| 4701 &label, | 4627 &label, |
| 4702 PcDescriptors::kOther, | 4628 PcDescriptors::kOther, |
| 4703 locs()); | 4629 locs()); |
| 4704 __ Drop(2); // Discard type arguments and receiver. | 4630 __ Drop(2); // Discard type arguments and receiver. |
| 4705 } | 4631 } |
| 4706 | 4632 |
| 4707 } // namespace dart | 4633 } // namespace dart |
| 4708 | 4634 |
| 4709 #endif // defined TARGET_ARCH_ARM | 4635 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |