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

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

Issue 626223002: Add unboxed Mint for X64 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 default: 366 default:
367 UNREACHABLE(); 367 UNREACHABLE();
368 return OVERFLOW; 368 return OVERFLOW;
369 } 369 }
370 } 370 }
371 371
372 372
373 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Isolate* isolate, 373 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Isolate* isolate,
374 bool opt) const { 374 bool opt) const {
375 const intptr_t kNumInputs = 2; 375 const intptr_t kNumInputs = 2;
376 if (operation_cid() == kMintCid) {
377 const intptr_t kNumTemps = 0;
378 LocationSummary* locs = new(isolate) LocationSummary(
379 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
380 locs->set_in(0, Location::RequiresRegister());
381 locs->set_in(1, Location::RequiresRegister());
382 locs->set_out(0, Location::RequiresRegister());
383 return locs;
384 }
376 if (operation_cid() == kDoubleCid) { 385 if (operation_cid() == kDoubleCid) {
377 const intptr_t kNumTemps = 0; 386 const intptr_t kNumTemps = 0;
378 LocationSummary* locs = new(isolate) LocationSummary( 387 LocationSummary* locs = new(isolate) LocationSummary(
379 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 388 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
380 locs->set_in(0, Location::RequiresFpuRegister()); 389 locs->set_in(0, Location::RequiresFpuRegister());
381 locs->set_in(1, Location::RequiresFpuRegister()); 390 locs->set_in(1, Location::RequiresFpuRegister());
382 locs->set_out(0, Location::RequiresRegister()); 391 locs->set_out(0, Location::RequiresRegister());
383 return locs; 392 return locs;
384 } 393 }
385 if (operation_cid() == kSmiCid) { 394 if (operation_cid() == kSmiCid) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 __ CompareObject(left.reg(), right.constant(), PP); 484 __ CompareObject(left.reg(), right.constant(), PP);
476 } else if (right.IsStackSlot()) { 485 } else if (right.IsStackSlot()) {
477 __ cmpq(left.reg(), right.ToStackSlotAddress()); 486 __ cmpq(left.reg(), right.ToStackSlotAddress());
478 } else { 487 } else {
479 __ cmpq(left.reg(), right.reg()); 488 __ cmpq(left.reg(), right.reg());
480 } 489 }
481 return true_condition; 490 return true_condition;
482 } 491 }
483 492
484 493
494 static Condition TokenKindToMintCondition(Token::Kind kind) {
Vyacheslav Egorov (Google) 2014/10/05 18:46:59 I don't think there is a need to have this duplica
Cutch 2014/10/06 23:55:25 Done.
495 switch (kind) {
496 case Token::kEQ: return EQUAL;
497 case Token::kNE: return NOT_EQUAL;
498 case Token::kLT: return LESS;
499 case Token::kGT: return GREATER;
500 case Token::kLTE: return LESS_EQUAL;
501 case Token::kGTE: return GREATER_EQUAL;
502 default:
503 UNREACHABLE();
504 return OVERFLOW;
505 }
506 }
507
508
509 static Condition EmitMintComparisonOp(FlowGraphCompiler* compiler,
Vyacheslav Egorov (Google) 2014/10/05 18:47:00 This is essentially the same as EmitSmiComparisonO
Cutch 2014/10/06 23:55:25 Done.
510 const LocationSummary& locs,
511 Token::Kind kind,
512 BranchLabels labels) {
513 const Location left = locs.in(0);
514 const Location right = locs.in(1);
515
516 ASSERT(!left.IsConstant() || !right.IsConstant());
517
518 Condition true_condition = TokenKindToMintCondition(kind);
519
520 __ cmpq(left.reg(), right.reg());
521
522 return true_condition;
523 }
524
485 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 525 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
486 switch (kind) { 526 switch (kind) {
487 case Token::kEQ: return EQUAL; 527 case Token::kEQ: return EQUAL;
488 case Token::kNE: return NOT_EQUAL; 528 case Token::kNE: return NOT_EQUAL;
489 case Token::kLT: return BELOW; 529 case Token::kLT: return BELOW;
490 case Token::kGT: return ABOVE; 530 case Token::kGT: return ABOVE;
491 case Token::kLTE: return BELOW_EQUAL; 531 case Token::kLTE: return BELOW_EQUAL;
492 case Token::kGTE: return ABOVE_EQUAL; 532 case Token::kGTE: return ABOVE_EQUAL;
493 default: 533 default:
494 UNREACHABLE(); 534 UNREACHABLE();
(...skipping 16 matching lines...) Expand all
511 ? labels.true_label : labels.false_label; 551 ? labels.true_label : labels.false_label;
512 __ j(PARITY_EVEN, nan_result); 552 __ j(PARITY_EVEN, nan_result);
513 return true_condition; 553 return true_condition;
514 } 554 }
515 555
516 556
517 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 557 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
518 BranchLabels labels) { 558 BranchLabels labels) {
519 if (operation_cid() == kSmiCid) { 559 if (operation_cid() == kSmiCid) {
520 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 560 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
561 } else if (operation_cid() == kMintCid) {
562 return EmitMintComparisonOp(compiler, *locs(), kind(), labels);
521 } else { 563 } else {
522 ASSERT(operation_cid() == kDoubleCid); 564 ASSERT(operation_cid() == kDoubleCid);
523 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 565 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
524 } 566 }
525 } 567 }
526 568
527 569
528 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 570 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
529 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 571 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
530 572
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 bool opt) const { 718 bool opt) const {
677 const intptr_t kNumInputs = 2; 719 const intptr_t kNumInputs = 2;
678 const intptr_t kNumTemps = 0; 720 const intptr_t kNumTemps = 0;
679 if (operation_cid() == kDoubleCid) { 721 if (operation_cid() == kDoubleCid) {
680 LocationSummary* summary = new(isolate) LocationSummary( 722 LocationSummary* summary = new(isolate) LocationSummary(
681 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 723 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
682 summary->set_in(0, Location::RequiresFpuRegister()); 724 summary->set_in(0, Location::RequiresFpuRegister());
683 summary->set_in(1, Location::RequiresFpuRegister()); 725 summary->set_in(1, Location::RequiresFpuRegister());
684 summary->set_out(0, Location::RequiresRegister()); 726 summary->set_out(0, Location::RequiresRegister());
685 return summary; 727 return summary;
728 } else if (operation_cid() == kMintCid) {
729 LocationSummary* summary = new(isolate) LocationSummary(
730 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
731 summary->set_in(0, Location::RequiresRegister());
732 summary->set_in(1, Location::RequiresRegister());
733 summary->set_out(0, Location::RequiresRegister());
734 return summary;
686 } 735 }
687 ASSERT(operation_cid() == kSmiCid); 736 ASSERT(operation_cid() == kSmiCid);
688 LocationSummary* summary = new(isolate) LocationSummary( 737 LocationSummary* summary = new(isolate) LocationSummary(
689 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 738 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
690 summary->set_in(0, Location::RegisterOrConstant(left())); 739 summary->set_in(0, Location::RegisterOrConstant(left()));
691 // Only one input can be a constant operand. The case of two constant 740 // Only one input can be a constant operand. The case of two constant
692 // operands should be handled by constant propagation. 741 // operands should be handled by constant propagation.
693 summary->set_in(1, summary->in(0).IsConstant() 742 summary->set_in(1, summary->in(0).IsConstant()
694 ? Location::RequiresRegister() 743 ? Location::RequiresRegister()
695 : Location::RegisterOrConstant(right())); 744 : Location::RegisterOrConstant(right()));
696 summary->set_out(0, Location::RequiresRegister()); 745 summary->set_out(0, Location::RequiresRegister());
697 return summary; 746 return summary;
698 } 747 }
699 748
700 749
701 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 750 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
702 BranchLabels labels) { 751 BranchLabels labels) {
703 if (operation_cid() == kSmiCid) { 752 if (operation_cid() == kSmiCid) {
704 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 753 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
754 } else if (operation_cid() == kMintCid) {
755 return EmitMintComparisonOp(compiler, *locs(), kind(), labels);
705 } else { 756 } else {
706 ASSERT(operation_cid() == kDoubleCid); 757 ASSERT(operation_cid() == kDoubleCid);
707 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 758 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
708 } 759 }
709 } 760 }
710 761
711 762
712 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 763 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
713 Label is_true, is_false; 764 Label is_true, is_false;
714 BranchLabels labels = { &is_true, &is_false, &is_false }; 765 BranchLabels labels = { &is_true, &is_false, &is_false };
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 case kExternalTypedDataUint8ArrayCid: 992 case kExternalTypedDataUint8ArrayCid:
942 case kExternalTypedDataUint8ClampedArrayCid: 993 case kExternalTypedDataUint8ClampedArrayCid:
943 case kTypedDataInt16ArrayCid: 994 case kTypedDataInt16ArrayCid:
944 case kTypedDataUint16ArrayCid: 995 case kTypedDataUint16ArrayCid:
945 case kOneByteStringCid: 996 case kOneByteStringCid:
946 case kTwoByteStringCid: 997 case kTwoByteStringCid:
947 case kTypedDataInt32ArrayCid: 998 case kTypedDataInt32ArrayCid:
948 case kTypedDataUint32ArrayCid: 999 case kTypedDataUint32ArrayCid:
949 return CompileType::FromCid(kSmiCid); 1000 return CompileType::FromCid(kSmiCid);
950 1001
1002 case kTypedDataInt64ArrayCid:
1003 return CompileType::Int();
1004
951 default: 1005 default:
952 UNIMPLEMENTED(); 1006 UNIMPLEMENTED();
953 return CompileType::Dynamic(); 1007 return CompileType::Dynamic();
954 } 1008 }
955 } 1009 }
956 1010
957 1011
958 Representation LoadIndexedInstr::representation() const { 1012 Representation LoadIndexedInstr::representation() const {
959 switch (class_id_) { 1013 switch (class_id_) {
960 case kArrayCid: 1014 case kArrayCid:
961 case kImmutableArrayCid: 1015 case kImmutableArrayCid:
962 case kTypedDataInt8ArrayCid: 1016 case kTypedDataInt8ArrayCid:
963 case kTypedDataUint8ArrayCid: 1017 case kTypedDataUint8ArrayCid:
964 case kTypedDataUint8ClampedArrayCid: 1018 case kTypedDataUint8ClampedArrayCid:
965 case kExternalTypedDataUint8ArrayCid: 1019 case kExternalTypedDataUint8ArrayCid:
966 case kExternalTypedDataUint8ClampedArrayCid: 1020 case kExternalTypedDataUint8ClampedArrayCid:
967 case kTypedDataInt16ArrayCid: 1021 case kTypedDataInt16ArrayCid:
968 case kTypedDataUint16ArrayCid: 1022 case kTypedDataUint16ArrayCid:
969 case kOneByteStringCid: 1023 case kOneByteStringCid:
970 case kTwoByteStringCid: 1024 case kTwoByteStringCid:
971 case kTypedDataInt32ArrayCid: 1025 case kTypedDataInt32ArrayCid:
972 case kTypedDataUint32ArrayCid: 1026 case kTypedDataUint32ArrayCid:
973 return kTagged; 1027 return kTagged;
1028 case kTypedDataInt64ArrayCid:
1029 return kUnboxedMint;
974 case kTypedDataFloat32ArrayCid: 1030 case kTypedDataFloat32ArrayCid:
975 case kTypedDataFloat64ArrayCid: 1031 case kTypedDataFloat64ArrayCid:
976 return kUnboxedDouble; 1032 return kUnboxedDouble;
977 case kTypedDataInt32x4ArrayCid: 1033 case kTypedDataInt32x4ArrayCid:
978 return kUnboxedInt32x4; 1034 return kUnboxedInt32x4;
979 case kTypedDataFloat32x4ArrayCid: 1035 case kTypedDataFloat32x4ArrayCid:
980 return kUnboxedFloat32x4; 1036 return kUnboxedFloat32x4;
981 case kTypedDataFloat64x2ArrayCid: 1037 case kTypedDataFloat64x2ArrayCid:
982 return kUnboxedFloat64x2; 1038 return kUnboxedFloat64x2;
983 default: 1039 default:
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 __ SmiTag(result); 1135 __ SmiTag(result);
1080 break; 1136 break;
1081 case kTypedDataInt32ArrayCid: 1137 case kTypedDataInt32ArrayCid:
1082 __ movsxd(result, element_address); 1138 __ movsxd(result, element_address);
1083 __ SmiTag(result); 1139 __ SmiTag(result);
1084 break; 1140 break;
1085 case kTypedDataUint32ArrayCid: 1141 case kTypedDataUint32ArrayCid:
1086 __ movl(result, element_address); 1142 __ movl(result, element_address);
1087 __ SmiTag(result); 1143 __ SmiTag(result);
1088 break; 1144 break;
1145 case kTypedDataInt64ArrayCid:
1146 __ movq(result, element_address);
1147 break;
1089 default: 1148 default:
1090 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1149 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1091 __ movq(result, element_address); 1150 __ movq(result, element_address);
1092 break; 1151 break;
1093 } 1152 }
1094 } 1153 }
1095 1154
1096 1155
1097 Representation StoreIndexedInstr::RequiredInputRepresentation( 1156 Representation StoreIndexedInstr::RequiredInputRepresentation(
1098 intptr_t idx) const { 1157 intptr_t idx) const {
1099 if (idx == 0) return kNoRepresentation; 1158 if (idx == 0) return kNoRepresentation;
1100 if (idx == 1) return kTagged; 1159 if (idx == 1) return kTagged;
1101 ASSERT(idx == 2); 1160 ASSERT(idx == 2);
1102 switch (class_id_) { 1161 switch (class_id_) {
1103 case kArrayCid: 1162 case kArrayCid:
1104 case kOneByteStringCid: 1163 case kOneByteStringCid:
1105 case kTypedDataInt8ArrayCid: 1164 case kTypedDataInt8ArrayCid:
1106 case kTypedDataUint8ArrayCid: 1165 case kTypedDataUint8ArrayCid:
1107 case kExternalTypedDataUint8ArrayCid: 1166 case kExternalTypedDataUint8ArrayCid:
1108 case kTypedDataUint8ClampedArrayCid: 1167 case kTypedDataUint8ClampedArrayCid:
1109 case kExternalTypedDataUint8ClampedArrayCid: 1168 case kExternalTypedDataUint8ClampedArrayCid:
1110 case kTypedDataInt16ArrayCid: 1169 case kTypedDataInt16ArrayCid:
1111 case kTypedDataUint16ArrayCid: 1170 case kTypedDataUint16ArrayCid:
1112 return kTagged; 1171 return kTagged;
1113 case kTypedDataInt32ArrayCid: 1172 case kTypedDataInt32ArrayCid:
1114 return kUnboxedInt32; 1173 return kUnboxedInt32;
1115 case kTypedDataUint32ArrayCid: 1174 case kTypedDataUint32ArrayCid:
1116 return kUnboxedUint32; 1175 return kUnboxedUint32;
1176 case kTypedDataInt64ArrayCid:
1177 return kUnboxedMint;
1117 case kTypedDataFloat32ArrayCid: 1178 case kTypedDataFloat32ArrayCid:
1118 case kTypedDataFloat64ArrayCid: 1179 case kTypedDataFloat64ArrayCid:
1119 return kUnboxedDouble; 1180 return kUnboxedDouble;
1120 case kTypedDataFloat32x4ArrayCid: 1181 case kTypedDataFloat32x4ArrayCid:
1121 return kUnboxedFloat32x4; 1182 return kUnboxedFloat32x4;
1122 case kTypedDataInt32x4ArrayCid: 1183 case kTypedDataInt32x4ArrayCid:
1123 return kUnboxedInt32x4; 1184 return kUnboxedInt32x4;
1124 case kTypedDataFloat64x2ArrayCid: 1185 case kTypedDataFloat64x2ArrayCid:
1125 return kUnboxedFloat64x2; 1186 return kUnboxedFloat64x2;
1126 default: 1187 default:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 // RBX, RCX, RDX) instead of using a fixed register. 1225 // RBX, RCX, RDX) instead of using a fixed register.
1165 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); 1226 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
1166 break; 1227 break;
1167 case kTypedDataInt16ArrayCid: 1228 case kTypedDataInt16ArrayCid:
1168 case kTypedDataUint16ArrayCid: 1229 case kTypedDataUint16ArrayCid:
1169 case kTypedDataInt32ArrayCid: 1230 case kTypedDataInt32ArrayCid:
1170 case kTypedDataUint32ArrayCid: 1231 case kTypedDataUint32ArrayCid:
1171 // Writable register because the value must be untagged before storing. 1232 // Writable register because the value must be untagged before storing.
1172 locs->set_in(2, Location::WritableRegister()); 1233 locs->set_in(2, Location::WritableRegister());
1173 break; 1234 break;
1235 case kTypedDataInt64ArrayCid:
1236 locs->set_in(2, Location::RequiresRegister());
1237 break;
1174 case kTypedDataFloat32ArrayCid: 1238 case kTypedDataFloat32ArrayCid:
1175 case kTypedDataFloat64ArrayCid: 1239 case kTypedDataFloat64ArrayCid:
1176 // TODO(srdjan): Support Float64 constants. 1240 // TODO(srdjan): Support Float64 constants.
1177 locs->set_in(2, Location::RequiresFpuRegister()); 1241 locs->set_in(2, Location::RequiresFpuRegister());
1178 break; 1242 break;
1179 case kTypedDataInt32x4ArrayCid: 1243 case kTypedDataInt32x4ArrayCid:
1180 case kTypedDataFloat64x2ArrayCid: 1244 case kTypedDataFloat64x2ArrayCid:
1181 case kTypedDataFloat32x4ArrayCid: 1245 case kTypedDataFloat32x4ArrayCid:
1182 locs->set_in(2, Location::RequiresFpuRegister()); 1246 locs->set_in(2, Location::RequiresFpuRegister());
1183 break; 1247 break;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 case kTypedDataUint16ArrayCid: { 1329 case kTypedDataUint16ArrayCid: {
1266 Register value = locs()->in(2).reg(); 1330 Register value = locs()->in(2).reg();
1267 __ SmiUntag(value); 1331 __ SmiUntag(value);
1268 __ movw(element_address, value); 1332 __ movw(element_address, value);
1269 break; 1333 break;
1270 } 1334 }
1271 case kTypedDataInt32ArrayCid: 1335 case kTypedDataInt32ArrayCid:
1272 case kTypedDataUint32ArrayCid: { 1336 case kTypedDataUint32ArrayCid: {
1273 Register value = locs()->in(2).reg(); 1337 Register value = locs()->in(2).reg();
1274 __ movl(element_address, value); 1338 __ movl(element_address, value);
1275 break; 1339 break;
1340 }
1341 case kTypedDataInt64ArrayCid: {
1342 Register value = locs()->in(2).reg();
1343 __ movq(element_address, value);
1344 break;
1276 } 1345 }
1277 case kTypedDataFloat32ArrayCid: 1346 case kTypedDataFloat32ArrayCid:
1278 __ movss(element_address, locs()->in(2).fpu_reg()); 1347 __ movss(element_address, locs()->in(2).fpu_reg());
1279 break; 1348 break;
1280 case kTypedDataFloat64ArrayCid: 1349 case kTypedDataFloat64ArrayCid:
1281 __ movsd(element_address, locs()->in(2).fpu_reg()); 1350 __ movsd(element_address, locs()->in(2).fpu_reg());
1282 break; 1351 break;
1283 case kTypedDataInt32x4ArrayCid: 1352 case kTypedDataInt32x4ArrayCid:
1284 case kTypedDataFloat64x2ArrayCid: 1353 case kTypedDataFloat64x2ArrayCid:
1285 case kTypedDataFloat32x4ArrayCid: 1354 case kTypedDataFloat32x4ArrayCid:
(...skipping 4147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5433 Register length = length_loc.reg(); 5502 Register length = length_loc.reg();
5434 Register index = index_loc.reg(); 5503 Register index = index_loc.reg();
5435 __ cmpq(index, length); 5504 __ cmpq(index, length);
5436 __ j(ABOVE_EQUAL, deopt); 5505 __ j(ABOVE_EQUAL, deopt);
5437 } 5506 }
5438 } 5507 }
5439 5508
5440 5509
5441 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5510 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5442 bool opt) const { 5511 bool opt) const {
5443 UNIMPLEMENTED(); 5512 const intptr_t kNumInputs = 1;
5444 return NULL; 5513 const intptr_t kNumTemps = 0;
5514 LocationSummary* locs = new(isolate) LocationSummary(
5515 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5516 locs->set_in(0, Location::RequiresRegister());
5517 locs->set_out(0, Location::RequiresRegister());
5518 return locs;
5445 } 5519 }
5446 5520
5447 5521
5448 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5522 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5449 UNIMPLEMENTED(); 5523 const intptr_t value_cid = value()->Type()->ToCid();
5524 const Register value = locs()->in(0).reg();
5525 const Register result = locs()->out(0).reg();
5526
5527 if (value_cid == kMintCid) {
5528 __ movq(result, FieldAddress(value, Mint::value_offset()));
5529 } else if (value_cid == kSmiCid) {
5530 __ movq(result, value);
5531 __ SmiUntag(result);
5532 } else {
5533 Label* deopt = compiler->AddDeoptStub(deopt_id_,
5534 ICData::kDeoptUnboxInteger);
5535 Label is_smi, done;
5536 __ testq(value, Immediate(kSmiTagMask));
Vyacheslav Egorov (Google) 2014/10/05 18:46:59 You can produce much smaller instruction sequence
Cutch 2014/10/06 23:55:26 Done.
5537 __ j(ZERO, &is_smi);
5538 __ CompareClassId(value, kMintCid);
5539 __ j(NOT_EQUAL, deopt);
5540 __ movq(result, FieldAddress(value, Mint::value_offset()));
5541 __ jmp(&done);
5542 __ Bind(&is_smi);
5543 __ movq(result, value);
5544 __ SmiUntag(result);
5545 __ Bind(&done);
5546 }
5450 } 5547 }
5451 5548
5452 5549
5453 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5550 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5454 bool opt) const { 5551 bool opt) const {
5455 UNIMPLEMENTED(); 5552 const intptr_t kNumInputs = 1;
5456 return NULL; 5553 const intptr_t kNumTemps = 0;
5554 LocationSummary* summary = new(isolate) LocationSummary(
5555 isolate, kNumInputs, kNumTemps, is_smi()
5556 ? LocationSummary::kNoCall
5557 : LocationSummary::kCallOnSlowPath);
5558 summary->set_in(0, Location::RequiresRegister());
5559 summary->set_out(0, Location::RequiresRegister());
5560 return summary;
5457 } 5561 }
5458 5562
5459 5563
5460 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5564 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5461 UNIMPLEMENTED(); 5565 const Register out = locs()->out(0).reg();
5566 const Register value = locs()->in(0).reg();
5567
5568 if (is_smi()) {
5569 __ movq(out, value);
5570 __ SmiTag(out);
5571 return;
5572 }
5573
5574 Label is_smi;
5575 Label done;
5576 // Tag, Untag, and then compare with original value.
5577 __ movq(out, value);
5578 __ SmiTag(out);
5579 __ SmiUntag(out);
Vyacheslav Egorov (Google) 2014/10/05 18:46:59 __ movq(out, value); __ SmiTag(out); // shrl set
Cutch 2014/10/06 23:55:25 Done.
5580 __ cmpq(out, value);
5581 __ j(EQUAL, &is_smi);
5582 BoxAllocationSlowPath::Allocate(
5583 compiler, this, compiler->mint_class(), out);
5584 __ movq(FieldAddress(out, Mint::value_offset()), value);
5585 __ jmp(&done);
5586 __ Bind(&is_smi);
5587 __ movq(out, value);
5588 __ SmiTag(out);
5589 __ Bind(&done);
5462 } 5590 }
5463 5591
5464 5592
5465 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5593 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5466 bool opt) const { 5594 bool opt) const {
5467 UNIMPLEMENTED(); 5595 const intptr_t kNumInputs = 2;
5468 return NULL; 5596 const intptr_t kNumTemps = 0;
5597 LocationSummary* summary = new(isolate) LocationSummary(
5598 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5599 summary->set_in(0, Location::RequiresRegister());
5600 summary->set_in(1, Location::RequiresRegister());
5601 summary->set_out(0, Location::SameAsFirstInput());
5602 return summary;
5469 } 5603 }
5470 5604
5471 5605
5472 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5606 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5473 UNIMPLEMENTED(); 5607 const Register left = locs()->in(0).reg();
5608 const Register right = locs()->in(1).reg();
5609 const Register out = locs()->out(0).reg();
5610
5611 ASSERT(out == left);
5612
5613 Label* deopt = NULL;
5614 if (CanDeoptimize()) {
5615 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5616 }
5617
5618 switch (op_kind()) {
Vyacheslav Egorov (Google) 2014/10/05 18:46:59 use EmitIntegerArithmetic
Cutch 2014/10/06 23:55:25 EmitIntegerArithmetic does 32-bit operations, thes
Vyacheslav Egorov (Google) 2014/10/07 12:03:50 Ack, true, shame on me! I was dwelling in ia32-t
Cutch 2014/10/21 17:42:11 Done.
5619 case Token::kBIT_AND:
5620 __ andq(left, right);
5621 break;
5622 case Token::kBIT_OR:
5623 __ orq(left, right);
5624 break;
5625 case Token::kBIT_XOR:
5626 __ xorq(left, right);
5627 break;
5628 case Token::kADD:
5629 case Token::kSUB: {
5630 if (op_kind() == Token::kADD) {
5631 __ addq(left, right);
5632 } else {
5633 __ subq(left, right);
5634 }
5635 if (can_overflow()) {
5636 ASSERT(deopt != NULL);
5637 __ j(OVERFLOW, deopt);
5638 }
5639 break;
5640 }
5641 case Token::kMUL:
5642 __ imulq(left, right);
5643 ASSERT(deopt != NULL);
5644 __ j(OVERFLOW, deopt);
5645 break;
5646 default:
5647 UNREACHABLE();
5648 break;
5649 }
5650 if (FLAG_throw_on_javascript_int_overflow) {
5651 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5652 }
5474 } 5653 }
5475 5654
5476 5655
5477 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5656 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5478 bool opt) const { 5657 bool opt) const {
5479 UNIMPLEMENTED(); 5658 const intptr_t kNumInputs = 1;
5480 return NULL; 5659 const intptr_t kNumTemps = 0;
5660 LocationSummary* summary = new(isolate) LocationSummary(
5661 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5662 summary->set_in(0, Location::RequiresRegister());
5663 summary->set_out(0, Location::SameAsFirstInput());
5664 return summary;
5481 } 5665 }
5482 5666
5483 5667
5484 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5668 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5485 UNIMPLEMENTED(); 5669 ASSERT(op_kind() == Token::kBIT_NOT);
5486 } 5670 const Register left = locs()->in(0).reg();
5487 5671 const Register out = locs()->out(0).reg();
5672 ASSERT(out == left);
5673
5674 Label* deopt = NULL;
5675 if (FLAG_throw_on_javascript_int_overflow) {
5676 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
5677 }
5678
5679 __ notq(left);
5680
5681 if (FLAG_throw_on_javascript_int_overflow) {
5682 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5683 }
5684 }
5685
5686
5687 static const intptr_t kMintShiftCountLimit = 63;
5488 5688
5489 bool ShiftMintOpInstr::has_shift_count_check() const { 5689 bool ShiftMintOpInstr::has_shift_count_check() const {
5490 UNREACHABLE(); 5690 return !RangeUtils::IsWithin(
5491 return false; 5691 right()->definition()->range(), 0, kMintShiftCountLimit);
5492 } 5692 }
5493 5693
5494 5694
5495 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 5695 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5496 bool opt) const { 5696 bool opt) const {
5497 UNIMPLEMENTED(); 5697 const intptr_t kNumInputs = 2;
5498 return NULL; 5698 const intptr_t kNumTemps = can_overflow() ? 1 : 0;
5699 LocationSummary* summary = new(isolate) LocationSummary(
5700 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5701 summary->set_in(0, Location::RequiresRegister());
5702 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
5703 if (kNumTemps > 0) {
5704 summary->set_temp(0, Location::RequiresRegister());
5705 }
5706 summary->set_out(0, Location::SameAsFirstInput());
5707 return summary;
5499 } 5708 }
5500 5709
5501 5710
5502 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5711 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5503 UNIMPLEMENTED(); 5712 const Register left = locs()->in(0).reg();
5504 } 5713 const Register out = locs()->out(0).reg();
5505 5714 ASSERT(left == out);
5506 5715
5716 Label* deopt = NULL;
5717 if (CanDeoptimize()) {
5718 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5719 }
5720 if (locs()->in(1).IsConstant()) {
5721 // Code for a constant shift amount.
5722 ASSERT(locs()->in(1).constant().IsSmi());
5723 const int64_t shift =
5724 reinterpret_cast<int64_t>(locs()->in(1).constant().raw()) >> 1;
5725 if ((shift < 0) || (shift > kMintShiftCountLimit)) {
Vyacheslav Egorov (Google) 2014/10/05 18:47:00 These cases should be handled in the Canonicalize
Cutch 2014/10/06 23:55:26 Done.
5726 __ jmp(deopt);
5727 return;
5728 } else if (shift == 0) {
5729 // Nothing to do for zero shift amount.
5730 return;
5731 }
5732 switch (op_kind()) {
5733 case Token::kSHR:
5734 __ sarq(left, Immediate(shift));
5735 break;
5736 case Token::kSHL: {
5737 if (can_overflow()) {
5738 // Check for overflow.
5739 Register temp = locs()->temp(0).reg();
5740 __ movq(temp, left);
5741 __ shlq(left, Immediate(shift));
5742 __ sarq(left, Immediate(shift));
5743 __ cmpq(left, temp);
5744 __ j(NOT_EQUAL, deopt); // Overflow.
5745 }
5746 // Shift for result now we know there is no overflow.
5747 __ shlq(left, Immediate(shift));
5748 break;
5749 }
5750 default:
5751 UNREACHABLE();
5752 }
5753 } else {
5754 // Code for a variable shift amount.
5755 // Deoptimize if shift count is > 63.
5756 // sarl operation masks the count to 5 bits and
5757 // shrd is undefined with count > operand size (32)
5758 __ SmiUntag(RCX);
5759 if (has_shift_count_check()) {
5760 __ cmpq(RCX, Immediate(kMintShiftCountLimit));
5761 __ j(ABOVE, deopt);
5762 }
5763 Label done, large_shift;
5764 switch (op_kind()) {
5765 case Token::kSHR: {
5766 __ sarq(left, RCX);
5767 break;
5768 }
5769 case Token::kSHL: {
5770 if (can_overflow()) {
5771 // Check for overflow.
5772 Register temp = locs()->temp(0).reg();
5773 __ movq(temp, left);
5774 __ shlq(left, RCX);
5775 __ sarq(left, RCX);
5776 __ cmpq(left, temp);
5777 __ j(NOT_EQUAL, deopt); // Overflow.
5778 }
5779 // Shift for result now we know there is no overflow.
5780 __ shlq(left, RCX);
5781 break;
5782 }
5783 default:
5784 UNREACHABLE();
5785 }
5786 }
5787 if (FLAG_throw_on_javascript_int_overflow) {
5788 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5789 }
5790 }
5791
5792
5507 CompileType BinaryUint32OpInstr::ComputeType() const { 5793 CompileType BinaryUint32OpInstr::ComputeType() const {
5508 return CompileType::FromCid(kSmiCid); 5794 return CompileType::FromCid(kSmiCid);
5509 } 5795 }
5510 5796
5511 5797
5512 CompileType ShiftUint32OpInstr::ComputeType() const { 5798 CompileType ShiftUint32OpInstr::ComputeType() const {
5513 return CompileType::FromCid(kSmiCid); 5799 return CompileType::FromCid(kSmiCid);
5514 } 5800 }
5515 5801
5516 5802
5517 CompileType UnaryUint32OpInstr::ComputeType() const { 5803 CompileType UnaryUint32OpInstr::ComputeType() const {
5518 return CompileType::FromCid(kSmiCid); 5804 return CompileType::FromCid(kSmiCid);
5519 } 5805 }
5520 5806
5521 5807
5522 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) 5808 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5523 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) 5809 bool opt) const {
5524 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) 5810 const intptr_t kNumInputs = 2;
5811 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
5812 LocationSummary* summary = new(isolate) LocationSummary(
5813 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5814 summary->set_in(0, Location::RequiresRegister());
5815 summary->set_in(1, Location::RequiresRegister());
5816 summary->set_out(0, Location::SameAsFirstInput());
5817 return summary;
5818 }
5819
5820
5821 template<typename OperandType>
5822 static void EmitIntegerArithmetic(FlowGraphCompiler* compiler,
5823 Token::Kind op_kind,
5824 Register left,
5825 const OperandType& right,
5826 Label* deopt) {
5827 switch (op_kind) {
5828 case Token::kADD:
5829 __ addl(left, right);
5830 break;
5831 case Token::kSUB:
5832 __ subl(left, right);
5833 break;
5834 case Token::kBIT_AND:
5835 __ andl(left, right);
5836 break;
5837 case Token::kBIT_OR:
5838 __ orl(left, right);
5839 break;
5840 case Token::kBIT_XOR:
5841 __ xorl(left, right);
5842 break;
5843 case Token::kMUL:
5844 __ imull(left, right);
5845 break;
5846 default:
5847 UNREACHABLE();
5848 }
5849 if (deopt != NULL) __ j(OVERFLOW, deopt);
5850 }
5851
5852
5853 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5854 Register left = locs()->in(0).reg();
5855 Register right = locs()->in(1).reg();
5856 Register out = locs()->out(0).reg();
5857 ASSERT(out == left);
5858 switch (op_kind()) {
5859 case Token::kBIT_AND:
5860 case Token::kBIT_OR:
5861 case Token::kBIT_XOR:
5862 case Token::kADD:
5863 case Token::kSUB:
5864 case Token::kMUL:
5865 EmitIntegerArithmetic(compiler, op_kind(), left, right, NULL);
5866 return;
5867 default:
5868 UNREACHABLE();
5869 }
5870 }
5871
5872
5873 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5874 bool opt) const {
5875 const intptr_t kNumInputs = 2;
5876 const intptr_t kNumTemps = 0;
5877 LocationSummary* summary = new(isolate) LocationSummary(
5878 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5879 summary->set_in(0, Location::RequiresRegister());
5880 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
5881 summary->set_out(0, Location::SameAsFirstInput());
5882 return summary;
5883 }
5884
5885
5886 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5887 const intptr_t kShifterLimit = 31;
5888
5889 Register left = locs()->in(0).reg();
5890 Register out = locs()->out(0).reg();
5891 ASSERT(left == out);
5892
5893
5894 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5895
5896 if (locs()->in(1).IsConstant()) {
5897 // Shifter is constant.
5898
5899 const Object& constant = locs()->in(1).constant();
5900 ASSERT(constant.IsSmi());
5901 const intptr_t shift_value = Smi::Cast(constant).Value();
5902
5903 // Check constant shift value.
5904 if (shift_value == 0) {
Vyacheslav Egorov (Google) 2014/10/05 18:46:59 Should be handled in the Canonicalize
Cutch 2014/10/06 23:55:25 Done.
5905 // Nothing to do.
5906 } else if (shift_value < 0) {
5907 // Invalid shift value.
5908 __ jmp(deopt);
5909 } else if (shift_value > kShifterLimit) {
5910 // Result is 0.
5911 __ xorq(left, left);
5912 } else {
5913 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
5914 switch (op_kind()) {
5915 case Token::kSHR:
5916 __ shrl(left, Immediate(shift_value));
5917 break;
5918 case Token::kSHL:
5919 __ shll(left, Immediate(shift_value));
5920 break;
5921 default:
5922 UNREACHABLE();
5923 }
5924 }
5925 return;
5926 }
5927
5928 // Non constant shift value.
5929
5930 Register shifter = locs()->in(1).reg();
5931 ASSERT(shifter == RCX);
5932
5933 Label done;
5934 Label zero;
5935
5936 // TODO(johnmccutchan): Use range information to avoid these checks.
5937 __ SmiUntag(shifter);
5938 __ cmpq(shifter, Immediate(0));
5939 // If shift value is < 0, deoptimize.
5940 __ j(NEGATIVE, deopt);
5941 __ cmpq(shifter, Immediate(kShifterLimit));
5942 // If shift value is >= 32, return zero.
5943 __ j(ABOVE, &zero);
5944
5945 // Do the shift.
5946 switch (op_kind()) {
5947 case Token::kSHR:
5948 __ shrl(left, shifter);
5949 __ jmp(&done);
5950 break;
5951 case Token::kSHL:
5952 __ shll(left, shifter);
5953 __ jmp(&done);
5954 break;
5955 default:
5956 UNREACHABLE();
5957 }
5958
5959 __ Bind(&zero);
5960 // Shift was greater than 31 bits, just return zero.
5961 __ xorq(left, left);
5962
5963 // Exit path.
5964 __ Bind(&done);
5965 }
5966
5967
5968 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5969 bool opt) const {
5970 const intptr_t kNumInputs = 1;
5971 const intptr_t kNumTemps = 0;
5972 LocationSummary* summary = new(isolate) LocationSummary(
5973 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5974 summary->set_in(0, Location::RequiresRegister());
5975 summary->set_out(0, Location::SameAsFirstInput());
5976 return summary;
5977 }
5978
5979
5980 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5981 Register out = locs()->out(0).reg();
5982 ASSERT(locs()->in(0).reg() == out);
5983
5984 ASSERT(op_kind() == Token::kBIT_NOT);
5985
5986 __ notl(out);
5987 }
5988
5989
5525 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5990 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5526 5991
5527 5992
5528 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, 5993 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
5529 bool opt) const { 5994 bool opt) const {
5530 const intptr_t kNumInputs = 1; 5995 const intptr_t kNumInputs = 1;
5531 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0; 5996 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
5532 LocationSummary* summary = new(isolate) LocationSummary( 5997 LocationSummary* summary = new(isolate) LocationSummary(
5533 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5998 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5534 summary->set_in(0, Location::RequiresRegister()); 5999 summary->set_in(0, Location::RequiresRegister());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
5606 } 6071 }
5607 6072
5608 6073
5609 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, 6074 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
5610 bool opt) const { 6075 bool opt) const {
5611 const intptr_t kNumInputs = 1; 6076 const intptr_t kNumInputs = 1;
5612 const intptr_t kNumTemps = 0; 6077 const intptr_t kNumTemps = 0;
5613 LocationSummary* summary = new(isolate) LocationSummary( 6078 LocationSummary* summary = new(isolate) LocationSummary(
5614 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6079 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5615 if (from() == kUnboxedMint) { 6080 if (from() == kUnboxedMint) {
5616 UNREACHABLE(); 6081 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6082 summary->set_in(0, Location::RequiresRegister());
6083 summary->set_out(0, Location::SameAsFirstInput());
5617 } else if (to() == kUnboxedMint) { 6084 } else if (to() == kUnboxedMint) {
5618 UNREACHABLE(); 6085 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedUint32));
6086 summary->set_in(0, Location::RequiresRegister());
6087 summary->set_out(0, Location::SameAsFirstInput());
5619 } else { 6088 } else {
5620 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); 6089 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
5621 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 6090 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5622 summary->set_in(0, Location::RequiresRegister()); 6091 summary->set_in(0, Location::RequiresRegister());
5623 summary->set_out(0, Location::SameAsFirstInput()); 6092 summary->set_out(0, Location::SameAsFirstInput());
5624 } 6093 }
5625 return summary; 6094 return summary;
5626 } 6095 }
5627 6096
5628 6097
(...skipping 11 matching lines...) Expand all
5640 const Register value = locs()->in(0).reg(); 6109 const Register value = locs()->in(0).reg();
5641 const Register out = locs()->out(0).reg(); 6110 const Register out = locs()->out(0).reg();
5642 __ movsxd(out, value); 6111 __ movsxd(out, value);
5643 if (CanDeoptimize()) { 6112 if (CanDeoptimize()) {
5644 Label* deopt = 6113 Label* deopt =
5645 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); 6114 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
5646 __ testl(out, out); 6115 __ testl(out, out);
5647 __ j(NEGATIVE, deopt); 6116 __ j(NEGATIVE, deopt);
5648 } 6117 }
5649 } else if (from() == kUnboxedMint) { 6118 } else if (from() == kUnboxedMint) {
5650 UNREACHABLE(); 6119 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6120 const Register value = locs()->in(0).reg();
6121 const Register out = locs()->out(0).reg();
6122 // Copy low.
6123 __ movl(out, value);
6124 if (CanDeoptimize()) {
6125 Label* deopt =
6126 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
6127 // Sign extend.
6128 __ movsxd(out, out);
Vyacheslav Egorov (Google) 2014/10/05 18:47:00 you could do __ movsxd(out, value) to begin with.
Cutch 2014/10/06 23:55:26 Done.
6129 // Compare with original value.
6130 __ cmpq(out, value);
6131 // Value cannot be held in Int32, deopt.
6132 __ j(NOT_EQUAL, deopt);
6133 }
5651 } else if (to() == kUnboxedMint) { 6134 } else if (to() == kUnboxedMint) {
5652 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 6135 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5653 UNREACHABLE(); 6136 const Register value = locs()->in(0).reg();
6137 const Register out = locs()->out(0).reg();
6138 if (from() == kUnboxedUint32) {
6139 // Zero extend.
6140 __ movl(out, value);
6141 } else {
6142 // Sign extend.
6143 ASSERT(from() == kUnboxedInt32);
6144 __ movsxd(out, value);
6145 }
5654 } else { 6146 } else {
5655 UNREACHABLE(); 6147 UNREACHABLE();
5656 } 6148 }
5657 } 6149 }
5658 6150
5659 6151
5660 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6152 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
5661 bool opt) const { 6153 bool opt) const {
5662 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6154 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
5663 } 6155 }
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
5927 __ movq(R10, Immediate(kInvalidObjectPointer)); 6419 __ movq(R10, Immediate(kInvalidObjectPointer));
5928 __ movq(RBX, Immediate(kInvalidObjectPointer)); 6420 __ movq(RBX, Immediate(kInvalidObjectPointer));
5929 #endif 6421 #endif
5930 } 6422 }
5931 6423
5932 } // namespace dart 6424 } // namespace dart
5933 6425
5934 #undef __ 6426 #undef __
5935 6427
5936 #endif // defined TARGET_ARCH_X64 6428 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698