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

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
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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 348
349 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 349 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
350 Register obj = locs()->in(0).reg(); 350 Register obj = locs()->in(0).reg();
351 Register result = locs()->out(0).reg(); 351 Register result = locs()->out(0).reg();
352 352
353 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 353 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
354 ASSERT(obj == result); 354 ASSERT(obj == result);
355 } 355 }
356 356
357 357
358 static Condition TokenKindToSmiCondition(Token::Kind kind) { 358 static Condition TokenKindToIntCondition(Token::Kind kind) {
359 switch (kind) { 359 switch (kind) {
360 case Token::kEQ: return EQUAL; 360 case Token::kEQ: return EQUAL;
361 case Token::kNE: return NOT_EQUAL; 361 case Token::kNE: return NOT_EQUAL;
362 case Token::kLT: return LESS; 362 case Token::kLT: return LESS;
363 case Token::kGT: return GREATER; 363 case Token::kGT: return GREATER;
364 case Token::kLTE: return LESS_EQUAL; 364 case Token::kLTE: return LESS_EQUAL;
365 case Token::kGTE: return GREATER_EQUAL; 365 case Token::kGTE: return GREATER_EQUAL;
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 __ j(false_condition, labels.false_label); 460 __ j(false_condition, labels.false_label);
452 461
453 // Fall through or jump to the true successor. 462 // Fall through or jump to the true successor.
454 if (labels.fall_through != labels.true_label) { 463 if (labels.fall_through != labels.true_label) {
455 __ jmp(labels.true_label); 464 __ jmp(labels.true_label);
456 } 465 }
457 } 466 }
458 } 467 }
459 468
460 469
461 static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler, 470 static Condition EmitIntComparisonOp(FlowGraphCompiler* compiler,
Vyacheslav Egorov (Google) 2014/10/07 12:03:50 Maybe it's better to call it Int64ComparisonOp to
462 const LocationSummary& locs, 471 const LocationSummary& locs,
463 Token::Kind kind, 472 Token::Kind kind,
464 BranchLabels labels) { 473 BranchLabels labels) {
465 Location left = locs.in(0); 474 Location left = locs.in(0);
466 Location right = locs.in(1); 475 Location right = locs.in(1);
467 ASSERT(!left.IsConstant() || !right.IsConstant()); 476 ASSERT(!left.IsConstant() || !right.IsConstant());
468 477
469 Condition true_condition = TokenKindToSmiCondition(kind); 478 Condition true_condition = TokenKindToIntCondition(kind);
470 479
471 if (left.IsConstant()) { 480 if (left.IsConstant()) {
472 __ CompareObject(right.reg(), left.constant(), PP); 481 __ CompareObject(right.reg(), left.constant(), PP);
473 true_condition = FlipCondition(true_condition); 482 true_condition = FlipCondition(true_condition);
474 } else if (right.IsConstant()) { 483 } else if (right.IsConstant()) {
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());
(...skipping 29 matching lines...) Expand all
509 Condition true_condition = TokenKindToDoubleCondition(kind); 518 Condition true_condition = TokenKindToDoubleCondition(kind);
510 Label* nan_result = (true_condition == NOT_EQUAL) 519 Label* nan_result = (true_condition == NOT_EQUAL)
511 ? labels.true_label : labels.false_label; 520 ? labels.true_label : labels.false_label;
512 __ j(PARITY_EVEN, nan_result); 521 __ j(PARITY_EVEN, nan_result);
513 return true_condition; 522 return true_condition;
514 } 523 }
515 524
516 525
517 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 526 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
518 BranchLabels labels) { 527 BranchLabels labels) {
519 if (operation_cid() == kSmiCid) { 528 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
520 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 529 return EmitIntComparisonOp(compiler, *locs(), kind(), labels);
521 } else { 530 } else {
522 ASSERT(operation_cid() == kDoubleCid); 531 ASSERT(operation_cid() == kDoubleCid);
523 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 532 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
524 } 533 }
525 } 534 }
526 535
527 536
528 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 537 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
529 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 538 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
530 539
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 bool opt) const { 685 bool opt) const {
677 const intptr_t kNumInputs = 2; 686 const intptr_t kNumInputs = 2;
678 const intptr_t kNumTemps = 0; 687 const intptr_t kNumTemps = 0;
679 if (operation_cid() == kDoubleCid) { 688 if (operation_cid() == kDoubleCid) {
680 LocationSummary* summary = new(isolate) LocationSummary( 689 LocationSummary* summary = new(isolate) LocationSummary(
681 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 690 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
682 summary->set_in(0, Location::RequiresFpuRegister()); 691 summary->set_in(0, Location::RequiresFpuRegister());
683 summary->set_in(1, Location::RequiresFpuRegister()); 692 summary->set_in(1, Location::RequiresFpuRegister());
684 summary->set_out(0, Location::RequiresRegister()); 693 summary->set_out(0, Location::RequiresRegister());
685 return summary; 694 return summary;
695 } else if (operation_cid() == kMintCid) {
696 LocationSummary* summary = new(isolate) LocationSummary(
697 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
698 summary->set_in(0, Location::RequiresRegister());
699 summary->set_in(1, Location::RequiresRegister());
700 summary->set_out(0, Location::RequiresRegister());
701 return summary;
686 } 702 }
687 ASSERT(operation_cid() == kSmiCid); 703 ASSERT(operation_cid() == kSmiCid);
688 LocationSummary* summary = new(isolate) LocationSummary( 704 LocationSummary* summary = new(isolate) LocationSummary(
689 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 705 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
690 summary->set_in(0, Location::RegisterOrConstant(left())); 706 summary->set_in(0, Location::RegisterOrConstant(left()));
691 // Only one input can be a constant operand. The case of two constant 707 // Only one input can be a constant operand. The case of two constant
692 // operands should be handled by constant propagation. 708 // operands should be handled by constant propagation.
693 summary->set_in(1, summary->in(0).IsConstant() 709 summary->set_in(1, summary->in(0).IsConstant()
694 ? Location::RequiresRegister() 710 ? Location::RequiresRegister()
695 : Location::RegisterOrConstant(right())); 711 : Location::RegisterOrConstant(right()));
696 summary->set_out(0, Location::RequiresRegister()); 712 summary->set_out(0, Location::RequiresRegister());
697 return summary; 713 return summary;
698 } 714 }
699 715
700 716
701 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 717 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
702 BranchLabels labels) { 718 BranchLabels labels) {
703 if (operation_cid() == kSmiCid) { 719 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
704 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 720 return EmitIntComparisonOp(compiler, *locs(), kind(), labels);
705 } else { 721 } else {
706 ASSERT(operation_cid() == kDoubleCid); 722 ASSERT(operation_cid() == kDoubleCid);
707 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 723 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
708 } 724 }
709 } 725 }
710 726
711 727
712 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 728 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
713 Label is_true, is_false; 729 Label is_true, is_false;
714 BranchLabels labels = { &is_true, &is_false, &is_false }; 730 BranchLabels labels = { &is_true, &is_false, &is_false };
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 case kExternalTypedDataUint8ArrayCid: 957 case kExternalTypedDataUint8ArrayCid:
942 case kExternalTypedDataUint8ClampedArrayCid: 958 case kExternalTypedDataUint8ClampedArrayCid:
943 case kTypedDataInt16ArrayCid: 959 case kTypedDataInt16ArrayCid:
944 case kTypedDataUint16ArrayCid: 960 case kTypedDataUint16ArrayCid:
945 case kOneByteStringCid: 961 case kOneByteStringCid:
946 case kTwoByteStringCid: 962 case kTwoByteStringCid:
947 case kTypedDataInt32ArrayCid: 963 case kTypedDataInt32ArrayCid:
948 case kTypedDataUint32ArrayCid: 964 case kTypedDataUint32ArrayCid:
949 return CompileType::FromCid(kSmiCid); 965 return CompileType::FromCid(kSmiCid);
950 966
967 case kTypedDataInt64ArrayCid:
968 return CompileType::Int();
969
951 default: 970 default:
952 UNIMPLEMENTED(); 971 UNIMPLEMENTED();
953 return CompileType::Dynamic(); 972 return CompileType::Dynamic();
954 } 973 }
955 } 974 }
956 975
957 976
958 Representation LoadIndexedInstr::representation() const { 977 Representation LoadIndexedInstr::representation() const {
959 switch (class_id_) { 978 switch (class_id_) {
960 case kArrayCid: 979 case kArrayCid:
961 case kImmutableArrayCid: 980 case kImmutableArrayCid:
962 case kTypedDataInt8ArrayCid: 981 case kTypedDataInt8ArrayCid:
963 case kTypedDataUint8ArrayCid: 982 case kTypedDataUint8ArrayCid:
964 case kTypedDataUint8ClampedArrayCid: 983 case kTypedDataUint8ClampedArrayCid:
965 case kExternalTypedDataUint8ArrayCid: 984 case kExternalTypedDataUint8ArrayCid:
966 case kExternalTypedDataUint8ClampedArrayCid: 985 case kExternalTypedDataUint8ClampedArrayCid:
967 case kTypedDataInt16ArrayCid: 986 case kTypedDataInt16ArrayCid:
968 case kTypedDataUint16ArrayCid: 987 case kTypedDataUint16ArrayCid:
969 case kOneByteStringCid: 988 case kOneByteStringCid:
970 case kTwoByteStringCid: 989 case kTwoByteStringCid:
971 case kTypedDataInt32ArrayCid: 990 case kTypedDataInt32ArrayCid:
972 case kTypedDataUint32ArrayCid: 991 case kTypedDataUint32ArrayCid:
973 return kTagged; 992 return kTagged;
993 case kTypedDataInt64ArrayCid:
994 return kUnboxedMint;
974 case kTypedDataFloat32ArrayCid: 995 case kTypedDataFloat32ArrayCid:
975 case kTypedDataFloat64ArrayCid: 996 case kTypedDataFloat64ArrayCid:
976 return kUnboxedDouble; 997 return kUnboxedDouble;
977 case kTypedDataInt32x4ArrayCid: 998 case kTypedDataInt32x4ArrayCid:
978 return kUnboxedInt32x4; 999 return kUnboxedInt32x4;
979 case kTypedDataFloat32x4ArrayCid: 1000 case kTypedDataFloat32x4ArrayCid:
980 return kUnboxedFloat32x4; 1001 return kUnboxedFloat32x4;
981 case kTypedDataFloat64x2ArrayCid: 1002 case kTypedDataFloat64x2ArrayCid:
982 return kUnboxedFloat64x2; 1003 return kUnboxedFloat64x2;
983 default: 1004 default:
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 __ SmiTag(result); 1100 __ SmiTag(result);
1080 break; 1101 break;
1081 case kTypedDataInt32ArrayCid: 1102 case kTypedDataInt32ArrayCid:
1082 __ movsxd(result, element_address); 1103 __ movsxd(result, element_address);
1083 __ SmiTag(result); 1104 __ SmiTag(result);
1084 break; 1105 break;
1085 case kTypedDataUint32ArrayCid: 1106 case kTypedDataUint32ArrayCid:
1086 __ movl(result, element_address); 1107 __ movl(result, element_address);
1087 __ SmiTag(result); 1108 __ SmiTag(result);
1088 break; 1109 break;
1110 case kTypedDataInt64ArrayCid:
1111 __ movq(result, element_address);
1112 break;
1089 default: 1113 default:
1090 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1114 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1091 __ movq(result, element_address); 1115 __ movq(result, element_address);
1092 break; 1116 break;
1093 } 1117 }
1094 } 1118 }
1095 1119
1096 1120
1097 Representation StoreIndexedInstr::RequiredInputRepresentation( 1121 Representation StoreIndexedInstr::RequiredInputRepresentation(
1098 intptr_t idx) const { 1122 intptr_t idx) const {
1099 if (idx == 0) return kNoRepresentation; 1123 if (idx == 0) return kNoRepresentation;
1100 if (idx == 1) return kTagged; 1124 if (idx == 1) return kTagged;
1101 ASSERT(idx == 2); 1125 ASSERT(idx == 2);
1102 switch (class_id_) { 1126 switch (class_id_) {
1103 case kArrayCid: 1127 case kArrayCid:
1104 case kOneByteStringCid: 1128 case kOneByteStringCid:
1105 case kTypedDataInt8ArrayCid: 1129 case kTypedDataInt8ArrayCid:
1106 case kTypedDataUint8ArrayCid: 1130 case kTypedDataUint8ArrayCid:
1107 case kExternalTypedDataUint8ArrayCid: 1131 case kExternalTypedDataUint8ArrayCid:
1108 case kTypedDataUint8ClampedArrayCid: 1132 case kTypedDataUint8ClampedArrayCid:
1109 case kExternalTypedDataUint8ClampedArrayCid: 1133 case kExternalTypedDataUint8ClampedArrayCid:
1110 case kTypedDataInt16ArrayCid: 1134 case kTypedDataInt16ArrayCid:
1111 case kTypedDataUint16ArrayCid: 1135 case kTypedDataUint16ArrayCid:
1112 return kTagged; 1136 return kTagged;
1113 case kTypedDataInt32ArrayCid: 1137 case kTypedDataInt32ArrayCid:
1114 return kUnboxedInt32; 1138 return kUnboxedInt32;
1115 case kTypedDataUint32ArrayCid: 1139 case kTypedDataUint32ArrayCid:
1116 return kUnboxedUint32; 1140 return kUnboxedUint32;
1141 case kTypedDataInt64ArrayCid:
1142 return kUnboxedMint;
1117 case kTypedDataFloat32ArrayCid: 1143 case kTypedDataFloat32ArrayCid:
1118 case kTypedDataFloat64ArrayCid: 1144 case kTypedDataFloat64ArrayCid:
1119 return kUnboxedDouble; 1145 return kUnboxedDouble;
1120 case kTypedDataFloat32x4ArrayCid: 1146 case kTypedDataFloat32x4ArrayCid:
1121 return kUnboxedFloat32x4; 1147 return kUnboxedFloat32x4;
1122 case kTypedDataInt32x4ArrayCid: 1148 case kTypedDataInt32x4ArrayCid:
1123 return kUnboxedInt32x4; 1149 return kUnboxedInt32x4;
1124 case kTypedDataFloat64x2ArrayCid: 1150 case kTypedDataFloat64x2ArrayCid:
1125 return kUnboxedFloat64x2; 1151 return kUnboxedFloat64x2;
1126 default: 1152 default:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 // RBX, RCX, RDX) instead of using a fixed register. 1190 // RBX, RCX, RDX) instead of using a fixed register.
1165 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); 1191 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
1166 break; 1192 break;
1167 case kTypedDataInt16ArrayCid: 1193 case kTypedDataInt16ArrayCid:
1168 case kTypedDataUint16ArrayCid: 1194 case kTypedDataUint16ArrayCid:
1169 case kTypedDataInt32ArrayCid: 1195 case kTypedDataInt32ArrayCid:
1170 case kTypedDataUint32ArrayCid: 1196 case kTypedDataUint32ArrayCid:
1171 // Writable register because the value must be untagged before storing. 1197 // Writable register because the value must be untagged before storing.
1172 locs->set_in(2, Location::WritableRegister()); 1198 locs->set_in(2, Location::WritableRegister());
1173 break; 1199 break;
1200 case kTypedDataInt64ArrayCid:
1201 locs->set_in(2, Location::RequiresRegister());
1202 break;
1174 case kTypedDataFloat32ArrayCid: 1203 case kTypedDataFloat32ArrayCid:
1175 case kTypedDataFloat64ArrayCid: 1204 case kTypedDataFloat64ArrayCid:
1176 // TODO(srdjan): Support Float64 constants. 1205 // TODO(srdjan): Support Float64 constants.
1177 locs->set_in(2, Location::RequiresFpuRegister()); 1206 locs->set_in(2, Location::RequiresFpuRegister());
1178 break; 1207 break;
1179 case kTypedDataInt32x4ArrayCid: 1208 case kTypedDataInt32x4ArrayCid:
1180 case kTypedDataFloat64x2ArrayCid: 1209 case kTypedDataFloat64x2ArrayCid:
1181 case kTypedDataFloat32x4ArrayCid: 1210 case kTypedDataFloat32x4ArrayCid:
1182 locs->set_in(2, Location::RequiresFpuRegister()); 1211 locs->set_in(2, Location::RequiresFpuRegister());
1183 break; 1212 break;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 case kTypedDataUint16ArrayCid: { 1294 case kTypedDataUint16ArrayCid: {
1266 Register value = locs()->in(2).reg(); 1295 Register value = locs()->in(2).reg();
1267 __ SmiUntag(value); 1296 __ SmiUntag(value);
1268 __ movw(element_address, value); 1297 __ movw(element_address, value);
1269 break; 1298 break;
1270 } 1299 }
1271 case kTypedDataInt32ArrayCid: 1300 case kTypedDataInt32ArrayCid:
1272 case kTypedDataUint32ArrayCid: { 1301 case kTypedDataUint32ArrayCid: {
1273 Register value = locs()->in(2).reg(); 1302 Register value = locs()->in(2).reg();
1274 __ movl(element_address, value); 1303 __ movl(element_address, value);
1275 break; 1304 break;
1305 }
1306 case kTypedDataInt64ArrayCid: {
1307 Register value = locs()->in(2).reg();
1308 __ movq(element_address, value);
1309 break;
1276 } 1310 }
1277 case kTypedDataFloat32ArrayCid: 1311 case kTypedDataFloat32ArrayCid:
1278 __ movss(element_address, locs()->in(2).fpu_reg()); 1312 __ movss(element_address, locs()->in(2).fpu_reg());
1279 break; 1313 break;
1280 case kTypedDataFloat64ArrayCid: 1314 case kTypedDataFloat64ArrayCid:
1281 __ movsd(element_address, locs()->in(2).fpu_reg()); 1315 __ movsd(element_address, locs()->in(2).fpu_reg());
1282 break; 1316 break;
1283 case kTypedDataInt32x4ArrayCid: 1317 case kTypedDataInt32x4ArrayCid:
1284 case kTypedDataFloat64x2ArrayCid: 1318 case kTypedDataFloat64x2ArrayCid:
1285 case kTypedDataFloat32x4ArrayCid: 1319 case kTypedDataFloat32x4ArrayCid:
(...skipping 4147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5433 Register length = length_loc.reg(); 5467 Register length = length_loc.reg();
5434 Register index = index_loc.reg(); 5468 Register index = index_loc.reg();
5435 __ cmpq(index, length); 5469 __ cmpq(index, length);
5436 __ j(ABOVE_EQUAL, deopt); 5470 __ j(ABOVE_EQUAL, deopt);
5437 } 5471 }
5438 } 5472 }
5439 5473
5440 5474
5441 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5475 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5442 bool opt) const { 5476 bool opt) const {
5443 UNIMPLEMENTED(); 5477 const intptr_t kNumInputs = 1;
5444 return NULL; 5478 const intptr_t kNumTemps = 0;
5479 LocationSummary* locs = new(isolate) LocationSummary(
5480 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5481 locs->set_in(0, Location::RequiresRegister());
5482 locs->set_out(0, Location::SameAsFirstInput());
5483 return locs;
5445 } 5484 }
5446 5485
5447 5486
5448 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5487 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5449 UNIMPLEMENTED(); 5488 const intptr_t value_cid = value()->Type()->ToCid();
5489 const Register value = locs()->in(0).reg();
5490 const Register result = locs()->out(0).reg();
5491 ASSERT(value == result);
5492
5493 if (value_cid == kMintCid) {
5494 __ movq(result, FieldAddress(value, Mint::value_offset()));
5495 } else if (value_cid == kSmiCid) {
5496 __ SmiUntag(result);
5497 } else {
5498 Label* deopt = compiler->AddDeoptStub(deopt_id_,
5499 ICData::kDeoptUnboxInteger);
5500 Label done;
5501 __ SmiUntagOrCheckClass(value, kMintCid, &done);
5502 __ j(NOT_EQUAL, deopt);
5503 // Undo untagging by multiplying value with 2.
5504 __ movq(result, Address(value, TIMES_2, Mint::value_offset()));
5505 __ Bind(&done);
5506 }
5450 } 5507 }
5451 5508
5452 5509
5453 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5510 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5454 bool opt) const { 5511 bool opt) const {
5455 UNIMPLEMENTED(); 5512 const intptr_t kNumInputs = 1;
5456 return NULL; 5513 const intptr_t kNumTemps = 0;
5514 LocationSummary* summary = new(isolate) LocationSummary(
5515 isolate, kNumInputs, kNumTemps, is_smi()
5516 ? LocationSummary::kNoCall
5517 : LocationSummary::kCallOnSlowPath);
5518 summary->set_in(0, Location::RequiresRegister());
5519 summary->set_out(0, Location::RequiresRegister());
5520 return summary;
5457 } 5521 }
5458 5522
5459 5523
5460 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5524 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5461 UNIMPLEMENTED(); 5525 const Register out = locs()->out(0).reg();
5526 const Register value = locs()->in(0).reg();
5527
5528 if (is_smi()) {
5529 __ movq(out, value);
5530 __ SmiTag(out);
5531 return;
5532 }
5533
5534 Label is_smi;
5535 Label done;
5536 __ movq(out, value);
5537 __ SmiTag(out); // shrl sets OF := SF ^ CF on 1 bit shifts
Vyacheslav Egorov (Google) 2014/10/07 12:03:50 I had a typo in this comment, sorry. It's tagging
5538 __ j(NO_OVERFLOW, &done);
5539 BoxAllocationSlowPath::Allocate(
5540 compiler, this, compiler->mint_class(), out);
5541 __ movq(FieldAddress(out, Mint::value_offset()), value);
5542 __ Bind(&done);
5543 }
5544
5545
5546 template<typename OperandType>
5547 static void EmitInt64Arithmetic(FlowGraphCompiler* compiler,
5548 Token::Kind op_kind,
5549 Register left,
5550 const OperandType& right,
5551 Label* deopt) {
5552 switch (op_kind) {
5553 case Token::kADD:
5554 __ addq(left, right);
5555 break;
5556 case Token::kSUB:
5557 __ subq(left, right);
5558 break;
5559 case Token::kBIT_AND:
5560 __ andq(left, right);
5561 break;
5562 case Token::kBIT_OR:
5563 __ orq(left, right);
5564 break;
5565 case Token::kBIT_XOR:
5566 __ xorq(left, right);
5567 break;
5568 case Token::kMUL:
5569 __ imulq(left, right);
5570 break;
5571 default:
5572 UNREACHABLE();
5573 }
5574 if (deopt != NULL) __ j(OVERFLOW, deopt);
5462 } 5575 }
5463 5576
5464 5577
5465 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5578 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5466 bool opt) const { 5579 bool opt) const {
5467 UNIMPLEMENTED(); 5580 const intptr_t kNumInputs = 2;
5468 return NULL; 5581 const intptr_t kNumTemps = 0;
5582 LocationSummary* summary = new(isolate) LocationSummary(
5583 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5584 summary->set_in(0, Location::RequiresRegister());
5585 summary->set_in(1, Location::RequiresRegister());
5586 summary->set_out(0, Location::SameAsFirstInput());
5587 return summary;
5469 } 5588 }
5470 5589
5471 5590
5472 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5591 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5473 UNIMPLEMENTED(); 5592 const Register left = locs()->in(0).reg();
5593 const Register right = locs()->in(1).reg();
5594 const Register out = locs()->out(0).reg();
5595
5596 ASSERT(out == left);
5597
5598 Label* deopt = NULL;
5599 if (CanDeoptimize()) {
5600 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5601 }
5602
5603 EmitInt64Arithmetic(compiler, op_kind(), left, right, deopt);
5604
5605 if (FLAG_throw_on_javascript_int_overflow) {
5606 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5607 }
5474 } 5608 }
5475 5609
5476 5610
5477 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5611 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5478 bool opt) const { 5612 bool opt) const {
5479 UNIMPLEMENTED(); 5613 const intptr_t kNumInputs = 1;
5480 return NULL; 5614 const intptr_t kNumTemps = 0;
5615 LocationSummary* summary = new(isolate) LocationSummary(
5616 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5617 summary->set_in(0, Location::RequiresRegister());
5618 summary->set_out(0, Location::SameAsFirstInput());
5619 return summary;
5481 } 5620 }
5482 5621
5483 5622
5484 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5623 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5485 UNIMPLEMENTED(); 5624 ASSERT(op_kind() == Token::kBIT_NOT);
5486 } 5625 const Register left = locs()->in(0).reg();
5487 5626 const Register out = locs()->out(0).reg();
5627 ASSERT(out == left);
5628
5629 Label* deopt = NULL;
5630 if (FLAG_throw_on_javascript_int_overflow) {
5631 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
5632 }
5633
5634 __ notq(left);
5635
5636 if (FLAG_throw_on_javascript_int_overflow) {
5637 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5638 }
5639 }
5640
5641
5642 static const intptr_t kMintShiftCountLimit = 63;
5488 5643
5489 bool ShiftMintOpInstr::has_shift_count_check() const { 5644 bool ShiftMintOpInstr::has_shift_count_check() const {
5490 UNREACHABLE(); 5645 return !RangeUtils::IsWithin(
5491 return false; 5646 right()->definition()->range(), 0, kMintShiftCountLimit);
5492 } 5647 }
5493 5648
5494 5649
5495 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 5650 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5496 bool opt) const { 5651 bool opt) const {
5497 UNIMPLEMENTED(); 5652 const intptr_t kNumInputs = 2;
5498 return NULL; 5653 const intptr_t kNumTemps = can_overflow() ? 1 : 0;
5654 LocationSummary* summary = new(isolate) LocationSummary(
5655 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5656 summary->set_in(0, Location::RequiresRegister());
5657 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
5658 if (kNumTemps > 0) {
5659 summary->set_temp(0, Location::RequiresRegister());
5660 }
5661 summary->set_out(0, Location::SameAsFirstInput());
5662 return summary;
5499 } 5663 }
5500 5664
5501 5665
5502 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5666 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5503 UNIMPLEMENTED(); 5667 const Register left = locs()->in(0).reg();
5504 } 5668 const Register out = locs()->out(0).reg();
5505 5669 ASSERT(left == out);
5506 5670
5671 Label* deopt = NULL;
5672 if (CanDeoptimize()) {
5673 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5674 }
5675 if (locs()->in(1).IsConstant()) {
5676 // Code for a constant shift amount.
5677 ASSERT(locs()->in(1).constant().IsSmi());
5678 const int64_t shift =
5679 reinterpret_cast<int64_t>(locs()->in(1).constant().raw()) >> 1;
5680 switch (op_kind()) {
5681 case Token::kSHR:
5682 __ sarq(left, Immediate(shift));
5683 break;
5684 case Token::kSHL: {
5685 if (can_overflow()) {
5686 // Check for overflow.
5687 Register temp = locs()->temp(0).reg();
5688 __ movq(temp, left);
5689 __ shlq(left, Immediate(shift));
5690 __ sarq(left, Immediate(shift));
5691 __ cmpq(left, temp);
5692 __ j(NOT_EQUAL, deopt); // Overflow.
5693 }
5694 // Shift for result now we know there is no overflow.
5695 __ shlq(left, Immediate(shift));
5696 break;
5697 }
5698 default:
5699 UNREACHABLE();
5700 }
5701 } else {
5702 // Code for a variable shift amount.
5703 // Deoptimize if shift count is > 63.
5704 // sarl operation masks the count to 5 bits and
5705 // shrd is undefined with count > operand size (32)
5706 __ SmiUntag(RCX);
5707 if (has_shift_count_check()) {
5708 __ cmpq(RCX, Immediate(kMintShiftCountLimit));
5709 __ j(ABOVE, deopt);
5710 }
5711 Label done, large_shift;
5712 switch (op_kind()) {
5713 case Token::kSHR: {
5714 __ sarq(left, RCX);
5715 break;
5716 }
5717 case Token::kSHL: {
5718 if (can_overflow()) {
5719 // Check for overflow.
5720 Register temp = locs()->temp(0).reg();
5721 __ movq(temp, left);
5722 __ shlq(left, RCX);
5723 __ sarq(left, RCX);
5724 __ cmpq(left, temp);
5725 __ j(NOT_EQUAL, deopt); // Overflow.
5726 }
5727 // Shift for result now we know there is no overflow.
5728 __ shlq(left, RCX);
5729 break;
5730 }
5731 default:
5732 UNREACHABLE();
5733 }
5734 }
5735 if (FLAG_throw_on_javascript_int_overflow) {
5736 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5737 }
5738 }
5739
5740
5507 CompileType BinaryUint32OpInstr::ComputeType() const { 5741 CompileType BinaryUint32OpInstr::ComputeType() const {
5508 return CompileType::FromCid(kSmiCid); 5742 return CompileType::FromCid(kSmiCid);
5509 } 5743 }
5510 5744
5511 5745
5512 CompileType ShiftUint32OpInstr::ComputeType() const { 5746 CompileType ShiftUint32OpInstr::ComputeType() const {
5513 return CompileType::FromCid(kSmiCid); 5747 return CompileType::FromCid(kSmiCid);
5514 } 5748 }
5515 5749
5516 5750
5517 CompileType UnaryUint32OpInstr::ComputeType() const { 5751 CompileType UnaryUint32OpInstr::ComputeType() const {
5518 return CompileType::FromCid(kSmiCid); 5752 return CompileType::FromCid(kSmiCid);
5519 } 5753 }
5520 5754
5521 5755
5522 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) 5756 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5523 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) 5757 bool opt) const {
5524 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) 5758 const intptr_t kNumInputs = 2;
5759 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
5760 LocationSummary* summary = new(isolate) LocationSummary(
5761 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5762 summary->set_in(0, Location::RequiresRegister());
5763 summary->set_in(1, Location::RequiresRegister());
5764 summary->set_out(0, Location::SameAsFirstInput());
5765 return summary;
5766 }
5767
5768
5769 template<typename OperandType>
5770 static void EmitIntegerArithmetic(FlowGraphCompiler* compiler,
5771 Token::Kind op_kind,
5772 Register left,
5773 const OperandType& right,
5774 Label* deopt) {
5775 switch (op_kind) {
5776 case Token::kADD:
5777 __ addl(left, right);
5778 break;
5779 case Token::kSUB:
5780 __ subl(left, right);
5781 break;
5782 case Token::kBIT_AND:
5783 __ andl(left, right);
5784 break;
5785 case Token::kBIT_OR:
5786 __ orl(left, right);
5787 break;
5788 case Token::kBIT_XOR:
5789 __ xorl(left, right);
5790 break;
5791 case Token::kMUL:
5792 __ imull(left, right);
5793 break;
5794 default:
5795 UNREACHABLE();
5796 }
5797 if (deopt != NULL) __ j(OVERFLOW, deopt);
5798 }
5799
5800
5801 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5802 Register left = locs()->in(0).reg();
5803 Register right = locs()->in(1).reg();
5804 Register out = locs()->out(0).reg();
5805 ASSERT(out == left);
5806 switch (op_kind()) {
5807 case Token::kBIT_AND:
5808 case Token::kBIT_OR:
5809 case Token::kBIT_XOR:
5810 case Token::kADD:
5811 case Token::kSUB:
5812 case Token::kMUL:
5813 EmitIntegerArithmetic(compiler, op_kind(), left, right, NULL);
5814 return;
5815 default:
5816 UNREACHABLE();
5817 }
5818 }
5819
5820
5821 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5822 bool opt) const {
5823 const intptr_t kNumInputs = 2;
5824 const intptr_t kNumTemps = 0;
5825 LocationSummary* summary = new(isolate) LocationSummary(
5826 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5827 summary->set_in(0, Location::RequiresRegister());
5828 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
5829 summary->set_out(0, Location::SameAsFirstInput());
5830 return summary;
5831 }
5832
5833
5834 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5835 const intptr_t kShifterLimit = 31;
5836
5837 Register left = locs()->in(0).reg();
5838 Register out = locs()->out(0).reg();
5839 ASSERT(left == out);
5840
5841
5842 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5843
5844 if (locs()->in(1).IsConstant()) {
5845 // Shifter is constant.
5846
5847 const Object& constant = locs()->in(1).constant();
5848 ASSERT(constant.IsSmi());
5849 const intptr_t shift_value = Smi::Cast(constant).Value();
5850
5851 // Check constant shift value.
5852 if (shift_value > kShifterLimit) {
Vyacheslav Egorov (Google) 2014/10/07 12:03:50 Is this not handled in Canonicalize?
Cutch 2014/10/21 17:42:11 Done.
5853 // Result is 0.
5854 __ xorq(left, left);
5855 } else {
5856 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
5857 switch (op_kind()) {
5858 case Token::kSHR:
5859 __ shrl(left, Immediate(shift_value));
5860 break;
5861 case Token::kSHL:
5862 __ shll(left, Immediate(shift_value));
5863 break;
5864 default:
5865 UNREACHABLE();
5866 }
5867 }
5868 return;
5869 }
5870
5871 // Non constant shift value.
5872
5873 Register shifter = locs()->in(1).reg();
5874 ASSERT(shifter == RCX);
5875
5876 Label done;
5877 Label zero;
5878
5879 // TODO(johnmccutchan): Use range information to avoid these checks.
5880 __ SmiUntag(shifter);
5881 __ cmpq(shifter, Immediate(0));
5882 // If shift value is < 0, deoptimize.
5883 __ j(NEGATIVE, deopt);
5884 __ cmpq(shifter, Immediate(kShifterLimit));
5885 // If shift value is >= 32, return zero.
5886 __ j(ABOVE, &zero);
5887
5888 // Do the shift.
5889 switch (op_kind()) {
5890 case Token::kSHR:
5891 __ shrl(left, shifter);
5892 __ jmp(&done);
5893 break;
5894 case Token::kSHL:
5895 __ shll(left, shifter);
5896 __ jmp(&done);
5897 break;
5898 default:
5899 UNREACHABLE();
5900 }
5901
5902 __ Bind(&zero);
5903 // Shift was greater than 31 bits, just return zero.
5904 __ xorq(left, left);
5905
5906 // Exit path.
5907 __ Bind(&done);
5908 }
5909
5910
5911 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5912 bool opt) const {
5913 const intptr_t kNumInputs = 1;
5914 const intptr_t kNumTemps = 0;
5915 LocationSummary* summary = new(isolate) LocationSummary(
5916 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5917 summary->set_in(0, Location::RequiresRegister());
5918 summary->set_out(0, Location::SameAsFirstInput());
5919 return summary;
5920 }
5921
5922
5923 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5924 Register out = locs()->out(0).reg();
5925 ASSERT(locs()->in(0).reg() == out);
5926
5927 ASSERT(op_kind() == Token::kBIT_NOT);
5928
5929 __ notl(out);
5930 }
5931
5932
5525 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5933 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5526 5934
5527 5935
5528 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, 5936 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
5529 bool opt) const { 5937 bool opt) const {
5530 const intptr_t kNumInputs = 1; 5938 const intptr_t kNumInputs = 1;
5531 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0; 5939 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
5532 LocationSummary* summary = new(isolate) LocationSummary( 5940 LocationSummary* summary = new(isolate) LocationSummary(
5533 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5941 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5534 summary->set_in(0, Location::RequiresRegister()); 5942 summary->set_in(0, Location::RequiresRegister());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
5606 } 6014 }
5607 6015
5608 6016
5609 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, 6017 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
5610 bool opt) const { 6018 bool opt) const {
5611 const intptr_t kNumInputs = 1; 6019 const intptr_t kNumInputs = 1;
5612 const intptr_t kNumTemps = 0; 6020 const intptr_t kNumTemps = 0;
5613 LocationSummary* summary = new(isolate) LocationSummary( 6021 LocationSummary* summary = new(isolate) LocationSummary(
5614 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6022 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5615 if (from() == kUnboxedMint) { 6023 if (from() == kUnboxedMint) {
5616 UNREACHABLE(); 6024 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6025 summary->set_in(0, Location::RequiresRegister());
6026 summary->set_out(0, Location::SameAsFirstInput());
5617 } else if (to() == kUnboxedMint) { 6027 } else if (to() == kUnboxedMint) {
5618 UNREACHABLE(); 6028 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedUint32));
6029 summary->set_in(0, Location::RequiresRegister());
6030 summary->set_out(0, Location::SameAsFirstInput());
5619 } else { 6031 } else {
5620 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); 6032 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
5621 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 6033 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5622 summary->set_in(0, Location::RequiresRegister()); 6034 summary->set_in(0, Location::RequiresRegister());
5623 summary->set_out(0, Location::SameAsFirstInput()); 6035 summary->set_out(0, Location::SameAsFirstInput());
5624 } 6036 }
5625 return summary; 6037 return summary;
5626 } 6038 }
5627 6039
5628 6040
(...skipping 11 matching lines...) Expand all
5640 const Register value = locs()->in(0).reg(); 6052 const Register value = locs()->in(0).reg();
5641 const Register out = locs()->out(0).reg(); 6053 const Register out = locs()->out(0).reg();
5642 __ movsxd(out, value); 6054 __ movsxd(out, value);
5643 if (CanDeoptimize()) { 6055 if (CanDeoptimize()) {
5644 Label* deopt = 6056 Label* deopt =
5645 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); 6057 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
5646 __ testl(out, out); 6058 __ testl(out, out);
5647 __ j(NEGATIVE, deopt); 6059 __ j(NEGATIVE, deopt);
5648 } 6060 }
5649 } else if (from() == kUnboxedMint) { 6061 } else if (from() == kUnboxedMint) {
5650 UNREACHABLE(); 6062 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6063 const Register value = locs()->in(0).reg();
6064 const Register out = locs()->out(0).reg();
6065 if (!CanDeoptimize()) {
6066 // Copy low.
6067 __ movl(out, value);
6068 } else {
6069 Label* deopt =
6070 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
6071 // Sign extend.
6072 __ movsxd(out, out);
Vyacheslav Egorov (Google) 2014/10/07 12:03:50 __ movsxd(out, value)
Cutch 2014/10/21 17:42:11 Done.
6073 // Compare with original value.
6074 __ cmpq(out, value);
6075 // Value cannot be held in Int32, deopt.
6076 __ j(NOT_EQUAL, deopt);
6077 }
5651 } else if (to() == kUnboxedMint) { 6078 } else if (to() == kUnboxedMint) {
5652 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 6079 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5653 UNREACHABLE(); 6080 const Register value = locs()->in(0).reg();
6081 const Register out = locs()->out(0).reg();
6082 if (from() == kUnboxedUint32) {
6083 // Zero extend.
6084 __ movl(out, value);
6085 } else {
6086 // Sign extend.
6087 ASSERT(from() == kUnboxedInt32);
6088 __ movsxd(out, value);
6089 }
5654 } else { 6090 } else {
5655 UNREACHABLE(); 6091 UNREACHABLE();
5656 } 6092 }
5657 } 6093 }
5658 6094
5659 6095
5660 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6096 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
5661 bool opt) const { 6097 bool opt) const {
5662 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6098 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
5663 } 6099 }
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
5927 __ movq(R10, Immediate(kInvalidObjectPointer)); 6363 __ movq(R10, Immediate(kInvalidObjectPointer));
5928 __ movq(RBX, Immediate(kInvalidObjectPointer)); 6364 __ movq(RBX, Immediate(kInvalidObjectPointer));
5929 #endif 6365 #endif
5930 } 6366 }
5931 6367
5932 } // namespace dart 6368 } // namespace dart
5933 6369
5934 #undef __ 6370 #undef __
5935 6371
5936 #endif // defined TARGET_ARCH_X64 6372 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698