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_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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 case BELOW_EQUAL: return ABOVE; | 319 case BELOW_EQUAL: return ABOVE; |
320 case ABOVE: return BELOW_EQUAL; | 320 case ABOVE: return BELOW_EQUAL; |
321 case ABOVE_EQUAL: return BELOW; | 321 case ABOVE_EQUAL: return BELOW; |
322 default: | 322 default: |
323 UNIMPLEMENTED(); | 323 UNIMPLEMENTED(); |
324 return EQUAL; | 324 return EQUAL; |
325 } | 325 } |
326 } | 326 } |
327 | 327 |
328 | 328 |
329 static void EmitBranchOnValue(FlowGraphCompiler* compiler, | |
330 TargetEntryInstr* true_successor, | |
331 TargetEntryInstr* false_successor, | |
332 bool value) { | |
333 if (value && !compiler->CanFallThroughTo(true_successor)) { | |
334 __ jmp(compiler->GetJumpLabel(true_successor)); | |
335 } else if (!value && !compiler->CanFallThroughTo(false_successor)) { | |
336 __ jmp(compiler->GetJumpLabel(false_successor)); | |
337 } | |
338 } | |
339 | |
340 | |
341 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, | 329 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
342 TargetEntryInstr* true_successor, | 330 TargetEntryInstr* true_successor, |
343 TargetEntryInstr* false_successor, | 331 TargetEntryInstr* false_successor, |
344 Condition true_condition) { | 332 Condition true_condition) { |
345 if (compiler->CanFallThroughTo(false_successor)) { | 333 if (compiler->CanFallThroughTo(false_successor)) { |
346 // If the next block is the false successor, fall through to it. | 334 // If the next block is the false successor, fall through to it. |
347 __ j(true_condition, compiler->GetJumpLabel(true_successor)); | 335 __ j(true_condition, compiler->GetJumpLabel(true_successor)); |
348 } else { | 336 } else { |
349 // If the next block is not the false successor, branch to it. | 337 // If the next block is not the false successor, branch to it. |
350 Condition false_condition = NegateCondition(true_condition); | 338 Condition false_condition = NegateCondition(true_condition); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 return; | 613 return; |
626 } | 614 } |
627 UNREACHABLE(); | 615 UNREACHABLE(); |
628 } | 616 } |
629 | 617 |
630 | 618 |
631 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 619 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
632 BranchInstr* branch) { | 620 BranchInstr* branch) { |
633 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 621 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
634 if (operation_cid() == kSmiCid) { | 622 if (operation_cid() == kSmiCid) { |
635 // Deoptimizes if both arguments not Smi. | |
636 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 623 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
637 return; | 624 return; |
638 } | 625 } |
639 if (operation_cid() == kMintCid) { | 626 if (operation_cid() == kMintCid) { |
640 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 627 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
641 return; | 628 return; |
642 } | 629 } |
643 if (operation_cid() == kDoubleCid) { | 630 if (operation_cid() == kDoubleCid) { |
644 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 631 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
645 return; | 632 return; |
(...skipping 4005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4651 LocationSummary* locs = | 4638 LocationSummary* locs = |
4652 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4639 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
4653 locs->set_in(0, Location::RegisterLocation(EAX)); | 4640 locs->set_in(0, Location::RegisterLocation(EAX)); |
4654 locs->set_in(1, Location::RegisterLocation(ECX)); | 4641 locs->set_in(1, Location::RegisterLocation(ECX)); |
4655 locs->set_out(Location::RegisterLocation(EAX)); | 4642 locs->set_out(Location::RegisterLocation(EAX)); |
4656 return locs; | 4643 return locs; |
4657 } | 4644 } |
4658 LocationSummary* locs = | 4645 LocationSummary* locs = |
4659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4646 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4660 locs->set_in(0, Location::RegisterOrConstant(left())); | 4647 locs->set_in(0, Location::RegisterOrConstant(left())); |
4661 locs->set_in(1, Location::RegisterOrConstant(right())); | 4648 // Only one of the inputs can be a constant. Choose register if the first one |
| 4649 // is a constant. |
| 4650 locs->set_in(1, locs->in(0).IsConstant() |
| 4651 ? Location::RequiresRegister() |
| 4652 : Location::RegisterOrConstant(right())); |
4662 locs->set_out(Location::RequiresRegister()); | 4653 locs->set_out(Location::RequiresRegister()); |
4663 return locs; | 4654 return locs; |
4664 } | 4655 } |
4665 | 4656 |
4666 | 4657 |
4667 // Special code for numbers (compare values instead of references.) | 4658 // Special code for numbers (compare values instead of references.) |
4668 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4659 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4669 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4660 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
4670 Location left = locs()->in(0); | 4661 Location left = locs()->in(0); |
4671 Location right = locs()->in(1); | 4662 Location right = locs()->in(1); |
4672 if (left.IsConstant() && right.IsConstant()) { | 4663 ASSERT(!left.IsConstant() || !right.IsConstant()); |
4673 // TODO(vegorov): should be eliminated earlier by constant propagation. | |
4674 const bool result = (kind() == Token::kEQ_STRICT) ? | |
4675 left.constant().raw() == right.constant().raw() : | |
4676 left.constant().raw() != right.constant().raw(); | |
4677 __ LoadObject(locs()->out().reg(), Bool::Get(result)); | |
4678 return; | |
4679 } | |
4680 if (left.IsConstant()) { | 4664 if (left.IsConstant()) { |
4681 compiler->EmitEqualityRegConstCompare(right.reg(), | 4665 compiler->EmitEqualityRegConstCompare(right.reg(), |
4682 left.constant(), | 4666 left.constant(), |
4683 needs_number_check(), | 4667 needs_number_check(), |
4684 token_pos()); | 4668 token_pos()); |
4685 } else if (right.IsConstant()) { | 4669 } else if (right.IsConstant()) { |
4686 compiler->EmitEqualityRegConstCompare(left.reg(), | 4670 compiler->EmitEqualityRegConstCompare(left.reg(), |
4687 right.constant(), | 4671 right.constant(), |
4688 needs_number_check(), | 4672 needs_number_check(), |
4689 token_pos()); | 4673 token_pos()); |
(...skipping 14 matching lines...) Expand all Loading... |
4704 __ LoadObject(result, Bool::True()); | 4688 __ LoadObject(result, Bool::True()); |
4705 __ Bind(&done); | 4689 __ Bind(&done); |
4706 } | 4690 } |
4707 | 4691 |
4708 | 4692 |
4709 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 4693 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
4710 BranchInstr* branch) { | 4694 BranchInstr* branch) { |
4711 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4695 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
4712 Location left = locs()->in(0); | 4696 Location left = locs()->in(0); |
4713 Location right = locs()->in(1); | 4697 Location right = locs()->in(1); |
4714 if (left.IsConstant() && right.IsConstant()) { | 4698 ASSERT(!left.IsConstant() || !right.IsConstant()); |
4715 // TODO(vegorov): should be eliminated earlier by constant propagation. | |
4716 const bool result = (kind() == Token::kEQ_STRICT) ? | |
4717 left.constant().raw() == right.constant().raw() : | |
4718 left.constant().raw() != right.constant().raw(); | |
4719 EmitBranchOnValue(compiler, | |
4720 branch->true_successor(), | |
4721 branch->false_successor(), | |
4722 result); | |
4723 return; | |
4724 } | |
4725 if (left.IsConstant()) { | 4699 if (left.IsConstant()) { |
4726 compiler->EmitEqualityRegConstCompare(right.reg(), | 4700 compiler->EmitEqualityRegConstCompare(right.reg(), |
4727 left.constant(), | 4701 left.constant(), |
4728 needs_number_check(), | 4702 needs_number_check(), |
4729 token_pos()); | 4703 token_pos()); |
4730 } else if (right.IsConstant()) { | 4704 } else if (right.IsConstant()) { |
4731 compiler->EmitEqualityRegConstCompare(left.reg(), | 4705 compiler->EmitEqualityRegConstCompare(left.reg(), |
4732 right.constant(), | 4706 right.constant(), |
4733 needs_number_check(), | 4707 needs_number_check(), |
4734 token_pos()); | 4708 token_pos()); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4952 PcDescriptors::kOther, | 4926 PcDescriptors::kOther, |
4953 locs()); | 4927 locs()); |
4954 __ Drop(2); // Discard type arguments and receiver. | 4928 __ Drop(2); // Discard type arguments and receiver. |
4955 } | 4929 } |
4956 | 4930 |
4957 } // namespace dart | 4931 } // namespace dart |
4958 | 4932 |
4959 #undef __ | 4933 #undef __ |
4960 | 4934 |
4961 #endif // defined TARGET_ARCH_IA32 | 4935 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |