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 |