| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 ASSERT(stack_trace()->IsUse()); | 733 ASSERT(stack_trace()->IsUse()); |
| 734 compiler->GenerateCallRuntime(cid(), | 734 compiler->GenerateCallRuntime(cid(), |
| 735 token_index(), | 735 token_index(), |
| 736 try_index(), | 736 try_index(), |
| 737 kReThrowRuntimeEntry); | 737 kReThrowRuntimeEntry); |
| 738 __ int3(); | 738 __ int3(); |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 LocationSummary* BranchInstr::MakeLocationSummary() const { | 742 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 743 const int kNumInputs = 1; | 743 if (is_fused_with_comparison()) { |
| 744 const int kNumTemps = 0; | 744 return LocationSummary::Make(0, Location::NoLocation()); |
| 745 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 745 } else { |
| 746 locs->set_in(0, Location::RequiresRegister()); | 746 const int kNumInputs = 1; |
| 747 return locs; | 747 const int kNumTemps = 0; |
| 748 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 749 locs->set_in(0, Location::RequiresRegister()); |
| 750 return locs; |
| 751 } |
| 748 } | 752 } |
| 749 | 753 |
| 750 | 754 |
| 751 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 755 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 752 Register value = locs()->in(0).reg(); | 756 // If branch was fused with a comparision then no code needs to be emitted. |
| 753 __ CompareObject(value, Bool::ZoneHandle(Bool::True())); | 757 if (!is_fused_with_comparison()) { |
| 754 if (compiler->IsNextBlock(false_successor())) { | 758 Register value = locs()->in(0).reg(); |
| 755 // If the next block is the false successor we will fall through to it if | 759 __ CompareObject(value, compiler->bool_true()); |
| 756 // comparison with true fails. | 760 EmitBranchOnCondition(compiler, EQUAL); |
| 757 __ j(EQUAL, compiler->GetBlockLabel(true_successor())); | |
| 758 } else { | |
| 759 ASSERT(compiler->IsNextBlock(true_successor())); | |
| 760 // If the next block is the true successor we negate comparison and fall | |
| 761 // through to it. | |
| 762 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor())); | |
| 763 } | 761 } |
| 764 } | 762 } |
| 765 | 763 |
| 764 |
| 765 static Condition NegateCondition(Condition condition) { |
| 766 switch (condition) { |
| 767 case EQUAL: return NOT_EQUAL; |
| 768 case NOT_EQUAL: return EQUAL; |
| 769 case LESS: return GREATER_EQUAL; |
| 770 case LESS_EQUAL: return GREATER; |
| 771 case GREATER: return LESS_EQUAL; |
| 772 case GREATER_EQUAL: return LESS; |
| 773 case BELOW: return ABOVE_EQUAL; |
| 774 case BELOW_EQUAL: return ABOVE; |
| 775 case ABOVE: return BELOW_EQUAL; |
| 776 case ABOVE_EQUAL: return BELOW; |
| 777 default: |
| 778 OS::Print("Error %d\n", condition); |
| 779 UNIMPLEMENTED(); |
| 780 return EQUAL; |
| 781 } |
| 782 } |
| 783 |
| 784 |
| 785 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 786 Condition true_condition) { |
| 787 if (compiler->IsNextBlock(false_successor())) { |
| 788 // If the next block is the false successor we will fall through to it. |
| 789 __ j(true_condition, compiler->GetBlockLabel(true_successor())); |
| 790 } else { |
| 791 // If the next block is the true successor we negate comparison and fall |
| 792 // through to it. |
| 793 ASSERT(compiler->IsNextBlock(true_successor())); |
| 794 Condition false_condition = NegateCondition(true_condition); |
| 795 __ j(false_condition, compiler->GetBlockLabel(false_successor())); |
| 796 } |
| 797 } |
| 798 |
| 766 | 799 |
| 767 LocationSummary* CurrentContextComp::MakeLocationSummary() const { | 800 LocationSummary* CurrentContextComp::MakeLocationSummary() const { |
| 768 return LocationSummary::Make(0, Location::RequiresRegister()); | 801 return LocationSummary::Make(0, Location::RequiresRegister()); |
| 769 } | 802 } |
| 770 | 803 |
| 771 | 804 |
| 772 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 805 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 773 __ MoveRegister(locs()->out().reg(), CTX); | 806 __ MoveRegister(locs()->out().reg(), CTX); |
| 774 } | 807 } |
| 775 | 808 |
| 776 | 809 |
| 777 LocationSummary* StoreContextComp::MakeLocationSummary() const { | 810 LocationSummary* StoreContextComp::MakeLocationSummary() const { |
| 778 const intptr_t kNumInputs = 1; | 811 const intptr_t kNumInputs = 1; |
| 779 const intptr_t kNumTemps = 0; | 812 const intptr_t kNumTemps = 0; |
| 780 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 813 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 781 summary->set_in(0, Location::RegisterLocation(CTX)); | 814 summary->set_in(0, Location::RegisterLocation(CTX)); |
| 782 return summary; | 815 return summary; |
| 783 } | 816 } |
| 784 | 817 |
| 785 | 818 |
| 786 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 819 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 787 // Nothing to do. Context register were loaded by register allocator. | 820 // Nothing to do. Context register were loaded by register allocator. |
| 788 ASSERT(locs()->in(0).reg() == CTX); | 821 ASSERT(locs()->in(0).reg() == CTX); |
| 789 } | 822 } |
| 790 | 823 |
| 791 | 824 |
| 792 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 825 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
| 793 return LocationSummary::Make(2, Location::SameAsFirstInput()); | 826 if (!is_fused_with_branch()) { |
| 827 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
| 828 } else { |
| 829 return LocationSummary::Make(2, Location::NoLocation()); |
| 830 } |
| 794 } | 831 } |
| 795 | 832 |
| 796 | 833 |
| 797 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 834 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 798 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 799 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 800 | |
| 801 Register left = locs()->in(0).reg(); | 835 Register left = locs()->in(0).reg(); |
| 802 Register right = locs()->in(1).reg(); | 836 Register right = locs()->in(1).reg(); |
| 803 Register result = locs()->out().reg(); | |
| 804 | 837 |
| 838 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 839 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 805 __ CompareRegisters(left, right); | 840 __ CompareRegisters(left, right); |
| 806 Label load_true, done; | 841 |
| 807 if (kind() == Token::kEQ_STRICT) { | 842 if (!is_fused_with_branch()) { |
| 808 __ j(EQUAL, &load_true, Assembler::kNearJump); | 843 Register result = locs()->out().reg(); |
| 844 Label load_true, done; |
| 845 __ j(true_condition, &load_true, Assembler::kNearJump); |
| 846 __ LoadObject(result, compiler->bool_false()); |
| 847 __ jmp(&done, Assembler::kNearJump); |
| 848 __ Bind(&load_true); |
| 849 __ LoadObject(result, compiler->bool_true()); |
| 850 __ Bind(&done); |
| 809 } else { | 851 } else { |
| 810 ASSERT(kind() == Token::kNE_STRICT); | 852 fused_with_branch()->EmitBranchOnCondition(compiler, true_condition); |
| 811 __ j(NOT_EQUAL, &load_true, Assembler::kNearJump); | |
| 812 } | 853 } |
| 813 __ LoadObject(result, bool_false); | |
| 814 __ jmp(&done, Assembler::kNearJump); | |
| 815 __ Bind(&load_true); | |
| 816 __ LoadObject(result, bool_true); | |
| 817 __ Bind(&done); | |
| 818 } | 854 } |
| 819 | 855 |
| 820 | 856 |
| 821 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 857 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 822 ASSERT(VerifyCallComputation(this)); | 858 ASSERT(VerifyCallComputation(this)); |
| 823 // The arguments to the stub include the closure. The arguments | 859 // The arguments to the stub include the closure. The arguments |
| 824 // descriptor describes the closure's arguments (and so does not include | 860 // descriptor describes the closure's arguments (and so does not include |
| 825 // the closure). | 861 // the closure). |
| 826 Register temp_reg = locs()->temp(0).reg(); | 862 Register temp_reg = locs()->temp(0).reg(); |
| 827 int argument_count = ArgumentCount(); | 863 int argument_count = ArgumentCount(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 | 957 |
| 922 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { | 958 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { |
| 923 return LocationSummary::Make(1, Location::RequiresRegister()); | 959 return LocationSummary::Make(1, Location::RequiresRegister()); |
| 924 } | 960 } |
| 925 | 961 |
| 926 | 962 |
| 927 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 963 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 928 Register value = locs()->in(0).reg(); | 964 Register value = locs()->in(0).reg(); |
| 929 Register result = locs()->out().reg(); | 965 Register result = locs()->out().reg(); |
| 930 | 966 |
| 931 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 932 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 933 Label done; | 967 Label done; |
| 934 __ LoadObject(result, bool_true); | 968 __ LoadObject(result, compiler->bool_true()); |
| 935 __ CompareRegisters(result, value); | 969 __ CompareRegisters(result, value); |
| 936 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 970 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 937 __ LoadObject(result, bool_false); | 971 __ LoadObject(result, compiler->bool_false()); |
| 938 __ Bind(&done); | 972 __ Bind(&done); |
| 939 } | 973 } |
| 940 | 974 |
| 941 | 975 |
| 942 LocationSummary* ChainContextComp::MakeLocationSummary() const { | 976 LocationSummary* ChainContextComp::MakeLocationSummary() const { |
| 943 return LocationSummary::Make(1, Location::NoLocation()); | 977 return LocationSummary::Make(1, Location::NoLocation()); |
| 944 } | 978 } |
| 945 | 979 |
| 946 | 980 |
| 947 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 981 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 StubCode::GetAllocationStubForClosure(closure_function)); | 1033 StubCode::GetAllocationStubForClosure(closure_function)); |
| 1000 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1034 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1001 compiler->GenerateCall(token_index(), try_index(), &label, | 1035 compiler->GenerateCall(token_index(), try_index(), &label, |
| 1002 PcDescriptors::kOther); | 1036 PcDescriptors::kOther); |
| 1003 __ Drop(2); // Discard type arguments and receiver. | 1037 __ Drop(2); // Discard type arguments and receiver. |
| 1004 } | 1038 } |
| 1005 | 1039 |
| 1006 #undef __ | 1040 #undef __ |
| 1007 | 1041 |
| 1008 } // namespace dart | 1042 } // namespace dart |
| OLD | NEW |