| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |