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

Side by Side Diff: runtime/vm/intermediate_language_x64.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, 4 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 return true; 162 return true;
163 } 163 }
164 164
165 165
166 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, 166 bool IfThenElseInstr::Supports(ComparisonInstr* comparison,
167 Value* v1, 167 Value* v1,
168 Value* v2) { 168 Value* v2) {
169 if (!(comparison->IsStrictCompare() && 169 if (!(comparison->IsStrictCompare() &&
170 !comparison->AsStrictCompare()->needs_number_check()) && 170 !comparison->AsStrictCompare()->needs_number_check()) &&
171 !(comparison->IsEqualityCompare() && 171 !(comparison->IsEqualityCompare() &&
172 (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) { 172 (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) {
173 return false; 173 return false;
174 } 174 }
175 175
176 intptr_t v1_value, v2_value; 176 intptr_t v1_value, v2_value;
177 177
178 if (!BindsToSmiConstant(v1, &v1_value) || 178 if (!BindsToSmiConstant(v1, &v1_value) ||
179 !BindsToSmiConstant(v2, &v2_value)) { 179 !BindsToSmiConstant(v2, &v2_value)) {
180 return false; 180 return false;
181 } 181 }
182 182
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 case Token::kGTE: return GREATER_EQUAL; 389 case Token::kGTE: return GREATER_EQUAL;
390 default: 390 default:
391 UNREACHABLE(); 391 UNREACHABLE();
392 return OVERFLOW; 392 return OVERFLOW;
393 } 393 }
394 } 394 }
395 395
396 396
397 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 397 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
398 const intptr_t kNumInputs = 2; 398 const intptr_t kNumInputs = 2;
399 if (receiver_class_id() == kDoubleCid) { 399 if (operation_cid() == kDoubleCid) {
400 const intptr_t kNumTemps = 0; 400 const intptr_t kNumTemps = 0;
401 LocationSummary* locs = 401 LocationSummary* locs =
402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
403 locs->set_in(0, Location::RequiresFpuRegister()); 403 locs->set_in(0, Location::RequiresFpuRegister());
404 locs->set_in(1, Location::RequiresFpuRegister()); 404 locs->set_in(1, Location::RequiresFpuRegister());
405 locs->set_out(Location::RequiresRegister()); 405 locs->set_out(Location::RequiresRegister());
406 return locs; 406 return locs;
407 } 407 }
408 if (receiver_class_id() == kSmiCid) { 408 if (operation_cid() == kSmiCid) {
409 const intptr_t kNumTemps = 0; 409 const intptr_t kNumTemps = 0;
410 LocationSummary* locs = 410 LocationSummary* locs =
411 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 411 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
412 locs->set_in(0, Location::RegisterOrConstant(left())); 412 locs->set_in(0, Location::RegisterOrConstant(left()));
413 // Only one input can be a constant operand. The case of two constant 413 // Only one input can be a constant operand. The case of two constant
414 // operands should be handled by constant propagation. 414 // operands should be handled by constant propagation.
415 // Only right can be a stack slot. 415 // Only right can be a stack slot.
416 locs->set_in(1, locs->in(0).IsConstant() 416 locs->set_in(1, locs->in(0).IsConstant()
417 ? Location::RequiresRegister() 417 ? Location::RequiresRegister()
418 : Location::RegisterOrConstant(right())); 418 : Location::RegisterOrConstant(right()));
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 } else { 834 } else {
835 compiler->EmitDoubleCompareBool( 835 compiler->EmitDoubleCompareBool(
836 true_condition, left, right, locs.out().reg()); 836 true_condition, left, right, locs.out().reg());
837 } 837 }
838 } 838 }
839 839
840 840
841 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 841 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
842 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 842 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
843 BranchInstr* kNoBranch = NULL; 843 BranchInstr* kNoBranch = NULL;
844 if (receiver_class_id() == kSmiCid) { 844 if (operation_cid() == kSmiCid) {
845 // Deoptimizes if both arguments not Smi. 845 // Deoptimizes if both arguments not Smi.
846 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 846 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
847 return; 847 return;
848 } 848 }
849 if (receiver_class_id() == kDoubleCid) { 849 if (operation_cid() == kDoubleCid) {
850 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 850 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
851 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); 851 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
852 return; 852 return;
853 } 853 }
854 if (IsCheckedStrictEqual()) { 854 if (IsCheckedStrictEqual()) {
855 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, 855 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
856 deopt_id()); 856 deopt_id());
857 return; 857 return;
858 } 858 }
859 if (IsPolymorphic()) { 859 if (IsPolymorphic()) {
(...skipping 11 matching lines...) Expand all
871 kind(), 871 kind(),
872 locs(), 872 locs(),
873 *ic_data()); 873 *ic_data());
874 ASSERT(locs()->out().reg() == RAX); 874 ASSERT(locs()->out().reg() == RAX);
875 } 875 }
876 876
877 877
878 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 878 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
879 BranchInstr* branch) { 879 BranchInstr* branch) {
880 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 880 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
881 if (receiver_class_id() == kSmiCid) { 881 if (operation_cid() == kSmiCid) {
882 // Deoptimizes if both arguments not Smi. 882 // Deoptimizes if both arguments not Smi.
883 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 883 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
884 return; 884 return;
885 } 885 }
886 if (receiver_class_id() == kDoubleCid) { 886 if (operation_cid() == kDoubleCid) {
887 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 887 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
888 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 888 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
889 return; 889 return;
890 } 890 }
891 if (IsCheckedStrictEqual()) { 891 if (IsCheckedStrictEqual()) {
892 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, 892 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
893 deopt_id()); 893 deopt_id());
894 return; 894 return;
895 } 895 }
896 if (IsPolymorphic()) { 896 if (IsPolymorphic()) {
(...skipping 16 matching lines...) Expand all
913 } 913 }
914 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 914 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
915 __ CompareObject(RAX, Bool::True()); 915 __ CompareObject(RAX, Bool::True());
916 branch->EmitBranchOnCondition(compiler, branch_condition); 916 branch->EmitBranchOnCondition(compiler, branch_condition);
917 } 917 }
918 918
919 919
920 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 920 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
921 const intptr_t kNumInputs = 2; 921 const intptr_t kNumInputs = 2;
922 const intptr_t kNumTemps = 0; 922 const intptr_t kNumTemps = 0;
923 if (operands_class_id() == kDoubleCid) { 923 if (operation_cid() == kDoubleCid) {
924 LocationSummary* summary = 924 LocationSummary* summary =
925 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 925 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
926 summary->set_in(0, Location::RequiresFpuRegister()); 926 summary->set_in(0, Location::RequiresFpuRegister());
927 summary->set_in(1, Location::RequiresFpuRegister()); 927 summary->set_in(1, Location::RequiresFpuRegister());
928 summary->set_out(Location::RequiresRegister()); 928 summary->set_out(Location::RequiresRegister());
929 return summary; 929 return summary;
930 } else if (operands_class_id() == kSmiCid) { 930 } else if (operation_cid() == kSmiCid) {
931 LocationSummary* summary = 931 LocationSummary* summary =
932 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 932 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
933 summary->set_in(0, Location::RegisterOrConstant(left())); 933 summary->set_in(0, Location::RegisterOrConstant(left()));
934 // Only one input can be a constant operand. The case of two constant 934 // Only one input can be a constant operand. The case of two constant
935 // operands should be handled by constant propagation. 935 // operands should be handled by constant propagation.
936 summary->set_in(1, summary->in(0).IsConstant() 936 summary->set_in(1, summary->in(0).IsConstant()
937 ? Location::RequiresRegister() 937 ? Location::RequiresRegister()
938 : Location::RegisterOrConstant(right())); 938 : Location::RegisterOrConstant(right()));
939 summary->set_out(Location::RequiresRegister()); 939 summary->set_out(Location::RequiresRegister());
940 return summary; 940 return summary;
941 } 941 }
942 LocationSummary* locs = 942 LocationSummary* locs =
943 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 943 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
944 // Pick arbitrary fixed input registers because this is a call. 944 // Pick arbitrary fixed input registers because this is a call.
945 locs->set_in(0, Location::RegisterLocation(RAX)); 945 locs->set_in(0, Location::RegisterLocation(RAX));
946 locs->set_in(1, Location::RegisterLocation(RCX)); 946 locs->set_in(1, Location::RegisterLocation(RCX));
947 locs->set_out(Location::RegisterLocation(RAX)); 947 locs->set_out(Location::RegisterLocation(RAX));
948 return locs; 948 return locs;
949 } 949 }
950 950
951 951
952 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 952 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
953 if (operands_class_id() == kSmiCid) { 953 if (operation_cid() == kSmiCid) {
954 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 954 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
955 return; 955 return;
956 } 956 }
957 if (operands_class_id() == kDoubleCid) { 957 if (operation_cid() == kDoubleCid) {
958 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 958 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
959 return; 959 return;
960 } 960 }
961 961
962 // Push arguments for the call. 962 // Push arguments for the call.
963 // TODO(fschneider): Split this instruction into different types to avoid 963 // TODO(fschneider): Split this instruction into different types to avoid
964 // explicitly pushing arguments to the call here. 964 // explicitly pushing arguments to the call here.
965 Register left = locs()->in(0).reg(); 965 Register left = locs()->in(0).reg();
966 Register right = locs()->in(1).reg(); 966 Register right = locs()->in(1).reg();
967 __ pushq(left); 967 __ pushq(left);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 token_pos(), 1017 token_pos(),
1018 kNumArguments, 1018 kNumArguments,
1019 Object::null_array(), // No optional args. 1019 Object::null_array(), // No optional args.
1020 locs(), 1020 locs(),
1021 relational_ic_data); 1021 relational_ic_data);
1022 } 1022 }
1023 1023
1024 1024
1025 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1025 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
1026 BranchInstr* branch) { 1026 BranchInstr* branch) {
1027 if (operands_class_id() == kSmiCid) { 1027 if (operation_cid() == kSmiCid) {
1028 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 1028 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
1029 return; 1029 return;
1030 } 1030 }
1031 if (operands_class_id() == kDoubleCid) { 1031 if (operation_cid() == kDoubleCid) {
1032 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 1032 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
1033 return; 1033 return;
1034 } 1034 }
1035 EmitNativeCode(compiler); 1035 EmitNativeCode(compiler);
1036 __ CompareObject(RAX, Bool::True()); 1036 __ CompareObject(RAX, Bool::True());
1037 branch->EmitBranchOnCondition(compiler, EQUAL); 1037 branch->EmitBranchOnCondition(compiler, EQUAL);
1038 } 1038 }
1039 1039
1040 1040
1041 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 1041 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
(...skipping 3470 matching lines...) Expand 10 before | Expand all | Expand 10 after
4512 PcDescriptors::kOther, 4512 PcDescriptors::kOther,
4513 locs()); 4513 locs());
4514 __ Drop(2); // Discard type arguments and receiver. 4514 __ Drop(2); // Discard type arguments and receiver.
4515 } 4515 }
4516 4516
4517 } // namespace dart 4517 } // namespace dart
4518 4518
4519 #undef __ 4519 #undef __
4520 4520
4521 #endif // defined TARGET_ARCH_X64 4521 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | tests/standalone/double_smi_comparison_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698