| 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 158 |
| 159 | 159 |
| 160 LocationSummary* ConstantComp::MakeLocationSummary() const { | 160 LocationSummary* ConstantComp::MakeLocationSummary() const { |
| 161 return LocationSummary::Make(0, | 161 return LocationSummary::Make(0, |
| 162 Location::RequiresRegister(), | 162 Location::RequiresRegister(), |
| 163 LocationSummary::kNoCall); | 163 LocationSummary::kNoCall); |
| 164 } | 164 } |
| 165 | 165 |
| 166 | 166 |
| 167 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 167 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 168 Register result = locs()->out().reg(); | 168 // Register allocator drops constant definitions that have no uses. |
| 169 __ LoadObject(result, value()); | 169 if (!locs()->out().IsInvalid()) { |
| 170 Register result = locs()->out().reg(); |
| 171 __ LoadObject(result, value()); |
| 172 } |
| 170 } | 173 } |
| 171 | 174 |
| 172 | 175 |
| 173 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { | 176 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { |
| 174 const intptr_t kNumInputs = 3; | 177 const intptr_t kNumInputs = 3; |
| 175 const intptr_t kNumTemps = 0; | 178 const intptr_t kNumTemps = 0; |
| 176 LocationSummary* summary = | 179 LocationSummary* summary = |
| 177 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 180 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 178 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. | 181 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. |
| 179 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. | 182 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. |
| (...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 | 1428 |
| 1426 __ cmpl(ESP, | 1429 __ cmpl(ESP, |
| 1427 Address::Absolute(Isolate::Current()->stack_limit_address())); | 1430 Address::Absolute(Isolate::Current()->stack_limit_address())); |
| 1428 __ j(BELOW_EQUAL, slow_path->entry_label()); | 1431 __ j(BELOW_EQUAL, slow_path->entry_label()); |
| 1429 __ Bind(slow_path->exit_label()); | 1432 __ Bind(slow_path->exit_label()); |
| 1430 } | 1433 } |
| 1431 | 1434 |
| 1432 | 1435 |
| 1433 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { | 1436 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { |
| 1434 const intptr_t kNumInputs = 2; | 1437 const intptr_t kNumInputs = 2; |
| 1438 |
| 1439 ConstantComp* right_constant = right()->definition()->AsConstant(); |
| 1440 if ((right_constant != NULL) && |
| 1441 (op_kind() != Token::kTRUNCDIV) && |
| 1442 (op_kind() != Token::kSHL)) { |
| 1443 const intptr_t kNumTemps = 0; |
| 1444 LocationSummary* summary = |
| 1445 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1446 summary->set_in(0, Location::RequiresRegister()); |
| 1447 summary->set_in(1, Location::Constant(right_constant->value())); |
| 1448 summary->set_out(Location::SameAsFirstInput()); |
| 1449 return summary; |
| 1450 } |
| 1451 |
| 1435 if (op_kind() == Token::kTRUNCDIV) { | 1452 if (op_kind() == Token::kTRUNCDIV) { |
| 1436 const intptr_t kNumTemps = 3; | 1453 const intptr_t kNumTemps = 3; |
| 1437 LocationSummary* summary = | 1454 LocationSummary* summary = |
| 1438 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1455 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1439 summary->set_in(0, Location::RegisterLocation(EAX)); | 1456 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1440 summary->set_in(1, Location::RegisterLocation(ECX)); | 1457 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1441 summary->set_out(Location::SameAsFirstInput()); | 1458 summary->set_out(Location::SameAsFirstInput()); |
| 1442 summary->set_temp(0, Location::RegisterLocation(EBX)); | 1459 summary->set_temp(0, Location::RegisterLocation(EBX)); |
| 1443 // Will be used for for sign extension. | 1460 // Will be used for for sign extension. |
| 1444 summary->set_temp(1, Location::RegisterLocation(EDX)); | 1461 summary->set_temp(1, Location::RegisterLocation(EDX)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1470 summary->set_in(0, Location::RequiresRegister()); | 1487 summary->set_in(0, Location::RequiresRegister()); |
| 1471 summary->set_in(1, Location::RequiresRegister()); | 1488 summary->set_in(1, Location::RequiresRegister()); |
| 1472 summary->set_out(Location::SameAsFirstInput()); | 1489 summary->set_out(Location::SameAsFirstInput()); |
| 1473 return summary; | 1490 return summary; |
| 1474 } | 1491 } |
| 1475 } | 1492 } |
| 1476 | 1493 |
| 1477 | 1494 |
| 1478 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1495 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1479 Register left = locs()->in(0).reg(); | 1496 Register left = locs()->in(0).reg(); |
| 1480 Register right = locs()->in(1).reg(); | |
| 1481 Register result = locs()->out().reg(); | 1497 Register result = locs()->out().reg(); |
| 1482 ASSERT(left == result); | 1498 ASSERT(left == result); |
| 1483 Label* deopt = NULL; | 1499 Label* deopt = NULL; |
| 1484 switch (op_kind()) { | 1500 switch (op_kind()) { |
| 1485 case Token::kBIT_AND: | 1501 case Token::kBIT_AND: |
| 1486 case Token::kBIT_OR: | 1502 case Token::kBIT_OR: |
| 1487 case Token::kBIT_XOR: | 1503 case Token::kBIT_XOR: |
| 1488 // Can't deoptimize. Arguments are already checked for smi. | 1504 // Can't deoptimize. Arguments are already checked for smi. |
| 1489 break; | 1505 break; |
| 1490 default: | 1506 default: |
| 1491 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1507 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1492 kDeoptBinarySmiOp); | 1508 kDeoptBinarySmiOp); |
| 1493 } | 1509 } |
| 1494 | 1510 |
| 1511 if (locs()->in(1).IsConstant()) { |
| 1512 const Object& constant = locs()->in(1).constant(); |
| 1513 ASSERT(constant.IsSmi()); |
| 1514 const int32_t imm = |
| 1515 reinterpret_cast<int32_t>(constant.raw()); |
| 1516 switch (op_kind()) { |
| 1517 case Token::kADD: |
| 1518 __ addl(left, Immediate(imm)); |
| 1519 __ j(OVERFLOW, deopt); |
| 1520 break; |
| 1521 case Token::kSUB: { |
| 1522 __ subl(left, Immediate(imm)); |
| 1523 __ j(OVERFLOW, deopt); |
| 1524 break; |
| 1525 } |
| 1526 case Token::kMUL: { |
| 1527 // Keep left value tagged and untag right value. |
| 1528 const intptr_t value = Smi::Cast(constant).Value(); |
| 1529 __ imull(left, Immediate(value)); |
| 1530 __ j(OVERFLOW, deopt); |
| 1531 break; |
| 1532 } |
| 1533 case Token::kBIT_AND: { |
| 1534 // No overflow check. |
| 1535 __ andl(left, Immediate(imm)); |
| 1536 break; |
| 1537 } |
| 1538 case Token::kBIT_OR: { |
| 1539 // No overflow check. |
| 1540 __ orl(left, Immediate(imm)); |
| 1541 break; |
| 1542 } |
| 1543 case Token::kBIT_XOR: { |
| 1544 // No overflow check. |
| 1545 __ xorl(left, Immediate(imm)); |
| 1546 break; |
| 1547 } |
| 1548 case Token::kSHR: { |
| 1549 // sarl operation masks the count to 5 bits. |
| 1550 const intptr_t kCountLimit = 0x1F; |
| 1551 intptr_t value = Smi::Cast(constant).Value(); |
| 1552 |
| 1553 if (value == 0) { |
| 1554 // TODO(vegorov): should be handled outside. |
| 1555 break; |
| 1556 } else if (value < 0) { |
| 1557 // TODO(vegorov): should be handled outside. |
| 1558 __ jmp(deopt); |
| 1559 break; |
| 1560 } |
| 1561 |
| 1562 value = value + kSmiTagSize; |
| 1563 if (value >= kCountLimit) value = kCountLimit; |
| 1564 |
| 1565 __ sarl(left, Immediate(value)); |
| 1566 __ SmiTag(left); |
| 1567 break; |
| 1568 } |
| 1569 |
| 1570 default: |
| 1571 UNREACHABLE(); |
| 1572 break; |
| 1573 } |
| 1574 return; |
| 1575 } |
| 1576 |
| 1577 Register right = locs()->in(1).reg(); |
| 1495 switch (op_kind()) { | 1578 switch (op_kind()) { |
| 1496 case Token::kADD: { | 1579 case Token::kADD: { |
| 1497 __ addl(left, right); | 1580 __ addl(left, right); |
| 1498 __ j(OVERFLOW, deopt); | 1581 __ j(OVERFLOW, deopt); |
| 1499 break; | 1582 break; |
| 1500 } | 1583 } |
| 1501 case Token::kSUB: { | 1584 case Token::kSUB: { |
| 1502 __ subl(left, right); | 1585 __ subl(left, right); |
| 1503 __ j(OVERFLOW, deopt); | 1586 __ j(OVERFLOW, deopt); |
| 1504 break; | 1587 break; |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2184 } | 2267 } |
| 2185 __ j(ABOVE_EQUAL, deopt); | 2268 __ j(ABOVE_EQUAL, deopt); |
| 2186 } | 2269 } |
| 2187 | 2270 |
| 2188 | 2271 |
| 2189 } // namespace dart | 2272 } // namespace dart |
| 2190 | 2273 |
| 2191 #undef __ | 2274 #undef __ |
| 2192 | 2275 |
| 2193 #endif // defined TARGET_ARCH_X64 | 2276 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |