| 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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 locs->set_out(Location::RequiresRegister()); | 895 locs->set_out(Location::RequiresRegister()); |
| 896 return locs; | 896 return locs; |
| 897 } | 897 } |
| 898 if (operation_cid() == kDoubleCid) { | 898 if (operation_cid() == kDoubleCid) { |
| 899 LocationSummary* summary = | 899 LocationSummary* summary = |
| 900 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 900 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 901 summary->set_in(0, Location::RequiresFpuRegister()); | 901 summary->set_in(0, Location::RequiresFpuRegister()); |
| 902 summary->set_in(1, Location::RequiresFpuRegister()); | 902 summary->set_in(1, Location::RequiresFpuRegister()); |
| 903 summary->set_out(Location::RequiresRegister()); | 903 summary->set_out(Location::RequiresRegister()); |
| 904 return summary; | 904 return summary; |
| 905 } else if (operation_cid() == kSmiCid) { | |
| 906 LocationSummary* summary = | |
| 907 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 908 summary->set_in(0, Location::RegisterOrConstant(left())); | |
| 909 // Only one input can be a constant operand. The case of two constant | |
| 910 // operands should be handled by constant propagation. | |
| 911 summary->set_in(1, summary->in(0).IsConstant() | |
| 912 ? Location::RequiresRegister() | |
| 913 : Location::RegisterOrConstant(right())); | |
| 914 summary->set_out(Location::RequiresRegister()); | |
| 915 return summary; | |
| 916 } | 905 } |
| 917 LocationSummary* locs = | 906 ASSERT(operation_cid() == kSmiCid); |
| 918 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 907 LocationSummary* summary = |
| 919 // Pick arbitrary fixed input registers because this is a call. | 908 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 920 locs->set_in(0, Location::RegisterLocation(A0)); | 909 summary->set_in(0, Location::RegisterOrConstant(left())); |
| 921 locs->set_in(1, Location::RegisterLocation(A1)); | 910 // Only one input can be a constant operand. The case of two constant |
| 922 locs->set_out(Location::RegisterLocation(V0)); | 911 // operands should be handled by constant propagation. |
| 923 return locs; | 912 summary->set_in(1, summary->in(0).IsConstant() |
| 913 ? Location::RequiresRegister() |
| 914 : Location::RegisterOrConstant(right())); |
| 915 summary->set_out(Location::RequiresRegister()); |
| 916 return summary; |
| 924 } | 917 } |
| 925 | 918 |
| 926 | 919 |
| 927 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 920 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 928 __ TraceSimMsg("RelationalOpInstr"); | 921 __ TraceSimMsg("RelationalOpInstr"); |
| 929 if (operation_cid() == kSmiCid) { | 922 if (operation_cid() == kSmiCid) { |
| 930 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 923 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 931 return; | 924 return; |
| 932 } | 925 } |
| 933 if (operation_cid() == kMintCid) { | 926 if (operation_cid() == kMintCid) { |
| 934 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); | 927 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); |
| 935 return; | 928 return; |
| 936 } | 929 } |
| 937 if (operation_cid() == kDoubleCid) { | 930 ASSERT(operation_cid() == kDoubleCid); |
| 938 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 931 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 939 return; | 932 return; |
| 940 } | |
| 941 | |
| 942 // Push arguments for the call. | |
| 943 // TODO(fschneider): Split this instruction into different types to avoid | |
| 944 // explicitly pushing arguments to the call here. | |
| 945 Register left = locs()->in(0).reg(); | |
| 946 Register right = locs()->in(1).reg(); | |
| 947 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
| 948 __ sw(left, Address(SP, 1 * kWordSize)); | |
| 949 __ sw(right, Address(SP, 0 * kWordSize)); | |
| 950 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | |
| 951 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp); | |
| 952 // Load class into A2. | |
| 953 const intptr_t kNumArguments = 2; | |
| 954 LoadValueCid(compiler, A2, left); | |
| 955 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), | |
| 956 A2, // Class id register. | |
| 957 kNumArguments, | |
| 958 Object::null_array(), // No named arguments. | |
| 959 deopt, // Deoptimize target. | |
| 960 deopt_id(), | |
| 961 token_pos(), | |
| 962 locs()); | |
| 963 return; | |
| 964 } | |
| 965 const String& function_name = | |
| 966 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | |
| 967 if (!compiler->is_optimizing()) { | |
| 968 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 969 deopt_id(), | |
| 970 token_pos()); | |
| 971 } | |
| 972 const intptr_t kNumArguments = 2; | |
| 973 const intptr_t kNumArgsChecked = 2; // Type-feedback. | |
| 974 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); | |
| 975 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | |
| 976 ASSERT(!ic_data()->IsNull()); | |
| 977 if (ic_data()->NumberOfChecks() == 0) { | |
| 978 // IC call for reoptimization populates original ICData. | |
| 979 relational_ic_data = ic_data()->raw(); | |
| 980 } else { | |
| 981 // Megamorphic call. | |
| 982 relational_ic_data = ic_data()->AsUnaryClassChecks(); | |
| 983 } | |
| 984 } else { | |
| 985 const Array& arguments_descriptor = | |
| 986 Array::Handle(ArgumentsDescriptor::New(kNumArguments, | |
| 987 Object::null_array())); | |
| 988 relational_ic_data = ICData::New(compiler->parsed_function().function(), | |
| 989 function_name, | |
| 990 arguments_descriptor, | |
| 991 deopt_id(), | |
| 992 kNumArgsChecked); | |
| 993 } | |
| 994 compiler->GenerateInstanceCall(deopt_id(), | |
| 995 token_pos(), | |
| 996 kNumArguments, | |
| 997 Object::null_array(), // No optional args. | |
| 998 locs(), | |
| 999 relational_ic_data); | |
| 1000 } | 933 } |
| 1001 | 934 |
| 1002 | 935 |
| 1003 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 936 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 1004 BranchInstr* branch) { | 937 BranchInstr* branch) { |
| 1005 __ TraceSimMsg("RelationalOpInstr"); | 938 __ TraceSimMsg("RelationalOpInstr"); |
| 1006 if (operation_cid() == kSmiCid) { | 939 if (operation_cid() == kSmiCid) { |
| 1007 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 940 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 1008 return; | 941 return; |
| 1009 } | 942 } |
| 1010 if (operation_cid() == kMintCid) { | 943 if (operation_cid() == kMintCid) { |
| 1011 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); | 944 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); |
| 1012 return; | 945 return; |
| 1013 } | 946 } |
| 1014 if (operation_cid() == kDoubleCid) { | 947 ASSERT(operation_cid() == kDoubleCid); |
| 1015 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 948 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 1016 return; | |
| 1017 } | |
| 1018 EmitNativeCode(compiler); | |
| 1019 __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); | |
| 1020 branch->EmitBranchOnCondition(compiler, EQ); | |
| 1021 } | 949 } |
| 1022 | 950 |
| 1023 | 951 |
| 1024 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 952 LocationSummary* NativeCallInstr::MakeLocationSummary() const { |
| 1025 const intptr_t kNumInputs = 0; | 953 const intptr_t kNumInputs = 0; |
| 1026 const intptr_t kNumTemps = 3; | 954 const intptr_t kNumTemps = 3; |
| 1027 LocationSummary* locs = | 955 LocationSummary* locs = |
| 1028 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 956 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1029 locs->set_temp(0, Location::RegisterLocation(A1)); | 957 locs->set_temp(0, Location::RegisterLocation(A1)); |
| 1030 locs->set_temp(1, Location::RegisterLocation(A2)); | 958 locs->set_temp(1, Location::RegisterLocation(A2)); |
| (...skipping 3106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4137 compiler->GenerateCall(token_pos(), | 4065 compiler->GenerateCall(token_pos(), |
| 4138 &label, | 4066 &label, |
| 4139 PcDescriptors::kOther, | 4067 PcDescriptors::kOther, |
| 4140 locs()); | 4068 locs()); |
| 4141 __ Drop(2); // Discard type arguments and receiver. | 4069 __ Drop(2); // Discard type arguments and receiver. |
| 4142 } | 4070 } |
| 4143 | 4071 |
| 4144 } // namespace dart | 4072 } // namespace dart |
| 4145 | 4073 |
| 4146 #endif // defined TARGET_ARCH_MIPS | 4074 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |