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 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 857 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
858 __ movl(EDX, Immediate(arg_count)); | 858 __ movl(EDX, Immediate(arg_count)); |
859 compiler->GenerateCall(token_pos(), | 859 compiler->GenerateCall(token_pos(), |
860 &StubCode::CallNativeCFunctionLabel(), | 860 &StubCode::CallNativeCFunctionLabel(), |
861 PcDescriptors::kOther, | 861 PcDescriptors::kOther, |
862 locs()); | 862 locs()); |
863 __ popl(result); | 863 __ popl(result); |
864 } | 864 } |
865 | 865 |
866 | 866 |
| 867 static bool CanBeImmediateIndex(Value* index) { |
| 868 if (!index->definition()->IsConstant()) return false; |
| 869 const Object& constant = index->definition()->AsConstant()->value(); |
| 870 const Smi& smi_const = Smi::Cast(constant); |
| 871 int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray); |
| 872 return Utils::IsInt(32, disp); |
| 873 } |
| 874 |
| 875 |
867 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 876 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
868 const intptr_t kNumInputs = 2; | 877 const intptr_t kNumInputs = 2; |
869 return LocationSummary::Make(kNumInputs, | 878 const intptr_t kNumTemps = 0; |
870 Location::RequiresRegister(), | 879 LocationSummary* locs = |
871 LocationSummary::kNoCall); | 880 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 881 locs->set_in(0, Location::RequiresRegister()); |
| 882 locs->set_in(1, CanBeImmediateIndex(index()) |
| 883 ? Location::RegisterOrConstant(index()) |
| 884 : Location::RequiresRegister()); |
| 885 locs->set_out(Location::RequiresRegister()); |
| 886 return locs; |
872 } | 887 } |
873 | 888 |
874 | 889 |
875 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 890 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
876 Register array = locs()->in(0).reg(); | 891 Register array = locs()->in(0).reg(); |
877 Register index = locs()->in(1).reg(); | |
878 Register result = locs()->out().reg(); | 892 Register result = locs()->out().reg(); |
879 | 893 Location index = locs()->in(1); |
880 // Note that index is Smi, i.e, times 2. | 894 if (index.IsRegister()) { |
881 ASSERT(kSmiTagShift == 1); | 895 // Note that index is Smi, i.e, times 2. |
882 __ movl(result, FieldAddress(array, index, TIMES_2, sizeof(RawArray))); | 896 ASSERT(kSmiTagShift == 1); |
| 897 __ movl(result, |
| 898 FieldAddress(array, index.reg(), TIMES_2, sizeof(RawArray))); |
| 899 } else { |
| 900 const int32_t disp = |
| 901 Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray); |
| 902 __ movl(result, FieldAddress(array, disp)); |
| 903 } |
883 } | 904 } |
884 | 905 |
885 | 906 |
886 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 907 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
887 const intptr_t kNumInputs = 3; | 908 const intptr_t kNumInputs = 3; |
888 const intptr_t kNumTemps = 0; | 909 const intptr_t kNumTemps = 0; |
889 LocationSummary* locs = | 910 LocationSummary* locs = |
890 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 911 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
891 locs->set_in(0, Location::RequiresRegister()); | 912 locs->set_in(0, Location::RequiresRegister()); |
892 locs->set_in(1, Location::RequiresRegister()); | 913 locs->set_in(1, CanBeImmediateIndex(index()) |
893 locs->set_in(2, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 914 ? Location::RegisterOrConstant(index()) |
894 : Location::RequiresRegister()); | 915 : Location::RequiresRegister()); |
| 916 locs->set_in(2, value()->NeedsStoreBuffer() |
| 917 ? Location::WritableRegister() |
| 918 : Location::RegisterOrConstant(value())); |
895 return locs; | 919 return locs; |
896 } | 920 } |
897 | 921 |
898 | 922 |
899 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 923 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
900 Register array = locs()->in(0).reg(); | 924 Register array = locs()->in(0).reg(); |
901 Register index = locs()->in(1).reg(); | |
902 Register value = locs()->in(2).reg(); | |
903 | 925 |
904 // Note that index is Smi, i.e, times 2. | 926 // Note that index is Smi, i.e, times 2. |
905 ASSERT(kSmiTagShift == 1); | 927 ASSERT(kSmiTagShift == 1); |
| 928 Location index = locs()->in(1); |
| 929 FieldAddress field_address = index.IsConstant() |
| 930 ? FieldAddress( |
| 931 array, |
| 932 Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray)) |
| 933 : FieldAddress(array, index.reg(), TIMES_2, sizeof(RawArray)); |
| 934 |
906 if (this->value()->NeedsStoreBuffer()) { | 935 if (this->value()->NeedsStoreBuffer()) { |
907 __ StoreIntoObject(array, | 936 Register value = locs()->in(2).reg(); |
908 FieldAddress(array, index, TIMES_2, sizeof(RawArray)), | 937 __ StoreIntoObject(array, field_address, value); |
909 value); | |
910 } else { | 938 } else { |
911 __ StoreIntoObjectNoBarrier(array, | 939 if (locs()->in(2).IsConstant()) { |
912 FieldAddress(array, index, TIMES_2, sizeof(RawArray)), | 940 const Object& constant = locs()->in(2).constant(); |
913 value); | 941 __ StoreIntoObjectNoBarrier(array, field_address, constant); |
| 942 } else { |
| 943 Register value = locs()->in(2).reg(); |
| 944 __ StoreIntoObjectNoBarrier(array, field_address, value); |
| 945 } |
914 } | 946 } |
915 } | 947 } |
916 | 948 |
917 | 949 |
918 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { | 950 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { |
919 // TODO(fschneider): For this instruction the input register may be | 951 // TODO(fschneider): For this instruction the input register may be |
920 // reused for the result (but is not required to) because the input | 952 // reused for the result (but is not required to) because the input |
921 // is not used after the result is defined. We should consider adding | 953 // is not used after the result is defined. We should consider adding |
922 // this information to the input policy. | 954 // this information to the input policy. |
923 return LocationSummary::Make(1, | 955 return LocationSummary::Make(1, |
(...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2279 __ j(ABOVE_EQUAL, deopt); | 2311 __ j(ABOVE_EQUAL, deopt); |
2280 } | 2312 } |
2281 } | 2313 } |
2282 | 2314 |
2283 | 2315 |
2284 } // namespace dart | 2316 } // namespace dart |
2285 | 2317 |
2286 #undef __ | 2318 #undef __ |
2287 | 2319 |
2288 #endif // defined TARGET_ARCH_X64 | 2320 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |