| 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_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 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 compiler->GenerateCallRuntime(cid(), | 1277 compiler->GenerateCallRuntime(cid(), |
| 1278 token_index(), | 1278 token_index(), |
| 1279 try_index(), | 1279 try_index(), |
| 1280 kStackOverflowRuntimeEntry); | 1280 kStackOverflowRuntimeEntry); |
| 1281 __ Bind(&no_stack_overflow); | 1281 __ Bind(&no_stack_overflow); |
| 1282 } | 1282 } |
| 1283 | 1283 |
| 1284 | 1284 |
| 1285 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 1285 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 1286 const intptr_t kNumInputs = 2; | 1286 const intptr_t kNumInputs = 2; |
| 1287 |
| 1287 if (operands_type() == kDoubleOperands) { | 1288 if (operands_type() == kDoubleOperands) { |
| 1288 return MakeCallSummary(); // Calls into a stub for allocation. | 1289 return MakeCallSummary(); // Calls into a stub for allocation. |
| 1289 } | 1290 } |
| 1291 |
| 1292 if (operands_type() == kMintOperands) { |
| 1293 ASSERT(op_kind() == Token::kBIT_AND); |
| 1294 const intptr_t kNumTemps = 1; |
| 1295 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1296 summary->set_in(0, Location::RequiresRegister()); |
| 1297 summary->set_in(1, Location::RequiresRegister()); |
| 1298 summary->set_out(Location::SameAsFirstInput()); |
| 1299 summary->set_temp(0, Location::RequiresRegister()); |
| 1300 return summary; |
| 1301 } |
| 1302 |
| 1290 ASSERT(operands_type() == kSmiOperands); | 1303 ASSERT(operands_type() == kSmiOperands); |
| 1304 |
| 1291 if (op_kind() == Token::kTRUNCDIV) { | 1305 if (op_kind() == Token::kTRUNCDIV) { |
| 1292 const intptr_t kNumTemps = 3; | 1306 const intptr_t kNumTemps = 3; |
| 1293 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1307 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1294 summary->set_in(0, Location::RegisterLocation(EAX)); | 1308 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1295 summary->set_in(1, Location::RegisterLocation(ECX)); | 1309 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1296 summary->set_out(Location::SameAsFirstInput()); | 1310 summary->set_out(Location::SameAsFirstInput()); |
| 1297 summary->set_temp(0, Location::RegisterLocation(EBX)); | 1311 summary->set_temp(0, Location::RegisterLocation(EBX)); |
| 1298 // Will be used for for sign extension. | 1312 // Will be used for for sign extension. |
| 1299 summary->set_temp(1, Location::RegisterLocation(EDX)); | 1313 summary->set_temp(1, Location::RegisterLocation(EDX)); |
| 1300 summary->set_temp(2, Location::RequiresRegister()); | 1314 summary->set_temp(2, Location::RequiresRegister()); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 UNREACHABLE(); | 1469 UNREACHABLE(); |
| 1456 break; | 1470 break; |
| 1457 } | 1471 } |
| 1458 default: | 1472 default: |
| 1459 UNREACHABLE(); | 1473 UNREACHABLE(); |
| 1460 break; | 1474 break; |
| 1461 } | 1475 } |
| 1462 } | 1476 } |
| 1463 | 1477 |
| 1464 | 1478 |
| 1479 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { |
| 1480 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi |
| 1481 // receiver and a Smi argument. |
| 1482 Register left = comp->locs()->in(0).reg(); |
| 1483 Register right = comp->locs()->in(1).reg(); |
| 1484 Register result = comp->locs()->out().reg(); |
| 1485 Register temp = comp->locs()->temp(0).reg(); |
| 1486 ASSERT(left == result); |
| 1487 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), |
| 1488 comp->instance_call()->token_index(), |
| 1489 comp->instance_call()->try_index(), |
| 1490 kDeoptMintBinaryOp, |
| 1491 temp, |
| 1492 right); |
| 1493 __ testl(right, Immediate(kSmiTagMask)); // Argument must be Smi. |
| 1494 __ j(NOT_ZERO, deopt); |
| 1495 __ testl(left, Immediate(kSmiTagMask)); // Receiver can be Smi. |
| 1496 Label two_smi; |
| 1497 __ j(ZERO, &two_smi); |
| 1498 __ CompareClassId(left, kMint, temp); // Receiver must be Mint. |
| 1499 __ j(NOT_EQUAL, deopt); |
| 1500 |
| 1501 ASSERT(comp->op_kind() == Token::kBIT_AND); |
| 1502 |
| 1503 // Load lower Mint word, convert to Smi. It is OK to loose bits. |
| 1504 ASSERT(result == left); |
| 1505 __ movl(result, FieldAddress(left, Mint::value_offset())); |
| 1506 __ SmiTag(result); |
| 1507 __ Bind(&two_smi); |
| 1508 __ andl(result, right); |
| 1509 } |
| 1510 |
| 1511 |
| 1465 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, | 1512 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, |
| 1466 BinaryOpComp* comp) { | 1513 BinaryOpComp* comp) { |
| 1467 Register left = EBX; | 1514 Register left = EBX; |
| 1468 Register right = ECX; | 1515 Register right = ECX; |
| 1469 Register temp = EDX; | 1516 Register temp = EDX; |
| 1470 Register result = comp->locs()->out().reg(); | 1517 Register result = comp->locs()->out().reg(); |
| 1471 | 1518 |
| 1472 const Class& double_class = compiler->double_class(); | 1519 const Class& double_class = compiler->double_class(); |
| 1473 const Code& stub = | 1520 const Code& stub = |
| 1474 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1521 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1503 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1550 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1504 } | 1551 } |
| 1505 | 1552 |
| 1506 | 1553 |
| 1507 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1554 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1508 switch (operands_type()) { | 1555 switch (operands_type()) { |
| 1509 case kSmiOperands: | 1556 case kSmiOperands: |
| 1510 EmitSmiBinaryOp(compiler, this); | 1557 EmitSmiBinaryOp(compiler, this); |
| 1511 break; | 1558 break; |
| 1512 | 1559 |
| 1560 case kMintOperands: |
| 1561 EmitMintBinaryOp(compiler, this); |
| 1562 break; |
| 1563 |
| 1513 case kDoubleOperands: | 1564 case kDoubleOperands: |
| 1514 EmitDoubleBinaryOp(compiler, this); | 1565 EmitDoubleBinaryOp(compiler, this); |
| 1515 break; | 1566 break; |
| 1516 | 1567 |
| 1517 default: | 1568 default: |
| 1518 UNREACHABLE(); | 1569 UNREACHABLE(); |
| 1519 } | 1570 } |
| 1520 } | 1571 } |
| 1521 | 1572 |
| 1522 | 1573 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1739 } | 1790 } |
| 1740 __ Bind(&done); | 1791 __ Bind(&done); |
| 1741 } | 1792 } |
| 1742 | 1793 |
| 1743 | 1794 |
| 1744 } // namespace dart | 1795 } // namespace dart |
| 1745 | 1796 |
| 1746 #undef __ | 1797 #undef __ |
| 1747 | 1798 |
| 1748 #endif // defined TARGET_ARCH_X64 | 1799 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |