| 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 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 compiler->GenerateCallRuntime(cid(), | 1247 compiler->GenerateCallRuntime(cid(), |
| 1248 token_index(), | 1248 token_index(), |
| 1249 try_index(), | 1249 try_index(), |
| 1250 kStackOverflowRuntimeEntry); | 1250 kStackOverflowRuntimeEntry); |
| 1251 __ Bind(&no_stack_overflow); | 1251 __ Bind(&no_stack_overflow); |
| 1252 } | 1252 } |
| 1253 | 1253 |
| 1254 | 1254 |
| 1255 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 1255 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 1256 const intptr_t kNumInputs = 2; | 1256 const intptr_t kNumInputs = 2; |
| 1257 |
| 1257 if (operands_type() == kDoubleOperands) { | 1258 if (operands_type() == kDoubleOperands) { |
| 1258 const intptr_t kNumTemps = 1; | 1259 const intptr_t kNumTemps = 1; |
| 1259 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1260 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1260 summary->set_in(0, Location::RequiresRegister()); | 1261 summary->set_in(0, Location::RequiresRegister()); |
| 1261 summary->set_in(1, Location::RequiresRegister()); | 1262 summary->set_in(1, Location::RequiresRegister()); |
| 1262 summary->set_out(Location::RegisterLocation(EAX)); | 1263 summary->set_out(Location::RegisterLocation(EAX)); |
| 1263 summary->set_temp(0, Location::RequiresRegister()); | 1264 summary->set_temp(0, Location::RequiresRegister()); |
| 1264 return summary; | 1265 return summary; |
| 1265 } | 1266 } |
| 1267 |
| 1268 if (operands_type() == kMintOperands) { |
| 1269 ASSERT(op_kind() == Token::kBIT_AND); |
| 1270 const intptr_t kNumTemps = 1; |
| 1271 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1272 summary->set_in(0, Location::RequiresRegister()); |
| 1273 summary->set_in(1, Location::RequiresRegister()); |
| 1274 summary->set_out(Location::SameAsFirstInput()); |
| 1275 summary->set_temp(0, Location::RequiresRegister()); |
| 1276 return summary; |
| 1277 } |
| 1278 |
| 1266 ASSERT(operands_type() == kSmiOperands); | 1279 ASSERT(operands_type() == kSmiOperands); |
| 1280 |
| 1267 if (op_kind() == Token::kTRUNCDIV) { | 1281 if (op_kind() == Token::kTRUNCDIV) { |
| 1268 const intptr_t kNumTemps = 3; | 1282 const intptr_t kNumTemps = 3; |
| 1269 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1283 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1270 summary->set_in(0, Location::RegisterLocation(EAX)); | 1284 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1271 summary->set_in(1, Location::RegisterLocation(ECX)); | 1285 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1272 summary->set_out(Location::SameAsFirstInput()); | 1286 summary->set_out(Location::SameAsFirstInput()); |
| 1273 summary->set_temp(0, Location::RegisterLocation(EBX)); | 1287 summary->set_temp(0, Location::RegisterLocation(EBX)); |
| 1274 // Will be used for for sign extension. | 1288 // Will be used for for sign extension. |
| 1275 summary->set_temp(1, Location::RegisterLocation(EDX)); | 1289 summary->set_temp(1, Location::RegisterLocation(EDX)); |
| 1276 summary->set_temp(2, Location::RequiresRegister()); | 1290 summary->set_temp(2, Location::RequiresRegister()); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1429 UNREACHABLE(); | 1443 UNREACHABLE(); |
| 1430 break; | 1444 break; |
| 1431 } | 1445 } |
| 1432 default: | 1446 default: |
| 1433 UNREACHABLE(); | 1447 UNREACHABLE(); |
| 1434 break; | 1448 break; |
| 1435 } | 1449 } |
| 1436 } | 1450 } |
| 1437 | 1451 |
| 1438 | 1452 |
| 1453 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { |
| 1454 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi |
| 1455 // receiver and a Smi argument. |
| 1456 Register left = comp->locs()->in(0).reg(); |
| 1457 Register right = comp->locs()->in(1).reg(); |
| 1458 Register result = comp->locs()->out().reg(); |
| 1459 Register temp = comp->locs()->temp(0).reg(); |
| 1460 ASSERT(left == result); |
| 1461 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), |
| 1462 comp->instance_call()->token_index(), |
| 1463 comp->instance_call()->try_index(), |
| 1464 kDeoptMintBinaryOp, |
| 1465 temp, |
| 1466 right); |
| 1467 __ testl(right, Immediate(kSmiTagMask)); // Argument must be Smi. |
| 1468 __ j(NOT_ZERO, deopt); |
| 1469 __ testl(left, Immediate(kSmiTagMask)); // Receiver can be Smi. |
| 1470 Label two_smi; |
| 1471 __ j(ZERO, &two_smi); |
| 1472 __ CompareClassId(left, kMint, temp); // Receiver must be Mint. |
| 1473 __ j(NOT_EQUAL, deopt); |
| 1474 |
| 1475 ASSERT(comp->op_kind() == Token::kBIT_AND); |
| 1476 |
| 1477 // Load lower Mint word, convert to Smi. It is OK to loose bits. |
| 1478 ASSERT(result == left); |
| 1479 __ movl(result, FieldAddress(left, Mint::value_offset())); |
| 1480 __ SmiTag(result); |
| 1481 __ Bind(&two_smi); |
| 1482 __ andl(result, right); |
| 1483 } |
| 1484 |
| 1485 |
| 1439 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, | 1486 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, |
| 1440 BinaryOpComp* comp) { | 1487 BinaryOpComp* comp) { |
| 1441 Register left = comp->locs()->in(0).reg(); | 1488 Register left = comp->locs()->in(0).reg(); |
| 1442 Register right = comp->locs()->in(1).reg(); | 1489 Register right = comp->locs()->in(1).reg(); |
| 1443 Register temp = comp->locs()->temp(0).reg(); | 1490 Register temp = comp->locs()->temp(0).reg(); |
| 1444 Register result = comp->locs()->out().reg(); | 1491 Register result = comp->locs()->out().reg(); |
| 1445 | 1492 |
| 1446 const Class& double_class = compiler->double_class(); | 1493 const Class& double_class = compiler->double_class(); |
| 1447 const Code& stub = | 1494 const Code& stub = |
| 1448 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1495 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1479 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1526 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1480 } | 1527 } |
| 1481 | 1528 |
| 1482 | 1529 |
| 1483 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1530 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1484 switch (operands_type()) { | 1531 switch (operands_type()) { |
| 1485 case kSmiOperands: | 1532 case kSmiOperands: |
| 1486 EmitSmiBinaryOp(compiler, this); | 1533 EmitSmiBinaryOp(compiler, this); |
| 1487 break; | 1534 break; |
| 1488 | 1535 |
| 1536 case kMintOperands: |
| 1537 EmitMintBinaryOp(compiler, this); |
| 1538 break; |
| 1539 |
| 1489 case kDoubleOperands: | 1540 case kDoubleOperands: |
| 1490 EmitDoubleBinaryOp(compiler, this); | 1541 EmitDoubleBinaryOp(compiler, this); |
| 1491 break; | 1542 break; |
| 1492 | 1543 |
| 1493 default: | 1544 default: |
| 1494 UNREACHABLE(); | 1545 UNREACHABLE(); |
| 1495 } | 1546 } |
| 1496 } | 1547 } |
| 1497 | 1548 |
| 1498 | 1549 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 } | 1764 } |
| 1714 __ Bind(&done); | 1765 __ Bind(&done); |
| 1715 } | 1766 } |
| 1716 | 1767 |
| 1717 | 1768 |
| 1718 } // namespace dart | 1769 } // namespace dart |
| 1719 | 1770 |
| 1720 #undef __ | 1771 #undef __ |
| 1721 | 1772 |
| 1722 #endif // defined TARGET_ARCH_X64 | 1773 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |