Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(777)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 20468002: Allow equality operation on mixed double/smi arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698