| 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 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 locs()); | 744 locs()); |
| 745 __ popq(result); | 745 __ popq(result); |
| 746 } | 746 } |
| 747 | 747 |
| 748 | 748 |
| 749 static bool CanBeImmediateIndex(Value* index, intptr_t cid) { | 749 static bool CanBeImmediateIndex(Value* index, intptr_t cid) { |
| 750 if (!index->definition()->IsConstant()) return false; | 750 if (!index->definition()->IsConstant()) return false; |
| 751 const Object& constant = index->definition()->AsConstant()->value(); | 751 const Object& constant = index->definition()->AsConstant()->value(); |
| 752 if (!constant.IsSmi()) return false; | 752 if (!constant.IsSmi()) return false; |
| 753 const Smi& smi_const = Smi::Cast(constant); | 753 const Smi& smi_const = Smi::Cast(constant); |
| 754 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); | 754 const intptr_t scale = Instance::ElementSizeFor(cid); |
| 755 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); | 755 const intptr_t data_offset = Instance::DataOffsetFor(cid); |
| 756 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; | 756 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
| 757 return Utils::IsInt(32, disp); | 757 return Utils::IsInt(32, disp); |
| 758 } | 758 } |
| 759 | 759 |
| 760 | 760 |
| 761 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Isolate* isolate, | 761 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Isolate* isolate, |
| 762 bool opt) const { | 762 bool opt) const { |
| 763 const intptr_t kNumInputs = 1; | 763 const intptr_t kNumInputs = 1; |
| 764 // TODO(fschneider): Allow immediate operands for the char code. | 764 // TODO(fschneider): Allow immediate operands for the char code. |
| 765 return LocationSummary::Make(kNumInputs, | 765 return LocationSummary::Make(kNumInputs, |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 (representation() == kUnboxedInt32x4) || | 966 (representation() == kUnboxedInt32x4) || |
| 967 (representation() == kUnboxedFloat64x2)) { | 967 (representation() == kUnboxedFloat64x2)) { |
| 968 locs->set_out(0, Location::RequiresFpuRegister()); | 968 locs->set_out(0, Location::RequiresFpuRegister()); |
| 969 } else { | 969 } else { |
| 970 locs->set_out(0, Location::RequiresRegister()); | 970 locs->set_out(0, Location::RequiresRegister()); |
| 971 } | 971 } |
| 972 return locs; | 972 return locs; |
| 973 } | 973 } |
| 974 | 974 |
| 975 | 975 |
| 976 static Address ElementAddressForIntIndex(bool is_external, |
| 977 intptr_t cid, |
| 978 intptr_t index_scale, |
| 979 Register array, |
| 980 intptr_t index) { |
| 981 if (is_external) { |
| 982 return Address(array, index * index_scale); |
| 983 } else { |
| 984 const int64_t disp = static_cast<int64_t>(index) * index_scale + |
| 985 Instance::DataOffsetFor(cid); |
| 986 ASSERT(Utils::IsInt(32, disp)); |
| 987 return FieldAddress(array, static_cast<int32_t>(disp)); |
| 988 } |
| 989 } |
| 990 |
| 991 |
| 992 static ScaleFactor ToScaleFactor(intptr_t index_scale) { |
| 993 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with |
| 994 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is |
| 995 // expected to be untagged before accessing. |
| 996 ASSERT(kSmiTagShift == 1); |
| 997 switch (index_scale) { |
| 998 case 1: return TIMES_1; |
| 999 case 2: return TIMES_1; |
| 1000 case 4: return TIMES_2; |
| 1001 case 8: return TIMES_4; |
| 1002 case 16: return TIMES_8; |
| 1003 default: |
| 1004 UNREACHABLE(); |
| 1005 return TIMES_1; |
| 1006 } |
| 1007 } |
| 1008 |
| 1009 |
| 1010 static Address ElementAddressForRegIndex(bool is_external, |
| 1011 intptr_t cid, |
| 1012 intptr_t index_scale, |
| 1013 Register array, |
| 1014 Register index) { |
| 1015 if (is_external) { |
| 1016 return Address(array, index, ToScaleFactor(index_scale), 0); |
| 1017 } else { |
| 1018 return FieldAddress(array, |
| 1019 index, |
| 1020 ToScaleFactor(index_scale), |
| 1021 Instance::DataOffsetFor(cid)); |
| 1022 } |
| 1023 } |
| 1024 |
| 1025 |
| 976 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1026 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 977 Register array = locs()->in(0).reg(); | 1027 Register array = locs()->in(0).reg(); |
| 978 Location index = locs()->in(1); | 1028 Location index = locs()->in(1); |
| 979 | 1029 |
| 980 const bool is_external = | |
| 981 (this->array()->definition()->representation() == kUntagged); | |
| 982 Address element_address(kNoRegister, 0); | 1030 Address element_address(kNoRegister, 0); |
| 983 | 1031 element_address = index.IsRegister() |
| 984 if (is_external) { | 1032 ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(), |
| 985 element_address = index.IsRegister() | 1033 array, index.reg()) |
| 986 ? compiler->ExternalElementAddressForRegIndex( | 1034 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), |
| 987 index_scale(), array, index.reg()) | 1035 array, Smi::Cast(index.constant()).Value()); |
| 988 : compiler->ExternalElementAddressForIntIndex( | |
| 989 index_scale(), array, Smi::Cast(index.constant()).Value()); | |
| 990 } else { | |
| 991 ASSERT(this->array()->definition()->representation() == kTagged); | |
| 992 element_address = index.IsRegister() | |
| 993 ? compiler->ElementAddressForRegIndex( | |
| 994 class_id(), index_scale(), array, index.reg()) | |
| 995 : compiler->ElementAddressForIntIndex( | |
| 996 class_id(), index_scale(), array, | |
| 997 Smi::Cast(index.constant()).Value()); | |
| 998 } | |
| 999 | 1036 |
| 1000 if ((representation() == kUnboxedDouble) || | 1037 if ((representation() == kUnboxedDouble) || |
| 1001 (representation() == kUnboxedFloat32x4) || | 1038 (representation() == kUnboxedFloat32x4) || |
| 1002 (representation() == kUnboxedInt32x4) || | 1039 (representation() == kUnboxedInt32x4) || |
| 1003 (representation() == kUnboxedFloat64x2)) { | 1040 (representation() == kUnboxedFloat64x2)) { |
| 1004 if ((index_scale() == 1) && index.IsRegister()) { | 1041 if ((index_scale() == 1) && index.IsRegister()) { |
| 1005 __ SmiUntag(index.reg()); | 1042 __ SmiUntag(index.reg()); |
| 1006 } | 1043 } |
| 1007 | 1044 |
| 1008 XmmRegister result = locs()->out(0).fpu_reg(); | 1045 XmmRegister result = locs()->out(0).fpu_reg(); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 return NULL; | 1191 return NULL; |
| 1155 } | 1192 } |
| 1156 return locs; | 1193 return locs; |
| 1157 } | 1194 } |
| 1158 | 1195 |
| 1159 | 1196 |
| 1160 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1197 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1161 Register array = locs()->in(0).reg(); | 1198 Register array = locs()->in(0).reg(); |
| 1162 Location index = locs()->in(1); | 1199 Location index = locs()->in(1); |
| 1163 | 1200 |
| 1164 const bool is_external = | |
| 1165 (this->array()->definition()->representation() == kUntagged); | |
| 1166 Address element_address(kNoRegister, 0); | 1201 Address element_address(kNoRegister, 0); |
| 1167 if (is_external) { | 1202 element_address = index.IsRegister() |
| 1168 element_address = index.IsRegister() | 1203 ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(), |
| 1169 ? compiler->ExternalElementAddressForRegIndex( | 1204 array, index.reg()) |
| 1170 index_scale(), array, index.reg()) | 1205 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), |
| 1171 : compiler->ExternalElementAddressForIntIndex( | 1206 array, Smi::Cast(index.constant()).Value()); |
| 1172 index_scale(), array, Smi::Cast(index.constant()).Value()); | |
| 1173 } else { | |
| 1174 ASSERT(this->array()->definition()->representation() == kTagged); | |
| 1175 element_address = index.IsRegister() | |
| 1176 ? compiler->ElementAddressForRegIndex( | |
| 1177 class_id(), index_scale(), array, index.reg()) | |
| 1178 : compiler->ElementAddressForIntIndex( | |
| 1179 class_id(), index_scale(), array, | |
| 1180 Smi::Cast(index.constant()).Value()); | |
| 1181 } | |
| 1182 | 1207 |
| 1183 if ((index_scale() == 1) && index.IsRegister()) { | 1208 if ((index_scale() == 1) && index.IsRegister()) { |
| 1184 __ SmiUntag(index.reg()); | 1209 __ SmiUntag(index.reg()); |
| 1185 } | 1210 } |
| 1186 switch (class_id()) { | 1211 switch (class_id()) { |
| 1187 case kArrayCid: | 1212 case kArrayCid: |
| 1188 if (ShouldEmitStoreBarrier()) { | 1213 if (ShouldEmitStoreBarrier()) { |
| 1189 Register value = locs()->in(2).reg(); | 1214 Register value = locs()->in(2).reg(); |
| 1190 __ StoreIntoObject(array, element_address, value); | 1215 __ StoreIntoObject(array, element_address, value); |
| 1191 } else if (locs()->in(2).IsConstant()) { | 1216 } else if (locs()->in(2).IsConstant()) { |
| (...skipping 4695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5887 PcDescriptors::kOther, | 5912 PcDescriptors::kOther, |
| 5888 locs()); | 5913 locs()); |
| 5889 __ Drop(ArgumentCount()); // Discard arguments. | 5914 __ Drop(ArgumentCount()); // Discard arguments. |
| 5890 } | 5915 } |
| 5891 | 5916 |
| 5892 } // namespace dart | 5917 } // namespace dart |
| 5893 | 5918 |
| 5894 #undef __ | 5919 #undef __ |
| 5895 | 5920 |
| 5896 #endif // defined TARGET_ARCH_X64 | 5921 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |