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

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

Issue 10867012: Add a smi-check instruction for arithmetic smi operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1436 summary->set_in(0, Location::RegisterLocation(RAX)); 1436 summary->set_in(0, Location::RegisterLocation(RAX));
1437 summary->set_in(1, Location::RegisterLocation(RCX)); 1437 summary->set_in(1, Location::RegisterLocation(RCX));
1438 summary->set_out(Location::SameAsFirstInput()); 1438 summary->set_out(Location::SameAsFirstInput());
1439 summary->set_temp(0, Location::RegisterLocation(RBX)); 1439 summary->set_temp(0, Location::RegisterLocation(RBX));
1440 // Will be used for for sign extension. 1440 // Will be used for for sign extension.
1441 summary->set_temp(1, Location::RegisterLocation(RDX)); 1441 summary->set_temp(1, Location::RegisterLocation(RDX));
1442 summary->set_temp(2, Location::RequiresRegister()); 1442 summary->set_temp(2, Location::RequiresRegister());
1443 return summary; 1443 return summary;
1444 } else if (op_kind() == Token::kSHR) { 1444 } else if (op_kind() == Token::kSHR) {
1445 const intptr_t kNumTemps = 1; 1445 const intptr_t kNumTemps = 0;
1446 LocationSummary* summary = 1446 LocationSummary* summary =
1447 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1447 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1448 summary->set_in(0, Location::RequiresRegister()); 1448 summary->set_in(0, Location::RequiresRegister());
1449 summary->set_in(1, Location::RegisterLocation(RCX)); 1449 summary->set_in(1, Location::RegisterLocation(RCX));
1450 summary->set_out(Location::SameAsFirstInput()); 1450 summary->set_out(Location::SameAsFirstInput());
1451 summary->set_temp(0, Location::RequiresRegister());
1452 return summary; 1451 return summary;
1453 } else if (op_kind() == Token::kSHL) { 1452 } else if (op_kind() == Token::kSHL) {
1454 // Two Smi operands can easily overflow into Mint. 1453 // Two Smi operands can easily overflow into Mint.
1455 const intptr_t kNumTemps = 2; 1454 const intptr_t kNumTemps = 2;
1456 LocationSummary* summary = 1455 LocationSummary* summary =
1457 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1458 summary->set_in(0, Location::RegisterLocation(RAX)); 1457 summary->set_in(0, Location::RegisterLocation(RAX));
1459 summary->set_in(1, Location::RegisterLocation(RDX)); 1458 summary->set_in(1, Location::RegisterLocation(RDX));
1460 summary->set_out(Location::RegisterLocation(RAX)); 1459 summary->set_out(Location::RegisterLocation(RAX));
1461 summary->set_temp(0, Location::RegisterLocation(RBX)); 1460 summary->set_temp(0, Location::RegisterLocation(RBX));
1462 summary->set_temp(1, Location::RegisterLocation(RCX)); 1461 summary->set_temp(1, Location::RegisterLocation(RCX));
1463 return summary; 1462 return summary;
1464 } else { 1463 } else {
1465 const intptr_t kNumTemps = 1; 1464 const intptr_t kNumTemps = 0;
1466 LocationSummary* summary = 1465 LocationSummary* summary =
1467 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1466 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1468 summary->set_in(0, Location::RequiresRegister()); 1467 summary->set_in(0, Location::RequiresRegister());
1469 summary->set_in(1, Location::RequiresRegister()); 1468 summary->set_in(1, Location::RequiresRegister());
1470 summary->set_out(Location::SameAsFirstInput()); 1469 summary->set_out(Location::SameAsFirstInput());
1471 summary->set_temp(0, Location::RequiresRegister());
1472 return summary; 1470 return summary;
1473 } 1471 }
1474 } 1472 }
1475 1473
1476 1474
1477 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1475 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1478 Register left = locs()->in(0).reg(); 1476 Register left = locs()->in(0).reg();
1479 Register right = locs()->in(1).reg(); 1477 Register right = locs()->in(1).reg();
1480 Register result = locs()->out().reg(); 1478 Register result = locs()->out().reg();
1481 Register temp = locs()->temp(0).reg();
1482 ASSERT(left == result); 1479 ASSERT(left == result);
1483 const bool left_is_smi = this->left()->ResultCid() == kSmiCid; 1480 Label* deopt = NULL;
1484 const bool right_is_smi = this->right()->ResultCid() == kSmiCid;
1485 bool can_deopt;
1486 switch (op_kind()) { 1481 switch (op_kind()) {
1487 case Token::kBIT_AND: 1482 case Token::kBIT_AND:
1488 case Token::kBIT_OR: 1483 case Token::kBIT_OR:
1489 case Token::kBIT_XOR: 1484 case Token::kBIT_XOR:
1490 can_deopt = !(right_is_smi && left_is_smi); 1485 // Can't deoptimize. Arguments are already checked for smi.
1491 break; 1486 break;
1492 default: 1487 default:
1493 can_deopt = true; 1488 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1494 } 1489 instance_call()->try_index(),
1495 Label* deopt = NULL; 1490 kDeoptBinarySmiOp);
1496 if (can_deopt) {
1497 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1498 instance_call()->try_index(),
1499 kDeoptBinarySmiOp);
1500 }
1501 if (!left_is_smi || !right_is_smi) {
1502 __ movq(temp, left);
1503 __ orq(temp, right);
1504 __ testq(temp, Immediate(kSmiTagMask));
1505 __ j(NOT_ZERO, deopt);
1506 } 1491 }
1507 switch (op_kind()) { 1492 switch (op_kind()) {
1508 case Token::kADD: { 1493 case Token::kADD: {
1509 __ addq(left, right); 1494 __ addq(left, right);
1510 __ j(OVERFLOW, deopt); 1495 __ j(OVERFLOW, deopt);
1511 break; 1496 break;
1512 } 1497 }
1513 case Token::kSUB: { 1498 case Token::kSUB: {
1514 __ subq(left, right); 1499 __ subq(left, right);
1515 __ j(OVERFLOW, deopt); 1500 __ j(OVERFLOW, deopt);
(...skipping 14 matching lines...) Expand all
1530 // No overflow check. 1515 // No overflow check.
1531 __ orq(left, right); 1516 __ orq(left, right);
1532 break; 1517 break;
1533 } 1518 }
1534 case Token::kBIT_XOR: { 1519 case Token::kBIT_XOR: {
1535 // No overflow check. 1520 // No overflow check.
1536 __ xorq(left, right); 1521 __ xorq(left, right);
1537 break; 1522 break;
1538 } 1523 }
1539 case Token::kTRUNCDIV: { 1524 case Token::kTRUNCDIV: {
1525 Register temp = locs()->temp(0).reg();
1540 // Handle divide by zero in runtime. 1526 // Handle divide by zero in runtime.
1541 // Deoptimization requires that temp and right are preserved. 1527 // Deoptimization requires that temp and right are preserved.
1542 __ testq(right, right); 1528 __ testq(right, right);
1543 __ j(ZERO, deopt); 1529 __ j(ZERO, deopt);
1544 ASSERT(left == RAX); 1530 ASSERT(left == RAX);
1545 ASSERT((right != RDX) && (right != RAX)); 1531 ASSERT((right != RDX) && (right != RAX));
1546 ASSERT((temp != RDX) && (temp != RAX)); 1532 ASSERT((temp != RDX) && (temp != RAX));
1547 ASSERT(locs()->temp(1).reg() == RDX); 1533 ASSERT(locs()->temp(1).reg() == RDX);
1548 ASSERT(result == RAX); 1534 ASSERT(result == RAX);
1549 Register right_temp = locs()->temp(2).reg(); 1535 Register right_temp = locs()->temp(2).reg();
(...skipping 20 matching lines...) Expand all
1570 __ j(LESS, &count_ok, Assembler::kNearJump); 1556 __ j(LESS, &count_ok, Assembler::kNearJump);
1571 __ movq(right, kCountLimit); 1557 __ movq(right, kCountLimit);
1572 __ Bind(&count_ok); 1558 __ Bind(&count_ok);
1573 ASSERT(right == RCX); // Count must be in RCX 1559 ASSERT(right == RCX); // Count must be in RCX
1574 __ SmiUntag(left); 1560 __ SmiUntag(left);
1575 __ sarq(left, right); 1561 __ sarq(left, right);
1576 __ SmiTag(left); 1562 __ SmiTag(left);
1577 break; 1563 break;
1578 } 1564 }
1579 case Token::kSHL: { 1565 case Token::kSHL: {
1566 Register temp = locs()->temp(0).reg();
1580 Label call_method, done; 1567 Label call_method, done;
1581 // Check if count too large for handling it inlined. 1568 // Check if count too large for handling it inlined.
1582 __ movq(temp, left); 1569 __ movq(temp, left);
1583 __ cmpq(right, 1570 __ cmpq(right,
1584 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits)))); 1571 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
1585 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump); 1572 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
1586 Register right_temp = locs()->temp(1).reg(); 1573 Register right_temp = locs()->temp(1).reg();
1587 ASSERT(right_temp == RCX); // Count must be in RCX 1574 ASSERT(right_temp == RCX); // Count must be in RCX
1588 __ movq(right_temp, right); 1575 __ movq(right_temp, right);
1589 __ SmiUntag(right_temp); 1576 __ SmiUntag(right_temp);
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
2198 if (use_near_jump) { 2185 if (use_near_jump) {
2199 __ j(EQUAL, &is_ok, Assembler::kNearJump); 2186 __ j(EQUAL, &is_ok, Assembler::kNearJump);
2200 } else { 2187 } else {
2201 __ j(EQUAL, &is_ok); 2188 __ j(EQUAL, &is_ok);
2202 } 2189 }
2203 } 2190 }
2204 } 2191 }
2205 __ Bind(&is_ok); 2192 __ Bind(&is_ok);
2206 } 2193 }
2207 2194
2195
2196 LocationSummary* CheckSmiComp::MakeLocationSummary() const {
2197 const intptr_t kNumInputs = 1;
2198 const intptr_t kNumTemps = 0;
2199 LocationSummary* summary =
2200 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2201 summary->set_in(0, Location::RequiresRegister());
2202 return summary;
2203 }
2204
2205
2206 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2207 Register value = locs()->in(0).reg();
2208 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2209 try_index(),
2210 kDeoptCheckSmi);
2211 __ testq(value, Immediate(kSmiTagMask));
2212 __ j(NOT_ZERO, deopt);
2213 }
2214
2215
2208 } // namespace dart 2216 } // namespace dart
2209 2217
2210 #undef __ 2218 #undef __
2211 2219
2212 #endif // defined TARGET_ARCH_X64 2220 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698