| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 case kArrayCid: | 1099 case kArrayCid: |
| 1100 case kImmutableArrayCid: | 1100 case kImmutableArrayCid: |
| 1101 return kDynamicCid; | 1101 return kDynamicCid; |
| 1102 case kFloat32ArrayCid : | 1102 case kFloat32ArrayCid : |
| 1103 case kFloat64ArrayCid : | 1103 case kFloat64ArrayCid : |
| 1104 return kDoubleCid; | 1104 return kDoubleCid; |
| 1105 case kInt8ArrayCid: | 1105 case kInt8ArrayCid: |
| 1106 case kUint8ArrayCid: | 1106 case kUint8ArrayCid: |
| 1107 case kUint8ClampedArrayCid: | 1107 case kUint8ClampedArrayCid: |
| 1108 case kExternalUint8ArrayCid: | 1108 case kExternalUint8ArrayCid: |
| 1109 case kExternalUint8ClampedArrayCid: |
| 1109 case kInt16ArrayCid: | 1110 case kInt16ArrayCid: |
| 1110 case kUint16ArrayCid: | 1111 case kUint16ArrayCid: |
| 1111 case kOneByteStringCid: | 1112 case kOneByteStringCid: |
| 1112 case kTwoByteStringCid: | 1113 case kTwoByteStringCid: |
| 1113 return kSmiCid; | 1114 return kSmiCid; |
| 1114 case kInt32ArrayCid: | 1115 case kInt32ArrayCid: |
| 1115 case kUint32ArrayCid: | 1116 case kUint32ArrayCid: |
| 1116 // Result can be Smi or Mint when boxed. | 1117 // Result can be Smi or Mint when boxed. |
| 1117 // Instruction can deoptimize if we optimistically assumed that the result | 1118 // Instruction can deoptimize if we optimistically assumed that the result |
| 1118 // fits into Smi. | 1119 // fits into Smi. |
| 1119 return CanDeoptimize() ? kSmiCid : kDynamicCid; | 1120 return CanDeoptimize() ? kSmiCid : kDynamicCid; |
| 1120 default: | 1121 default: |
| 1121 UNIMPLEMENTED(); | 1122 UNIMPLEMENTED(); |
| 1122 return kDynamicCid; | 1123 return kDynamicCid; |
| 1123 } | 1124 } |
| 1124 } | 1125 } |
| 1125 | 1126 |
| 1126 | 1127 |
| 1127 Representation LoadIndexedInstr::representation() const { | 1128 Representation LoadIndexedInstr::representation() const { |
| 1128 switch (class_id_) { | 1129 switch (class_id_) { |
| 1129 case kArrayCid: | 1130 case kArrayCid: |
| 1130 case kImmutableArrayCid: | 1131 case kImmutableArrayCid: |
| 1131 case kInt8ArrayCid: | 1132 case kInt8ArrayCid: |
| 1132 case kUint8ArrayCid: | 1133 case kUint8ArrayCid: |
| 1133 case kUint8ClampedArrayCid: | 1134 case kUint8ClampedArrayCid: |
| 1134 case kExternalUint8ArrayCid: | 1135 case kExternalUint8ArrayCid: |
| 1136 case kExternalUint8ClampedArrayCid: |
| 1135 case kInt16ArrayCid: | 1137 case kInt16ArrayCid: |
| 1136 case kUint16ArrayCid: | 1138 case kUint16ArrayCid: |
| 1137 case kOneByteStringCid: | 1139 case kOneByteStringCid: |
| 1138 case kTwoByteStringCid: | 1140 case kTwoByteStringCid: |
| 1139 return kTagged; | 1141 return kTagged; |
| 1140 case kInt32ArrayCid: | 1142 case kInt32ArrayCid: |
| 1141 case kUint32ArrayCid: | 1143 case kUint32ArrayCid: |
| 1142 // Instruction can deoptimize if we optimistically assumed that the result | 1144 // Instruction can deoptimize if we optimistically assumed that the result |
| 1143 // fits into Smi. | 1145 // fits into Smi. |
| 1144 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1146 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1170 locs->set_out(Location::RequiresRegister()); | 1172 locs->set_out(Location::RequiresRegister()); |
| 1171 } | 1173 } |
| 1172 return locs; | 1174 return locs; |
| 1173 } | 1175 } |
| 1174 | 1176 |
| 1175 | 1177 |
| 1176 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1178 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1177 Register array = locs()->in(0).reg(); | 1179 Register array = locs()->in(0).reg(); |
| 1178 Location index = locs()->in(1); | 1180 Location index = locs()->in(1); |
| 1179 | 1181 |
| 1180 if (class_id() == kExternalUint8ArrayCid) { | 1182 if ((class_id() == kExternalUint8ArrayCid) || |
| 1183 (class_id() == kExternalUint8ClampedArrayCid)) { |
| 1181 Register result = locs()->out().reg(); | 1184 Register result = locs()->out().reg(); |
| 1182 const Address& element_address = index.IsRegister() | 1185 const Address& element_address = index.IsRegister() |
| 1183 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( | 1186 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1184 class_id(), index_scale(), result, index.reg()) | 1187 class_id(), index_scale(), result, index.reg()) |
| 1185 : FlowGraphCompiler::ExternalElementAddressForIntIndex( | 1188 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1186 class_id(), index_scale(), result, | 1189 class_id(), index_scale(), result, |
| 1187 Smi::Cast(index.constant()).Value()); | 1190 Smi::Cast(index.constant()).Value()); |
| 1188 ASSERT(index_scale() == 1); | 1191 ASSERT(index_scale() == 1); |
| 1189 if (index.IsRegister()) { | 1192 if (index.IsRegister()) { |
| 1190 __ SmiUntag(index.reg()); | 1193 __ SmiUntag(index.reg()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1202 FieldAddress element_address = index.IsRegister() | 1205 FieldAddress element_address = index.IsRegister() |
| 1203 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1206 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1204 class_id(), index_scale(), array, index.reg()) | 1207 class_id(), index_scale(), array, index.reg()) |
| 1205 : FlowGraphCompiler::ElementAddressForIntIndex( | 1208 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1206 class_id(), index_scale(), array, | 1209 class_id(), index_scale(), array, |
| 1207 Smi::Cast(index.constant()).Value()); | 1210 Smi::Cast(index.constant()).Value()); |
| 1208 | 1211 |
| 1209 if ((representation() == kUnboxedDouble) || | 1212 if ((representation() == kUnboxedDouble) || |
| 1210 (representation() == kUnboxedMint)) { | 1213 (representation() == kUnboxedMint)) { |
| 1211 XmmRegister result = locs()->out().fpu_reg(); | 1214 XmmRegister result = locs()->out().fpu_reg(); |
| 1212 if (index_scale() == 1 && index.IsRegister()) { | 1215 if ((index_scale() == 1) && index.IsRegister()) { |
| 1213 __ SmiUntag(index.reg()); | 1216 __ SmiUntag(index.reg()); |
| 1214 } | 1217 } |
| 1215 switch (class_id()) { | 1218 switch (class_id()) { |
| 1216 case kInt32ArrayCid: | 1219 case kInt32ArrayCid: |
| 1217 __ movss(result, element_address); | 1220 __ movss(result, element_address); |
| 1218 __ pmovsxdq(result, result); | 1221 __ pmovsxdq(result, result); |
| 1219 break; | 1222 break; |
| 1220 case kUint32ArrayCid: | 1223 case kUint32ArrayCid: |
| 1221 __ xorpd(result, result); | 1224 __ xorpd(result, result); |
| 1222 __ movss(result, element_address); | 1225 __ movss(result, element_address); |
| 1223 break; | 1226 break; |
| 1224 case kFloat32ArrayCid: | 1227 case kFloat32ArrayCid: |
| 1225 // Load single precision float and promote to double. | 1228 // Load single precision float and promote to double. |
| 1226 __ movss(result, element_address); | 1229 __ movss(result, element_address); |
| 1227 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1230 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1228 break; | 1231 break; |
| 1229 case kFloat64ArrayCid: | 1232 case kFloat64ArrayCid: |
| 1230 __ movsd(result, element_address); | 1233 __ movsd(result, element_address); |
| 1231 break; | 1234 break; |
| 1232 } | 1235 } |
| 1233 if (index_scale() == 1 && index.IsRegister()) { | 1236 if ((index_scale() == 1) && index.IsRegister()) { |
| 1234 __ SmiTag(index.reg()); // Re-tag. | 1237 __ SmiTag(index.reg()); // Re-tag. |
| 1235 } | 1238 } |
| 1236 return; | 1239 return; |
| 1237 } | 1240 } |
| 1238 | 1241 |
| 1239 Register result = locs()->out().reg(); | 1242 Register result = locs()->out().reg(); |
| 1240 if (index_scale() == 1 && index.IsRegister()) { | 1243 if ((index_scale() == 1) && index.IsRegister()) { |
| 1241 __ SmiUntag(index.reg()); | 1244 __ SmiUntag(index.reg()); |
| 1242 } | 1245 } |
| 1243 switch (class_id()) { | 1246 switch (class_id()) { |
| 1244 case kInt8ArrayCid: | 1247 case kInt8ArrayCid: |
| 1245 case kUint8ArrayCid: | 1248 case kUint8ArrayCid: |
| 1246 case kUint8ClampedArrayCid: | 1249 case kUint8ClampedArrayCid: |
| 1247 case kOneByteStringCid: | 1250 case kOneByteStringCid: |
| 1248 ASSERT(index_scale() == 1); | 1251 ASSERT(index_scale() == 1); |
| 1249 if (class_id() == kInt8ArrayCid) { | 1252 if (class_id() == kInt8ArrayCid) { |
| 1250 __ movsxb(result, element_address); | 1253 __ movsxb(result, element_address); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1278 __ testl(result, Immediate(0xC0000000)); | 1281 __ testl(result, Immediate(0xC0000000)); |
| 1279 __ j(NOT_ZERO, deopt); | 1282 __ j(NOT_ZERO, deopt); |
| 1280 __ SmiTag(result); | 1283 __ SmiTag(result); |
| 1281 } | 1284 } |
| 1282 break; | 1285 break; |
| 1283 default: | 1286 default: |
| 1284 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1287 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1285 __ movl(result, element_address); | 1288 __ movl(result, element_address); |
| 1286 break; | 1289 break; |
| 1287 } | 1290 } |
| 1288 if (index_scale() == 1 && index.IsRegister()) { | 1291 if ((index_scale() == 1) && index.IsRegister()) { |
| 1289 __ SmiTag(index.reg()); // Re-tag. | 1292 __ SmiTag(index.reg()); // Re-tag. |
| 1290 } | 1293 } |
| 1291 } | 1294 } |
| 1292 | 1295 |
| 1293 | 1296 |
| 1294 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1297 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1295 intptr_t idx) const { | 1298 intptr_t idx) const { |
| 1296 if ((idx == 0) || (idx == 1)) return kTagged; | 1299 if ((idx == 0) || (idx == 1)) return kTagged; |
| 1297 ASSERT(idx == 2); | 1300 ASSERT(idx == 2); |
| 1298 switch (class_id_) { | 1301 switch (class_id_) { |
| (...skipping 2112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3411 PcDescriptors::kOther, | 3414 PcDescriptors::kOther, |
| 3412 locs()); | 3415 locs()); |
| 3413 __ Drop(2); // Discard type arguments and receiver. | 3416 __ Drop(2); // Discard type arguments and receiver. |
| 3414 } | 3417 } |
| 3415 | 3418 |
| 3416 } // namespace dart | 3419 } // namespace dart |
| 3417 | 3420 |
| 3418 #undef __ | 3421 #undef __ |
| 3419 | 3422 |
| 3420 #endif // defined TARGET_ARCH_IA32 | 3423 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |