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

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

Issue 10553040: Inline binary And operation for Mint and Smi in new compilers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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) 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 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 if (operands_type() == kDoubleOperands) { 1273 if (operands_type() == kDoubleOperands) {
1274 const intptr_t kNumTemps = 1; 1274 const intptr_t kNumTemps = 1;
1275 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1275 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1276 summary->set_in(0, Location::RequiresRegister()); 1276 summary->set_in(0, Location::RequiresRegister());
1277 summary->set_in(1, Location::RequiresRegister()); 1277 summary->set_in(1, Location::RequiresRegister());
1278 summary->set_out(Location::RegisterLocation(RAX)); 1278 summary->set_out(Location::RegisterLocation(RAX));
1279 summary->set_temp(0, Location::RequiresRegister()); 1279 summary->set_temp(0, Location::RequiresRegister());
1280 return summary; 1280 return summary;
1281 } 1281 }
1282 1282
1283 if (operands_type() == kMintOperands) {
1284 ASSERT(op_kind() == Token::kBIT_AND);
1285 const intptr_t kNumTemps = 1;
1286 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1287 summary->set_in(0, Location::RequiresRegister());
1288 summary->set_in(1, Location::RequiresRegister());
1289 summary->set_out(Location::SameAsFirstInput());
1290 summary->set_temp(0, Location::RequiresRegister());
1291 return summary;
1292 }
1293
1283 ASSERT(operands_type() == kSmiOperands); 1294 ASSERT(operands_type() == kSmiOperands);
1284 1295
1285 if (op_kind() == Token::kTRUNCDIV) { 1296 if (op_kind() == Token::kTRUNCDIV) {
1286 const intptr_t kNumTemps = 3; 1297 const intptr_t kNumTemps = 3;
1287 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1298 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1288 summary->set_in(0, Location::RegisterLocation(RAX)); 1299 summary->set_in(0, Location::RegisterLocation(RAX));
1289 summary->set_in(1, Location::RegisterLocation(RCX)); 1300 summary->set_in(1, Location::RegisterLocation(RCX));
1290 summary->set_out(Location::SameAsFirstInput()); 1301 summary->set_out(Location::SameAsFirstInput());
1291 summary->set_temp(0, Location::RegisterLocation(RBX)); 1302 summary->set_temp(0, Location::RegisterLocation(RBX));
1292 // Will be used for for sign extension. 1303 // Will be used for for sign extension.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 UNREACHABLE(); 1458 UNREACHABLE();
1448 break; 1459 break;
1449 } 1460 }
1450 default: 1461 default:
1451 UNREACHABLE(); 1462 UNREACHABLE();
1452 break; 1463 break;
1453 } 1464 }
1454 } 1465 }
1455 1466
1456 1467
1468 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1469 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1470 // receiver and a Smi argument.
1471 Register left = comp->locs()->in(0).reg();
1472 Register right = comp->locs()->in(1).reg();
1473 Register result = comp->locs()->out().reg();
1474 Register temp = comp->locs()->temp(0).reg();
1475 ASSERT(left == result);
1476 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1477 comp->instance_call()->token_index(),
1478 comp->instance_call()->try_index(),
1479 kDeoptMintBinaryOp,
1480 temp,
1481 right);
1482 __ testq(right, Immediate(kSmiTagMask)); // Argument must be Smi.
1483 __ j(NOT_ZERO, deopt);
1484 __ testq(left, Immediate(kSmiTagMask)); // Receiver can be Smi.
1485 Label two_smi;
1486 __ j(ZERO, &two_smi);
1487 __ CompareClassId(left, kMint); // Receiver must be Mint.
1488 __ j(NOT_EQUAL, deopt);
1489
1490 ASSERT(comp->op_kind() == Token::kBIT_AND);
1491
1492 // Load lower Mint word, convert to Smi. It is OK to loose bits.
1493 ASSERT(result == left);
1494 __ movq(result, FieldAddress(left, Mint::value_offset()));
1495 __ SmiTag(result);
1496 __ Bind(&two_smi);
1497 __ andq(result, right);
1498 }
1499
1500
1457 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, 1501 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
1458 BinaryOpComp* comp) { 1502 BinaryOpComp* comp) {
1459 Register left = comp->locs()->in(0).reg(); 1503 Register left = comp->locs()->in(0).reg();
1460 Register right = comp->locs()->in(1).reg(); 1504 Register right = comp->locs()->in(1).reg();
1461 Register temp = comp->locs()->temp(0).reg(); 1505 Register temp = comp->locs()->temp(0).reg();
1462 Register result = comp->locs()->out().reg(); 1506 Register result = comp->locs()->out().reg();
1463 1507
1464 const Class& double_class = compiler->double_class(); 1508 const Class& double_class = compiler->double_class();
1465 const Code& stub = 1509 const Code& stub =
1466 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1510 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
(...skipping 30 matching lines...) Expand all
1497 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1541 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1498 } 1542 }
1499 1543
1500 1544
1501 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1545 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1502 switch (operands_type()) { 1546 switch (operands_type()) {
1503 case kSmiOperands: 1547 case kSmiOperands:
1504 EmitSmiBinaryOp(compiler, this); 1548 EmitSmiBinaryOp(compiler, this);
1505 break; 1549 break;
1506 1550
1551 case kMintOperands:
1552 EmitMintBinaryOp(compiler, this);
1553 break;
1554
1507 case kDoubleOperands: 1555 case kDoubleOperands:
1508 EmitDoubleBinaryOp(compiler, this); 1556 EmitDoubleBinaryOp(compiler, this);
1509 break; 1557 break;
1510 1558
1511 default: 1559 default:
1512 UNREACHABLE(); 1560 UNREACHABLE();
1513 } 1561 }
1514 } 1562 }
1515 1563
1516 1564
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 instance_call()->argument_names()); 1776 instance_call()->argument_names());
1729 } 1777 }
1730 __ Bind(&done); 1778 __ Bind(&done);
1731 } 1779 }
1732 1780
1733 } // namespace dart 1781 } // namespace dart
1734 1782
1735 #undef __ 1783 #undef __
1736 1784
1737 #endif // defined TARGET_ARCH_X64 1785 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698