| 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 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 __ popl(result); | 815 __ popl(result); |
| 816 } | 816 } |
| 817 | 817 |
| 818 | 818 |
| 819 static bool CanBeImmediateIndex(Value* value, intptr_t cid) { | 819 static bool CanBeImmediateIndex(Value* value, intptr_t cid) { |
| 820 ConstantInstr* constant = value->definition()->AsConstant(); | 820 ConstantInstr* constant = value->definition()->AsConstant(); |
| 821 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) { | 821 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) { |
| 822 return false; | 822 return false; |
| 823 } | 823 } |
| 824 const int64_t index = Smi::Cast(constant->value()).AsInt64Value(); | 824 const int64_t index = Smi::Cast(constant->value()).AsInt64Value(); |
| 825 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); | 825 const intptr_t scale = Instance::ElementSizeFor(cid); |
| 826 const intptr_t offset = FlowGraphCompiler::DataOffsetFor(cid); | 826 const intptr_t offset = Instance::DataOffsetFor(cid); |
| 827 const int64_t displacement = index * scale + offset; | 827 const int64_t displacement = index * scale + offset; |
| 828 return Utils::IsInt(32, displacement); | 828 return Utils::IsInt(32, displacement); |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| 832 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Isolate* isolate, | 832 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Isolate* isolate, |
| 833 bool opt) const { | 833 bool opt) const { |
| 834 const intptr_t kNumInputs = 1; | 834 const intptr_t kNumInputs = 1; |
| 835 // TODO(fschneider): Allow immediate operands for the char code. | 835 // TODO(fschneider): Allow immediate operands for the char code. |
| 836 return LocationSummary::Make(kNumInputs, | 836 return LocationSummary::Make(kNumInputs, |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 Location::RequiresRegister())); | 1053 Location::RequiresRegister())); |
| 1054 } | 1054 } |
| 1055 } else { | 1055 } else { |
| 1056 ASSERT(representation() == kTagged); | 1056 ASSERT(representation() == kTagged); |
| 1057 locs->set_out(0, Location::RequiresRegister()); | 1057 locs->set_out(0, Location::RequiresRegister()); |
| 1058 } | 1058 } |
| 1059 return locs; | 1059 return locs; |
| 1060 } | 1060 } |
| 1061 | 1061 |
| 1062 | 1062 |
| 1063 static Address ElementAddressForIntIndex(bool is_external, |
| 1064 intptr_t cid, |
| 1065 intptr_t index_scale, |
| 1066 Register array, |
| 1067 intptr_t index) { |
| 1068 if (is_external) { |
| 1069 return Address(array, index * index_scale); |
| 1070 } else { |
| 1071 const int64_t disp = static_cast<int64_t>(index) * index_scale + |
| 1072 Instance::DataOffsetFor(cid); |
| 1073 ASSERT(Utils::IsInt(32, disp)); |
| 1074 return FieldAddress(array, static_cast<int32_t>(disp)); |
| 1075 } |
| 1076 } |
| 1077 |
| 1078 |
| 1079 static ScaleFactor ToScaleFactor(intptr_t index_scale) { |
| 1080 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with |
| 1081 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is |
| 1082 // expected to be untagged before accessing. |
| 1083 ASSERT(kSmiTagShift == 1); |
| 1084 switch (index_scale) { |
| 1085 case 1: return TIMES_1; |
| 1086 case 2: return TIMES_1; |
| 1087 case 4: return TIMES_2; |
| 1088 case 8: return TIMES_4; |
| 1089 case 16: return TIMES_8; |
| 1090 default: |
| 1091 UNREACHABLE(); |
| 1092 return TIMES_1; |
| 1093 } |
| 1094 } |
| 1095 |
| 1096 |
| 1097 static Address ElementAddressForRegIndex(bool is_external, |
| 1098 intptr_t cid, |
| 1099 intptr_t index_scale, |
| 1100 Register array, |
| 1101 Register index) { |
| 1102 if (is_external) { |
| 1103 return Address(array, index, ToScaleFactor(index_scale), 0); |
| 1104 } else { |
| 1105 return FieldAddress(array, |
| 1106 index, |
| 1107 ToScaleFactor(index_scale), |
| 1108 Instance::DataOffsetFor(cid)); |
| 1109 } |
| 1110 } |
| 1111 |
| 1112 |
| 1063 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1113 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1064 Register array = locs()->in(0).reg(); | 1114 Register array = locs()->in(0).reg(); |
| 1065 Location index = locs()->in(1); | 1115 Location index = locs()->in(1); |
| 1066 | 1116 |
| 1067 Address element_address(kNoRegister, 0); | 1117 Address element_address(kNoRegister, 0); |
| 1068 if (IsExternal()) { | 1118 element_address = index.IsRegister() |
| 1069 element_address = index.IsRegister() | 1119 ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(), |
| 1070 ? compiler->ExternalElementAddressForRegIndex( | 1120 array, index.reg()) |
| 1071 index_scale(), array, index.reg()) | 1121 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), |
| 1072 : compiler->ExternalElementAddressForIntIndex( | 1122 array, Smi::Cast(index.constant()).Value()); |
| 1073 index_scale(), array, Smi::Cast(index.constant()).Value()); | |
| 1074 } else { | |
| 1075 ASSERT(this->array()->definition()->representation() == kTagged); | |
| 1076 element_address = index.IsRegister() | |
| 1077 ? compiler->ElementAddressForRegIndex( | |
| 1078 class_id(), index_scale(), array, index.reg()) | |
| 1079 : compiler->ElementAddressForIntIndex( | |
| 1080 class_id(), index_scale(), array, | |
| 1081 Smi::Cast(index.constant()).Value()); | |
| 1082 } | |
| 1083 | 1123 |
| 1084 if ((representation() == kUnboxedDouble) || | 1124 if ((representation() == kUnboxedDouble) || |
| 1085 (representation() == kUnboxedFloat32x4) || | 1125 (representation() == kUnboxedFloat32x4) || |
| 1086 (representation() == kUnboxedInt32x4) || | 1126 (representation() == kUnboxedInt32x4) || |
| 1087 (representation() == kUnboxedFloat64x2)) { | 1127 (representation() == kUnboxedFloat64x2)) { |
| 1088 XmmRegister result = locs()->out(0).fpu_reg(); | 1128 XmmRegister result = locs()->out(0).fpu_reg(); |
| 1089 if ((index_scale() == 1) && index.IsRegister()) { | 1129 if ((index_scale() == 1) && index.IsRegister()) { |
| 1090 __ SmiUntag(index.reg()); | 1130 __ SmiUntag(index.reg()); |
| 1091 } | 1131 } |
| 1092 switch (class_id()) { | 1132 switch (class_id()) { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 } | 1333 } |
| 1294 return locs; | 1334 return locs; |
| 1295 } | 1335 } |
| 1296 | 1336 |
| 1297 | 1337 |
| 1298 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1338 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1299 Register array = locs()->in(0).reg(); | 1339 Register array = locs()->in(0).reg(); |
| 1300 Location index = locs()->in(1); | 1340 Location index = locs()->in(1); |
| 1301 | 1341 |
| 1302 Address element_address(kNoRegister, 0); | 1342 Address element_address(kNoRegister, 0); |
| 1303 if (IsExternal()) { | 1343 element_address = index.IsRegister() |
| 1304 element_address = index.IsRegister() | 1344 ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(), |
| 1305 ? compiler->ExternalElementAddressForRegIndex( | 1345 array, index.reg()) |
| 1306 index_scale(), array, index.reg()) | 1346 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), |
| 1307 : compiler->ExternalElementAddressForIntIndex( | 1347 array, Smi::Cast(index.constant()).Value()); |
| 1308 index_scale(), array, Smi::Cast(index.constant()).Value()); | |
| 1309 } else { | |
| 1310 ASSERT(this->array()->definition()->representation() == kTagged); | |
| 1311 element_address = index.IsRegister() | |
| 1312 ? compiler->ElementAddressForRegIndex( | |
| 1313 class_id(), index_scale(), array, index.reg()) | |
| 1314 : compiler->ElementAddressForIntIndex( | |
| 1315 class_id(), index_scale(), array, | |
| 1316 Smi::Cast(index.constant()).Value()); | |
| 1317 } | |
| 1318 | 1348 |
| 1319 if ((index_scale() == 1) && index.IsRegister()) { | 1349 if ((index_scale() == 1) && index.IsRegister()) { |
| 1320 __ SmiUntag(index.reg()); | 1350 __ SmiUntag(index.reg()); |
| 1321 } | 1351 } |
| 1322 switch (class_id()) { | 1352 switch (class_id()) { |
| 1323 case kArrayCid: | 1353 case kArrayCid: |
| 1324 if (ShouldEmitStoreBarrier()) { | 1354 if (ShouldEmitStoreBarrier()) { |
| 1325 Register value = locs()->in(2).reg(); | 1355 Register value = locs()->in(2).reg(); |
| 1326 __ StoreIntoObject(array, element_address, value); | 1356 __ StoreIntoObject(array, element_address, value); |
| 1327 } else if (locs()->in(2).IsConstant()) { | 1357 } else if (locs()->in(2).IsConstant()) { |
| (...skipping 5017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6345 PcDescriptors::kOther, | 6375 PcDescriptors::kOther, |
| 6346 locs()); | 6376 locs()); |
| 6347 __ Drop(ArgumentCount()); // Discard arguments. | 6377 __ Drop(ArgumentCount()); // Discard arguments. |
| 6348 } | 6378 } |
| 6349 | 6379 |
| 6350 } // namespace dart | 6380 } // namespace dart |
| 6351 | 6381 |
| 6352 #undef __ | 6382 #undef __ |
| 6353 | 6383 |
| 6354 #endif // defined TARGET_ARCH_IA32 | 6384 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |