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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('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) 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1419 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1420 summary->set_in(0, Location::RegisterLocation(EAX)); 1420 summary->set_in(0, Location::RegisterLocation(EAX));
1421 summary->set_in(1, Location::RegisterLocation(ECX)); 1421 summary->set_in(1, Location::RegisterLocation(ECX));
1422 summary->set_out(Location::SameAsFirstInput()); 1422 summary->set_out(Location::SameAsFirstInput());
1423 summary->set_temp(0, Location::RegisterLocation(EBX)); 1423 summary->set_temp(0, Location::RegisterLocation(EBX));
1424 // Will be used for for sign extension. 1424 // Will be used for for sign extension.
1425 summary->set_temp(1, Location::RegisterLocation(EDX)); 1425 summary->set_temp(1, Location::RegisterLocation(EDX));
1426 summary->set_temp(2, Location::RequiresRegister()); 1426 summary->set_temp(2, Location::RequiresRegister());
1427 return summary; 1427 return summary;
1428 } else if (op_kind() == Token::kSHR) { 1428 } else if (op_kind() == Token::kSHR) {
1429 const intptr_t kNumTemps = 1; 1429 const intptr_t kNumTemps = 0;
1430 LocationSummary* summary = 1430 LocationSummary* summary =
1431 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1431 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1432 summary->set_in(0, Location::RequiresRegister()); 1432 summary->set_in(0, Location::RequiresRegister());
1433 summary->set_in(1, Location::RegisterLocation(ECX)); 1433 summary->set_in(1, Location::RegisterLocation(ECX));
1434 summary->set_out(Location::SameAsFirstInput()); 1434 summary->set_out(Location::SameAsFirstInput());
1435 summary->set_temp(0, Location::RequiresRegister());
1436 return summary; 1435 return summary;
1437 } else if (op_kind() == Token::kSHL) { 1436 } else if (op_kind() == Token::kSHL) {
1438 // Two Smi operands can easily overflow into Mint. 1437 // Two Smi operands can easily overflow into Mint.
1439 const intptr_t kNumTemps = 2; 1438 const intptr_t kNumTemps = 2;
1440 LocationSummary* summary = 1439 LocationSummary* summary =
1441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1440 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1442 summary->set_in(0, Location::RegisterLocation(EAX)); 1441 summary->set_in(0, Location::RegisterLocation(EAX));
1443 summary->set_in(1, Location::RegisterLocation(EDX)); 1442 summary->set_in(1, Location::RegisterLocation(EDX));
1444 summary->set_temp(0, Location::RegisterLocation(EBX)); 1443 summary->set_temp(0, Location::RegisterLocation(EBX));
1445 summary->set_temp(1, Location::RegisterLocation(ECX)); 1444 summary->set_temp(1, Location::RegisterLocation(ECX));
1446 summary->set_out(Location::RegisterLocation(EAX)); 1445 summary->set_out(Location::RegisterLocation(EAX));
1447 return summary; 1446 return summary;
1448 } else { 1447 } else {
1449 const intptr_t kNumTemps = 1; 1448 const intptr_t kNumTemps = 0;
1450 LocationSummary* summary = 1449 LocationSummary* summary =
1451 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1450 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1452 summary->set_in(0, Location::RequiresRegister()); 1451 summary->set_in(0, Location::RequiresRegister());
1453 summary->set_in(1, Location::RequiresRegister()); 1452 summary->set_in(1, Location::RequiresRegister());
1454 summary->set_out(Location::SameAsFirstInput()); 1453 summary->set_out(Location::SameAsFirstInput());
1455 summary->set_temp(0, Location::RequiresRegister());
1456 return summary; 1454 return summary;
1457 } 1455 }
1458 } 1456 }
1459 1457
1460 1458
1461 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1459 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1462 Register left = locs()->in(0).reg(); 1460 Register left = locs()->in(0).reg();
1463 Register right = locs()->in(1).reg(); 1461 Register right = locs()->in(1).reg();
1464 Register result = locs()->out().reg(); 1462 Register result = locs()->out().reg();
1465 Register temp = locs()->temp(0).reg();
1466 ASSERT(left == result); 1463 ASSERT(left == result);
1467 const bool left_is_smi = this->left()->ResultCid() == kSmiCid; 1464 Label* deopt = NULL;
1468 const bool right_is_smi = this->right()->ResultCid() == kSmiCid;
1469 bool can_deopt;
1470 switch (op_kind()) { 1465 switch (op_kind()) {
1471 case Token::kBIT_AND: 1466 case Token::kBIT_AND:
1472 case Token::kBIT_OR: 1467 case Token::kBIT_OR:
1473 case Token::kBIT_XOR: 1468 case Token::kBIT_XOR:
1474 can_deopt = !(right_is_smi && left_is_smi); 1469 // Can't deoptimize. Arguments are already checked for smi.
1475 break; 1470 break;
1476 default: 1471 default:
1477 can_deopt = true; 1472 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1473 instance_call()->try_index(),
1474 kDeoptBinarySmiOp);
1478 } 1475 }
1479 Label* deopt = NULL; 1476
1480 if (can_deopt) {
1481 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1482 instance_call()->try_index(),
1483 kDeoptBinarySmiOp);
1484 }
1485 if (!left_is_smi || !right_is_smi) {
1486 __ movl(temp, left);
1487 __ orl(temp, right);
1488 __ testl(temp, Immediate(kSmiTagMask));
1489 __ j(NOT_ZERO, deopt);
1490 }
1491 switch (op_kind()) { 1477 switch (op_kind()) {
1492 case Token::kADD: { 1478 case Token::kADD: {
1493 __ addl(left, right); 1479 __ addl(left, right);
1494 __ j(OVERFLOW, deopt); 1480 __ j(OVERFLOW, deopt);
1495 break; 1481 break;
1496 } 1482 }
1497 case Token::kSUB: { 1483 case Token::kSUB: {
1498 __ subl(left, right); 1484 __ subl(left, right);
1499 __ j(OVERFLOW, deopt); 1485 __ j(OVERFLOW, deopt);
1500 break; 1486 break;
(...skipping 13 matching lines...) Expand all
1514 // No overflow check. 1500 // No overflow check.
1515 __ orl(left, right); 1501 __ orl(left, right);
1516 break; 1502 break;
1517 } 1503 }
1518 case Token::kBIT_XOR: { 1504 case Token::kBIT_XOR: {
1519 // No overflow check. 1505 // No overflow check.
1520 __ xorl(left, right); 1506 __ xorl(left, right);
1521 break; 1507 break;
1522 } 1508 }
1523 case Token::kTRUNCDIV: { 1509 case Token::kTRUNCDIV: {
1510 Register temp = locs()->temp(0).reg();
1524 // Handle divide by zero in runtime. 1511 // Handle divide by zero in runtime.
1525 // Deoptimization requires that temp and right are preserved. 1512 // Deoptimization requires that temp and right are preserved.
1526 __ testl(right, right); 1513 __ testl(right, right);
1527 __ j(ZERO, deopt); 1514 __ j(ZERO, deopt);
1528 ASSERT(left == EAX); 1515 ASSERT(left == EAX);
1529 ASSERT((right != EDX) && (right != EAX)); 1516 ASSERT((right != EDX) && (right != EAX));
1530 ASSERT((temp != EDX) && (temp != EAX)); 1517 ASSERT((temp != EDX) && (temp != EAX));
1531 ASSERT(locs()->temp(1).reg() == EDX); 1518 ASSERT(locs()->temp(1).reg() == EDX);
1532 ASSERT(result == EAX); 1519 ASSERT(result == EAX);
1533 Register right_temp = locs()->temp(2).reg(); 1520 Register right_temp = locs()->temp(2).reg();
(...skipping 20 matching lines...) Expand all
1554 __ j(LESS, &count_ok, Assembler::kNearJump); 1541 __ j(LESS, &count_ok, Assembler::kNearJump);
1555 __ movl(right, kCountLimit); 1542 __ movl(right, kCountLimit);
1556 __ Bind(&count_ok); 1543 __ Bind(&count_ok);
1557 ASSERT(right == ECX); // Count must be in ECX 1544 ASSERT(right == ECX); // Count must be in ECX
1558 __ SmiUntag(left); 1545 __ SmiUntag(left);
1559 __ sarl(left, right); 1546 __ sarl(left, right);
1560 __ SmiTag(left); 1547 __ SmiTag(left);
1561 break; 1548 break;
1562 } 1549 }
1563 case Token::kSHL: { 1550 case Token::kSHL: {
1551 Register temp = locs()->temp(0).reg();
1564 Label call_method, done; 1552 Label call_method, done;
1565 // Check if count too large for handling it inlined. 1553 // Check if count too large for handling it inlined.
1566 __ movl(temp, left); 1554 __ movl(temp, left);
1567 __ cmpl(right, 1555 __ cmpl(right,
1568 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits)))); 1556 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
1569 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump); 1557 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
1570 Register right_temp = locs()->temp(1).reg(); 1558 Register right_temp = locs()->temp(1).reg();
1571 ASSERT(right_temp == ECX); // Count must be in ECX 1559 ASSERT(right_temp == ECX); // Count must be in ECX
1572 __ movl(right_temp, right); 1560 __ movl(right_temp, right);
1573 __ SmiUntag(right_temp); 1561 __ SmiUntag(right_temp);
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 if (use_near_jump) { 2173 if (use_near_jump) {
2186 __ j(EQUAL, &is_ok, Assembler::kNearJump); 2174 __ j(EQUAL, &is_ok, Assembler::kNearJump);
2187 } else { 2175 } else {
2188 __ j(EQUAL, &is_ok); 2176 __ j(EQUAL, &is_ok);
2189 } 2177 }
2190 } 2178 }
2191 } 2179 }
2192 __ Bind(&is_ok); 2180 __ Bind(&is_ok);
2193 } 2181 }
2194 2182
2183
2184 LocationSummary* CheckSmiComp::MakeLocationSummary() const {
2185 const intptr_t kNumInputs = 1;
2186 const intptr_t kNumTemps = 0;
2187 LocationSummary* summary =
2188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2189 summary->set_in(0, Location::RequiresRegister());
2190 return summary;
2191 }
2192
2193
2194 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2195 Register value = locs()->in(0).reg();
2196 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2197 try_index(),
2198 kDeoptCheckSmi);
2199 __ testl(value, Immediate(kSmiTagMask));
2200 __ j(NOT_ZERO, deopt);
2201 }
2202
2203
2195 } // namespace dart 2204 } // namespace dart
2196 2205
2197 #undef __ 2206 #undef __
2198 2207
2199 #endif // defined TARGET_ARCH_X64 2208 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698