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

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_ia32.cc ('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 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 EmitInt64ComparisonOp(FlowGraphCompiler* compiler,
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 EmitInt64ComparisonOp(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 EmitInt64ComparisonOp(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 return kTagged; 990 return kTagged;
972 case kTypedDataInt32ArrayCid: 991 case kTypedDataInt32ArrayCid:
973 return kUnboxedInt32; 992 return kUnboxedInt32;
974 case kTypedDataUint32ArrayCid: 993 case kTypedDataUint32ArrayCid:
975 return kUnboxedUint32; 994 return kUnboxedUint32;
995 case kTypedDataInt64ArrayCid:
996 return kUnboxedMint;
976 case kTypedDataFloat32ArrayCid: 997 case kTypedDataFloat32ArrayCid:
977 case kTypedDataFloat64ArrayCid: 998 case kTypedDataFloat64ArrayCid:
978 return kUnboxedDouble; 999 return kUnboxedDouble;
979 case kTypedDataInt32x4ArrayCid: 1000 case kTypedDataInt32x4ArrayCid:
980 return kUnboxedInt32x4; 1001 return kUnboxedInt32x4;
981 case kTypedDataFloat32x4ArrayCid: 1002 case kTypedDataFloat32x4ArrayCid:
982 return kUnboxedFloat32x4; 1003 return kUnboxedFloat32x4;
983 case kTypedDataFloat64x2ArrayCid: 1004 case kTypedDataFloat64x2ArrayCid:
984 return kUnboxedFloat64x2; 1005 return kUnboxedFloat64x2;
985 default: 1006 default:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 case kTypedDataUint32ArrayCid: 1089 case kTypedDataUint32ArrayCid:
1069 ASSERT(representation() == kUnboxedUint32); 1090 ASSERT(representation() == kUnboxedUint32);
1070 __ movl(result, element_address); 1091 __ movl(result, element_address);
1071 break; 1092 break;
1072 default: 1093 default:
1073 UNREACHABLE(); 1094 UNREACHABLE();
1074 } 1095 }
1075 return; 1096 return;
1076 } 1097 }
1077 1098
1099 if (representation() == kUnboxedMint) {
1100 ASSERT(class_id() == kTypedDataInt64ArrayCid);
1101 if ((index_scale() == 1) && index.IsRegister()) {
1102 __ SmiUntag(index.reg());
1103 }
1104 Register result = locs()->out(0).reg();
1105 __ movq(result, element_address);
1106 return;
1107 }
1108
1078 ASSERT(representation() == kTagged); 1109 ASSERT(representation() == kTagged);
1079 1110
1080 if ((index_scale() == 1) && index.IsRegister()) { 1111 if ((index_scale() == 1) && index.IsRegister()) {
1081 __ SmiUntag(index.reg()); 1112 __ SmiUntag(index.reg());
1082 } 1113 }
1083 Register result = locs()->out(0).reg(); 1114 Register result = locs()->out(0).reg();
1084 switch (class_id()) { 1115 switch (class_id()) {
1085 case kTypedDataInt8ArrayCid: 1116 case kTypedDataInt8ArrayCid:
1086 __ movsxb(result, element_address); 1117 __ movsxb(result, element_address);
1087 __ SmiTag(result); 1118 __ SmiTag(result);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 case kExternalTypedDataUint8ArrayCid: 1155 case kExternalTypedDataUint8ArrayCid:
1125 case kTypedDataUint8ClampedArrayCid: 1156 case kTypedDataUint8ClampedArrayCid:
1126 case kExternalTypedDataUint8ClampedArrayCid: 1157 case kExternalTypedDataUint8ClampedArrayCid:
1127 case kTypedDataInt16ArrayCid: 1158 case kTypedDataInt16ArrayCid:
1128 case kTypedDataUint16ArrayCid: 1159 case kTypedDataUint16ArrayCid:
1129 return kTagged; 1160 return kTagged;
1130 case kTypedDataInt32ArrayCid: 1161 case kTypedDataInt32ArrayCid:
1131 return kUnboxedInt32; 1162 return kUnboxedInt32;
1132 case kTypedDataUint32ArrayCid: 1163 case kTypedDataUint32ArrayCid:
1133 return kUnboxedUint32; 1164 return kUnboxedUint32;
1165 case kTypedDataInt64ArrayCid:
1166 return kUnboxedMint;
1134 case kTypedDataFloat32ArrayCid: 1167 case kTypedDataFloat32ArrayCid:
1135 case kTypedDataFloat64ArrayCid: 1168 case kTypedDataFloat64ArrayCid:
1136 return kUnboxedDouble; 1169 return kUnboxedDouble;
1137 case kTypedDataFloat32x4ArrayCid: 1170 case kTypedDataFloat32x4ArrayCid:
1138 return kUnboxedFloat32x4; 1171 return kUnboxedFloat32x4;
1139 case kTypedDataInt32x4ArrayCid: 1172 case kTypedDataInt32x4ArrayCid:
1140 return kUnboxedInt32x4; 1173 return kUnboxedInt32x4;
1141 case kTypedDataFloat64x2ArrayCid: 1174 case kTypedDataFloat64x2ArrayCid:
1142 return kUnboxedFloat64x2; 1175 return kUnboxedFloat64x2;
1143 default: 1176 default:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 // RBX, RCX, RDX) instead of using a fixed register. 1214 // RBX, RCX, RDX) instead of using a fixed register.
1182 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); 1215 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
1183 break; 1216 break;
1184 case kTypedDataInt16ArrayCid: 1217 case kTypedDataInt16ArrayCid:
1185 case kTypedDataUint16ArrayCid: 1218 case kTypedDataUint16ArrayCid:
1186 case kTypedDataInt32ArrayCid: 1219 case kTypedDataInt32ArrayCid:
1187 case kTypedDataUint32ArrayCid: 1220 case kTypedDataUint32ArrayCid:
1188 // Writable register because the value must be untagged before storing. 1221 // Writable register because the value must be untagged before storing.
1189 locs->set_in(2, Location::WritableRegister()); 1222 locs->set_in(2, Location::WritableRegister());
1190 break; 1223 break;
1224 case kTypedDataInt64ArrayCid:
1225 locs->set_in(2, Location::RequiresRegister());
1226 break;
1191 case kTypedDataFloat32ArrayCid: 1227 case kTypedDataFloat32ArrayCid:
1192 case kTypedDataFloat64ArrayCid: 1228 case kTypedDataFloat64ArrayCid:
1193 // TODO(srdjan): Support Float64 constants. 1229 // TODO(srdjan): Support Float64 constants.
1194 locs->set_in(2, Location::RequiresFpuRegister()); 1230 locs->set_in(2, Location::RequiresFpuRegister());
1195 break; 1231 break;
1196 case kTypedDataInt32x4ArrayCid: 1232 case kTypedDataInt32x4ArrayCid:
1197 case kTypedDataFloat64x2ArrayCid: 1233 case kTypedDataFloat64x2ArrayCid:
1198 case kTypedDataFloat32x4ArrayCid: 1234 case kTypedDataFloat32x4ArrayCid:
1199 locs->set_in(2, Location::RequiresFpuRegister()); 1235 locs->set_in(2, Location::RequiresFpuRegister());
1200 break; 1236 break;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 __ SmiUntag(value); 1320 __ SmiUntag(value);
1285 __ movw(element_address, value); 1321 __ movw(element_address, value);
1286 break; 1322 break;
1287 } 1323 }
1288 case kTypedDataInt32ArrayCid: 1324 case kTypedDataInt32ArrayCid:
1289 case kTypedDataUint32ArrayCid: { 1325 case kTypedDataUint32ArrayCid: {
1290 Register value = locs()->in(2).reg(); 1326 Register value = locs()->in(2).reg();
1291 __ movl(element_address, value); 1327 __ movl(element_address, value);
1292 break; 1328 break;
1293 } 1329 }
1330 case kTypedDataInt64ArrayCid: {
1331 Register value = locs()->in(2).reg();
1332 __ movq(element_address, value);
1333 break;
1334 }
1294 case kTypedDataFloat32ArrayCid: 1335 case kTypedDataFloat32ArrayCid:
1295 __ movss(element_address, locs()->in(2).fpu_reg()); 1336 __ movss(element_address, locs()->in(2).fpu_reg());
1296 break; 1337 break;
1297 case kTypedDataFloat64ArrayCid: 1338 case kTypedDataFloat64ArrayCid:
1298 __ movsd(element_address, locs()->in(2).fpu_reg()); 1339 __ movsd(element_address, locs()->in(2).fpu_reg());
1299 break; 1340 break;
1300 case kTypedDataInt32x4ArrayCid: 1341 case kTypedDataInt32x4ArrayCid:
1301 case kTypedDataFloat64x2ArrayCid: 1342 case kTypedDataFloat64x2ArrayCid:
1302 case kTypedDataFloat32x4ArrayCid: 1343 case kTypedDataFloat32x4ArrayCid:
1303 __ movups(element_address, locs()->in(2).fpu_reg()); 1344 __ movups(element_address, locs()->in(2).fpu_reg());
(...skipping 4181 matching lines...) Expand 10 before | Expand all | Expand 10 after
5485 Register length = length_loc.reg(); 5526 Register length = length_loc.reg();
5486 Register index = index_loc.reg(); 5527 Register index = index_loc.reg();
5487 __ cmpq(index, length); 5528 __ cmpq(index, length);
5488 __ j(ABOVE_EQUAL, deopt); 5529 __ j(ABOVE_EQUAL, deopt);
5489 } 5530 }
5490 } 5531 }
5491 5532
5492 5533
5493 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5534 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5494 bool opt) const { 5535 bool opt) const {
5495 UNIMPLEMENTED(); 5536 const intptr_t kNumInputs = 1;
5496 return NULL; 5537 const intptr_t kNumTemps = 0;
5538 LocationSummary* locs = new(isolate) LocationSummary(
5539 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5540 locs->set_in(0, Location::RequiresRegister());
5541 locs->set_out(0, Location::SameAsFirstInput());
5542 return locs;
5497 } 5543 }
5498 5544
5499 5545
5500 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5546 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5501 UNIMPLEMENTED(); 5547 const intptr_t value_cid = value()->Type()->ToCid();
5548 const Register value = locs()->in(0).reg();
5549 const Register result = locs()->out(0).reg();
5550 ASSERT(value == result);
5551
5552 if (value_cid == kMintCid) {
5553 __ movq(result, FieldAddress(value, Mint::value_offset()));
5554 } else if (value_cid == kSmiCid) {
5555 __ SmiUntag(result);
5556 } else {
5557 Label* deopt = compiler->AddDeoptStub(deopt_id_,
5558 ICData::kDeoptUnboxInteger);
5559 Label done;
5560 __ SmiUntagOrCheckClass(value, kMintCid, &done);
5561 __ j(NOT_EQUAL, deopt);
5562 // Undo untagging by multiplying value with 2.
5563 __ movq(result, Address(value, TIMES_2, Mint::value_offset()));
5564 __ Bind(&done);
5565 }
5502 } 5566 }
5503 5567
5504 5568
5505 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5569 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5506 bool opt) const { 5570 bool opt) const {
5507 UNIMPLEMENTED(); 5571 const intptr_t kNumInputs = 1;
5508 return NULL; 5572 const intptr_t kNumTemps = 0;
5573 LocationSummary* summary = new(isolate) LocationSummary(
5574 isolate, kNumInputs, kNumTemps, is_smi()
5575 ? LocationSummary::kNoCall
5576 : LocationSummary::kCallOnSlowPath);
5577 summary->set_in(0, Location::RequiresRegister());
5578 summary->set_out(0, Location::RequiresRegister());
5579 return summary;
5509 } 5580 }
5510 5581
5511 5582
5512 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5583 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5513 UNIMPLEMENTED(); 5584 const Register out = locs()->out(0).reg();
5585 const Register value = locs()->in(0).reg();
5586
5587 if (is_smi()) {
5588 __ movq(out, value);
5589 __ SmiTag(out);
5590 return;
5591 }
5592
5593 Label is_smi;
5594 Label done;
5595 __ movq(out, value);
5596 __ SmiTag(out); // shlq sets OF := SF ^ CF on 1 bit shifts
5597 __ j(NO_OVERFLOW, &done);
5598 BoxAllocationSlowPath::Allocate(
5599 compiler, this, compiler->mint_class(), out);
5600 __ movq(FieldAddress(out, Mint::value_offset()), value);
5601 __ Bind(&done);
5602 }
5603
5604
5605 template<typename OperandType>
5606 static void EmitInt64Arithmetic(FlowGraphCompiler* compiler,
5607 Token::Kind op_kind,
5608 Register left,
5609 const OperandType& right,
5610 Label* deopt) {
5611 switch (op_kind) {
5612 case Token::kADD:
5613 __ addq(left, right);
5614 break;
5615 case Token::kSUB:
5616 __ subq(left, right);
5617 break;
5618 case Token::kBIT_AND:
5619 __ andq(left, right);
5620 break;
5621 case Token::kBIT_OR:
5622 __ orq(left, right);
5623 break;
5624 case Token::kBIT_XOR:
5625 __ xorq(left, right);
5626 break;
5627 case Token::kMUL:
5628 __ imulq(left, right);
5629 break;
5630 default:
5631 UNREACHABLE();
5632 }
5633 if (deopt != NULL) __ j(OVERFLOW, deopt);
5514 } 5634 }
5515 5635
5516 5636
5517 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5637 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5518 bool opt) const { 5638 bool opt) const {
5519 UNIMPLEMENTED(); 5639 const intptr_t kNumInputs = 2;
5520 return NULL; 5640 const intptr_t kNumTemps = 0;
5641 LocationSummary* summary = new(isolate) LocationSummary(
5642 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5643 summary->set_in(0, Location::RequiresRegister());
5644 summary->set_in(1, Location::RequiresRegister());
5645 summary->set_out(0, Location::SameAsFirstInput());
5646 return summary;
5521 } 5647 }
5522 5648
5523 5649
5524 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5650 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5525 UNIMPLEMENTED(); 5651 const Register left = locs()->in(0).reg();
5652 const Register right = locs()->in(1).reg();
5653 const Register out = locs()->out(0).reg();
5654
5655 ASSERT(out == left);
5656
5657 Label* deopt = NULL;
5658 if (CanDeoptimize()) {
5659 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5660 }
5661
5662 EmitInt64Arithmetic(compiler, op_kind(), left, right, deopt);
5663
5664 if (FLAG_throw_on_javascript_int_overflow) {
5665 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5666 }
5526 } 5667 }
5527 5668
5528 5669
5529 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5670 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5530 bool opt) const { 5671 bool opt) const {
5531 UNIMPLEMENTED(); 5672 const intptr_t kNumInputs = 1;
5532 return NULL; 5673 const intptr_t kNumTemps = 0;
5674 LocationSummary* summary = new(isolate) LocationSummary(
5675 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5676 summary->set_in(0, Location::RequiresRegister());
5677 summary->set_out(0, Location::SameAsFirstInput());
5678 return summary;
5533 } 5679 }
5534 5680
5535 5681
5536 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5682 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5537 UNIMPLEMENTED(); 5683 ASSERT(op_kind() == Token::kBIT_NOT);
5538 } 5684 const Register left = locs()->in(0).reg();
5539 5685 const Register out = locs()->out(0).reg();
5686 ASSERT(out == left);
5687
5688 Label* deopt = NULL;
5689 if (FLAG_throw_on_javascript_int_overflow) {
5690 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
5691 }
5692
5693 __ notq(left);
5694
5695 if (FLAG_throw_on_javascript_int_overflow) {
5696 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5697 }
5698 }
5699
5700
5701 static const intptr_t kMintShiftCountLimit = 63;
5540 5702
5541 bool ShiftMintOpInstr::has_shift_count_check() const { 5703 bool ShiftMintOpInstr::has_shift_count_check() const {
5542 UNREACHABLE(); 5704 return !RangeUtils::IsWithin(
5543 return false; 5705 right()->definition()->range(), 0, kMintShiftCountLimit);
5544 } 5706 }
5545 5707
5546 5708
5547 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 5709 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5548 bool opt) const { 5710 bool opt) const {
5549 UNIMPLEMENTED(); 5711 const intptr_t kNumInputs = 2;
5550 return NULL; 5712 const intptr_t kNumTemps = can_overflow() ? 1 : 0;
5713 LocationSummary* summary = new(isolate) LocationSummary(
5714 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5715 summary->set_in(0, Location::RequiresRegister());
5716 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
5717 if (kNumTemps > 0) {
5718 summary->set_temp(0, Location::RequiresRegister());
5719 }
5720 summary->set_out(0, Location::SameAsFirstInput());
5721 return summary;
5551 } 5722 }
5552 5723
5553 5724
5554 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5725 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5555 UNIMPLEMENTED(); 5726 const Register left = locs()->in(0).reg();
5556 } 5727 const Register out = locs()->out(0).reg();
5557 5728 ASSERT(left == out);
5558 5729
5730 Label* deopt = NULL;
5731 if (CanDeoptimize()) {
5732 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5733 }
5734 if (locs()->in(1).IsConstant()) {
5735 // Code for a constant shift amount.
5736 ASSERT(locs()->in(1).constant().IsSmi());
5737 const int64_t shift =
5738 reinterpret_cast<int64_t>(locs()->in(1).constant().raw()) >> 1;
5739 switch (op_kind()) {
5740 case Token::kSHR:
5741 __ sarq(left, Immediate(shift));
5742 break;
5743 case Token::kSHL: {
5744 if (can_overflow()) {
5745 // Check for overflow.
5746 Register temp = locs()->temp(0).reg();
5747 __ movq(temp, left);
5748 __ shlq(left, Immediate(shift));
5749 __ sarq(left, Immediate(shift));
5750 __ cmpq(left, temp);
5751 __ j(NOT_EQUAL, deopt); // Overflow.
5752 }
5753 // Shift for result now we know there is no overflow.
5754 __ shlq(left, Immediate(shift));
5755 break;
5756 }
5757 default:
5758 UNREACHABLE();
5759 }
5760 } else {
5761 // Code for a variable shift amount.
5762 // Deoptimize if shift count is > 63.
5763 // sarl operation masks the count to 5 bits and
5764 // shrd is undefined with count > operand size (32)
5765 __ SmiUntag(RCX);
5766 if (has_shift_count_check()) {
5767 __ cmpq(RCX, Immediate(kMintShiftCountLimit));
5768 __ j(ABOVE, deopt);
5769 }
5770 Label done, large_shift;
5771 switch (op_kind()) {
5772 case Token::kSHR: {
5773 __ sarq(left, RCX);
5774 break;
5775 }
5776 case Token::kSHL: {
5777 if (can_overflow()) {
5778 // Check for overflow.
5779 Register temp = locs()->temp(0).reg();
5780 __ movq(temp, left);
5781 __ shlq(left, RCX);
5782 __ sarq(left, RCX);
5783 __ cmpq(left, temp);
5784 __ j(NOT_EQUAL, deopt); // Overflow.
5785 }
5786 // Shift for result now we know there is no overflow.
5787 __ shlq(left, RCX);
5788 break;
5789 }
5790 default:
5791 UNREACHABLE();
5792 }
5793 }
5794 if (FLAG_throw_on_javascript_int_overflow) {
5795 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5796 }
5797 }
5798
5799
5559 CompileType BinaryUint32OpInstr::ComputeType() const { 5800 CompileType BinaryUint32OpInstr::ComputeType() const {
5560 return CompileType::FromCid(kSmiCid); 5801 return CompileType::FromCid(kSmiCid);
5561 } 5802 }
5562 5803
5563 5804
5564 CompileType ShiftUint32OpInstr::ComputeType() const { 5805 CompileType ShiftUint32OpInstr::ComputeType() const {
5565 return CompileType::FromCid(kSmiCid); 5806 return CompileType::FromCid(kSmiCid);
5566 } 5807 }
5567 5808
5568 5809
5569 CompileType UnaryUint32OpInstr::ComputeType() const { 5810 CompileType UnaryUint32OpInstr::ComputeType() const {
5570 return CompileType::FromCid(kSmiCid); 5811 return CompileType::FromCid(kSmiCid);
5571 } 5812 }
5572 5813
5573 5814
5574 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) 5815 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5575 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) 5816 bool opt) const {
5576 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) 5817 const intptr_t kNumInputs = 2;
5818 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
5819 LocationSummary* summary = new(isolate) LocationSummary(
5820 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5821 summary->set_in(0, Location::RequiresRegister());
5822 summary->set_in(1, Location::RequiresRegister());
5823 summary->set_out(0, Location::SameAsFirstInput());
5824 return summary;
5825 }
5826
5827
5828 template<typename OperandType>
5829 static void EmitIntegerArithmetic(FlowGraphCompiler* compiler,
5830 Token::Kind op_kind,
5831 Register left,
5832 const OperandType& right,
5833 Label* deopt) {
5834 switch (op_kind) {
5835 case Token::kADD:
5836 __ addl(left, right);
5837 break;
5838 case Token::kSUB:
5839 __ subl(left, right);
5840 break;
5841 case Token::kBIT_AND:
5842 __ andl(left, right);
5843 break;
5844 case Token::kBIT_OR:
5845 __ orl(left, right);
5846 break;
5847 case Token::kBIT_XOR:
5848 __ xorl(left, right);
5849 break;
5850 case Token::kMUL:
5851 __ imull(left, right);
5852 break;
5853 default:
5854 UNREACHABLE();
5855 }
5856 if (deopt != NULL) __ j(OVERFLOW, deopt);
5857 }
5858
5859
5860 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5861 Register left = locs()->in(0).reg();
5862 Register right = locs()->in(1).reg();
5863 Register out = locs()->out(0).reg();
5864 ASSERT(out == left);
5865 switch (op_kind()) {
5866 case Token::kBIT_AND:
5867 case Token::kBIT_OR:
5868 case Token::kBIT_XOR:
5869 case Token::kADD:
5870 case Token::kSUB:
5871 case Token::kMUL:
5872 EmitIntegerArithmetic(compiler, op_kind(), left, right, NULL);
5873 return;
5874 default:
5875 UNREACHABLE();
5876 }
5877 }
5878
5879
5880 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5881 bool opt) const {
5882 const intptr_t kNumInputs = 2;
5883 const intptr_t kNumTemps = 0;
5884 LocationSummary* summary = new(isolate) LocationSummary(
5885 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5886 summary->set_in(0, Location::RequiresRegister());
5887 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
5888 summary->set_out(0, Location::SameAsFirstInput());
5889 return summary;
5890 }
5891
5892
5893 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5894 const intptr_t kShifterLimit = 31;
5895
5896 Register left = locs()->in(0).reg();
5897 Register out = locs()->out(0).reg();
5898 ASSERT(left == out);
5899
5900
5901 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5902
5903 if (locs()->in(1).IsConstant()) {
5904 // Shifter is constant.
5905
5906 const Object& constant = locs()->in(1).constant();
5907 ASSERT(constant.IsSmi());
5908 const intptr_t shift_value = Smi::Cast(constant).Value();
5909
5910 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
5911 switch (op_kind()) {
5912 case Token::kSHR:
5913 __ shrl(left, Immediate(shift_value));
5914 break;
5915 case Token::kSHL:
5916 __ shll(left, Immediate(shift_value));
5917 break;
5918 default:
5919 UNREACHABLE();
5920 }
5921 return;
5922 }
5923
5924 // Non constant shift value.
5925
5926 Register shifter = locs()->in(1).reg();
5927 ASSERT(shifter == RCX);
5928
5929 Label done;
5930 Label zero;
5931
5932 // TODO(johnmccutchan): Use range information to avoid these checks.
5933 __ SmiUntag(shifter);
5934 __ cmpq(shifter, Immediate(0));
5935 // If shift value is < 0, deoptimize.
5936 __ j(NEGATIVE, deopt);
5937 __ cmpq(shifter, Immediate(kShifterLimit));
5938 // If shift value is >= 32, return zero.
5939 __ j(ABOVE, &zero);
5940
5941 // Do the shift.
5942 switch (op_kind()) {
5943 case Token::kSHR:
5944 __ shrl(left, shifter);
5945 __ jmp(&done);
5946 break;
5947 case Token::kSHL:
5948 __ shll(left, shifter);
5949 __ jmp(&done);
5950 break;
5951 default:
5952 UNREACHABLE();
5953 }
5954
5955 __ Bind(&zero);
5956 // Shift was greater than 31 bits, just return zero.
5957 __ xorq(left, left);
5958
5959 // Exit path.
5960 __ Bind(&done);
5961 }
5962
5963
5964 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
5965 bool opt) const {
5966 const intptr_t kNumInputs = 1;
5967 const intptr_t kNumTemps = 0;
5968 LocationSummary* summary = new(isolate) LocationSummary(
5969 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5970 summary->set_in(0, Location::RequiresRegister());
5971 summary->set_out(0, Location::SameAsFirstInput());
5972 return summary;
5973 }
5974
5975
5976 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5977 Register out = locs()->out(0).reg();
5978 ASSERT(locs()->in(0).reg() == out);
5979
5980 ASSERT(op_kind() == Token::kBIT_NOT);
5981
5982 __ notl(out);
5983 }
5984
5985
5577 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5986 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5578 5987
5579 5988
5580 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, 5989 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
5581 bool opt) const { 5990 bool opt) const {
5582 const intptr_t kNumInputs = 1; 5991 const intptr_t kNumInputs = 1;
5583 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0; 5992 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
5584 LocationSummary* summary = new(isolate) LocationSummary( 5993 LocationSummary* summary = new(isolate) LocationSummary(
5585 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5994 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5586 summary->set_in(0, Location::RequiresRegister()); 5995 summary->set_in(0, Location::RequiresRegister());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
5658 } 6067 }
5659 6068
5660 6069
5661 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, 6070 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
5662 bool opt) const { 6071 bool opt) const {
5663 const intptr_t kNumInputs = 1; 6072 const intptr_t kNumInputs = 1;
5664 const intptr_t kNumTemps = 0; 6073 const intptr_t kNumTemps = 0;
5665 LocationSummary* summary = new(isolate) LocationSummary( 6074 LocationSummary* summary = new(isolate) LocationSummary(
5666 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6075 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5667 if (from() == kUnboxedMint) { 6076 if (from() == kUnboxedMint) {
5668 UNREACHABLE(); 6077 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6078 summary->set_in(0, Location::RequiresRegister());
6079 summary->set_out(0, Location::SameAsFirstInput());
5669 } else if (to() == kUnboxedMint) { 6080 } else if (to() == kUnboxedMint) {
5670 UNREACHABLE(); 6081 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedUint32));
6082 summary->set_in(0, Location::RequiresRegister());
6083 summary->set_out(0, Location::SameAsFirstInput());
5671 } else { 6084 } else {
5672 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); 6085 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
5673 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 6086 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5674 summary->set_in(0, Location::RequiresRegister()); 6087 summary->set_in(0, Location::RequiresRegister());
5675 summary->set_out(0, Location::SameAsFirstInput()); 6088 summary->set_out(0, Location::SameAsFirstInput());
5676 } 6089 }
5677 return summary; 6090 return summary;
5678 } 6091 }
5679 6092
5680 6093
(...skipping 11 matching lines...) Expand all
5692 const Register value = locs()->in(0).reg(); 6105 const Register value = locs()->in(0).reg();
5693 const Register out = locs()->out(0).reg(); 6106 const Register out = locs()->out(0).reg();
5694 __ movsxd(out, value); 6107 __ movsxd(out, value);
5695 if (CanDeoptimize()) { 6108 if (CanDeoptimize()) {
5696 Label* deopt = 6109 Label* deopt =
5697 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); 6110 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
5698 __ testl(out, out); 6111 __ testl(out, out);
5699 __ j(NEGATIVE, deopt); 6112 __ j(NEGATIVE, deopt);
5700 } 6113 }
5701 } else if (from() == kUnboxedMint) { 6114 } else if (from() == kUnboxedMint) {
5702 UNREACHABLE(); 6115 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6116 const Register value = locs()->in(0).reg();
6117 const Register out = locs()->out(0).reg();
6118 if (!CanDeoptimize()) {
6119 // Copy low.
6120 __ movl(out, value);
6121 } else {
6122 Label* deopt =
6123 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
6124 // Sign extend.
6125 __ movsxd(out, value);
6126 // Compare with original value.
6127 __ cmpq(out, value);
6128 // Value cannot be held in Int32, deopt.
6129 __ j(NOT_EQUAL, deopt);
6130 }
5703 } else if (to() == kUnboxedMint) { 6131 } else if (to() == kUnboxedMint) {
5704 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 6132 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5705 UNREACHABLE(); 6133 const Register value = locs()->in(0).reg();
6134 const Register out = locs()->out(0).reg();
6135 if (from() == kUnboxedUint32) {
6136 // Zero extend.
6137 __ movl(out, value);
6138 } else {
6139 // Sign extend.
6140 ASSERT(from() == kUnboxedInt32);
6141 __ movsxd(out, value);
6142 }
5706 } else { 6143 } else {
5707 UNREACHABLE(); 6144 UNREACHABLE();
5708 } 6145 }
5709 } 6146 }
5710 6147
5711 6148
5712 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6149 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
5713 bool opt) const { 6150 bool opt) const {
5714 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6151 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
5715 } 6152 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
5965 __ movq(R10, Immediate(kInvalidObjectPointer)); 6402 __ movq(R10, Immediate(kInvalidObjectPointer));
5966 __ movq(RBX, Immediate(kInvalidObjectPointer)); 6403 __ movq(RBX, Immediate(kInvalidObjectPointer));
5967 #endif 6404 #endif
5968 } 6405 }
5969 6406
5970 } // namespace dart 6407 } // namespace dart
5971 6408
5972 #undef __ 6409 #undef __
5973 6410
5974 #endif // defined TARGET_ARCH_X64 6411 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698