| 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 |