| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 522 |
| 523 | 523 |
| 524 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 524 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 525 BranchInstr* branch) { | 525 BranchInstr* branch) { |
| 526 BranchLabels labels = compiler->CreateBranchLabels(branch); | 526 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 527 Condition true_condition = EmitComparisonCode(compiler, labels); | 527 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 528 EmitBranchOnCondition(compiler, true_condition, labels); | 528 EmitBranchOnCondition(compiler, true_condition, labels); |
| 529 } | 529 } |
| 530 | 530 |
| 531 | 531 |
| 532 |
| 533 LocationSummary* TestCidsInstr::MakeLocationSummary(bool opt) const { |
| 534 const intptr_t kNumInputs = 1; |
| 535 const intptr_t kNumTemps = 1; |
| 536 LocationSummary* locs = |
| 537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 538 locs->set_in(0, Location::RequiresRegister()); |
| 539 locs->set_temp(0, Location::RequiresRegister()); |
| 540 locs->set_out(0, Location::RequiresRegister()); |
| 541 return locs; |
| 542 } |
| 543 |
| 544 |
| 545 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 546 BranchLabels labels) { |
| 547 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); |
| 548 Register val_reg = locs()->in(0).reg(); |
| 549 Register cid_reg = locs()->temp(0).reg(); |
| 550 |
| 551 Label* deopt = CanDeoptimize() ? |
| 552 compiler->AddDeoptStub(deopt_id(), kDeoptTestCids) : NULL; |
| 553 |
| 554 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; |
| 555 const ZoneGrowableArray<intptr_t>& data = cid_results(); |
| 556 ASSERT(data[0] == kSmiCid); |
| 557 bool result = data[1] == true_result; |
| 558 __ testq(val_reg, Immediate(kSmiTagMask)); |
| 559 __ j(ZERO, result ? labels.true_label : labels.false_label); |
| 560 __ LoadClassId(cid_reg, val_reg); |
| 561 for (intptr_t i = 2; i < data.length(); i += 2) { |
| 562 const intptr_t test_cid = data[i]; |
| 563 ASSERT(test_cid != kSmiCid); |
| 564 result = data[i + 1] == true_result; |
| 565 __ cmpq(cid_reg, Immediate(test_cid)); |
| 566 __ j(EQUAL, result ? labels.true_label : labels.false_label); |
| 567 } |
| 568 // No match found, deoptimize or false. |
| 569 if (deopt == NULL) { |
| 570 Label* target = result ? labels.false_label : labels.true_label; |
| 571 if (target != labels.fall_through) { |
| 572 __ jmp(target); |
| 573 } |
| 574 } else { |
| 575 __ jmp(deopt); |
| 576 } |
| 577 // Dummy result as the last instruction is a jump, any conditional |
| 578 // branch using the result will therefore be skipped. |
| 579 return ZERO; |
| 580 } |
| 581 |
| 582 |
| 583 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 584 BranchInstr* branch) { |
| 585 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 586 EmitComparisonCode(compiler, labels); |
| 587 } |
| 588 |
| 589 |
| 590 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 591 Register result_reg = locs()->out(0).reg(); |
| 592 Label is_true, is_false, done; |
| 593 BranchLabels labels = { &is_true, &is_false, &is_false }; |
| 594 EmitComparisonCode(compiler, labels); |
| 595 __ Bind(&is_false); |
| 596 __ LoadObject(result_reg, Bool::False(), PP); |
| 597 __ jmp(&done, Assembler::kNearJump); |
| 598 __ Bind(&is_true); |
| 599 __ LoadObject(result_reg, Bool::True(), PP); |
| 600 __ Bind(&done); |
| 601 } |
| 602 |
| 603 |
| 532 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { | 604 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { |
| 533 const intptr_t kNumInputs = 2; | 605 const intptr_t kNumInputs = 2; |
| 534 const intptr_t kNumTemps = 0; | 606 const intptr_t kNumTemps = 0; |
| 535 if (operation_cid() == kDoubleCid) { | 607 if (operation_cid() == kDoubleCid) { |
| 536 LocationSummary* summary = | 608 LocationSummary* summary = |
| 537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 538 summary->set_in(0, Location::RequiresFpuRegister()); | 610 summary->set_in(0, Location::RequiresFpuRegister()); |
| 539 summary->set_in(1, Location::RequiresFpuRegister()); | 611 summary->set_in(1, Location::RequiresFpuRegister()); |
| 540 summary->set_out(0, Location::RequiresRegister()); | 612 summary->set_out(0, Location::RequiresRegister()); |
| 541 return summary; | 613 return summary; |
| (...skipping 4956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5498 PcDescriptors::kOther, | 5570 PcDescriptors::kOther, |
| 5499 locs()); | 5571 locs()); |
| 5500 __ Drop(ArgumentCount()); // Discard arguments. | 5572 __ Drop(ArgumentCount()); // Discard arguments. |
| 5501 } | 5573 } |
| 5502 | 5574 |
| 5503 } // namespace dart | 5575 } // namespace dart |
| 5504 | 5576 |
| 5505 #undef __ | 5577 #undef __ |
| 5506 | 5578 |
| 5507 #endif // defined TARGET_ARCH_X64 | 5579 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |