Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 12871010: Replace scalarlist optimizations and split external array loads into two IL instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 Register result = locs()->out().reg(); 1087 Register result = locs()->out().reg();
1088 __ movl(result, 1088 __ movl(result,
1089 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); 1089 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
1090 __ movl(result, Address(result, 1090 __ movl(result, Address(result,
1091 char_code, 1091 char_code,
1092 TIMES_HALF_WORD_SIZE, // Char code is a smi. 1092 TIMES_HALF_WORD_SIZE, // Char code is a smi.
1093 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 1093 Symbols::kNullCharCodeSymbolOffset * kWordSize));
1094 } 1094 }
1095 1095
1096 1096
1097 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const {
1098 const intptr_t kNumInputs = 1;
1099 const intptr_t kNumTemps = 0;
1100 LocationSummary* locs =
1101 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1102 locs->set_in(0, Location::RequiresRegister());
1103 locs->set_out(Location::RequiresRegister());
1104 return locs;
1105 }
1106
1107
1108 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1109 Register object = locs()->in(0).reg();
1110 Register result = locs()->out().reg();
1111 __ movl(result, FieldAddress(object, offset()));
1112 }
1113
1114
1097 CompileType LoadIndexedInstr::ComputeType() const { 1115 CompileType LoadIndexedInstr::ComputeType() const {
1098 switch (class_id_) { 1116 switch (class_id_) {
1099 case kArrayCid: 1117 case kArrayCid:
1100 case kImmutableArrayCid: 1118 case kImmutableArrayCid:
1101 return CompileType::Dynamic(); 1119 return CompileType::Dynamic();
1102 1120
1103 case kFloat32ArrayCid :
1104 case kFloat64ArrayCid :
1105 case kTypedDataFloat32ArrayCid: 1121 case kTypedDataFloat32ArrayCid:
1106 case kTypedDataFloat64ArrayCid: 1122 case kTypedDataFloat64ArrayCid:
1107 return CompileType::FromCid(kDoubleCid); 1123 return CompileType::FromCid(kDoubleCid);
1108 1124
1109 case kInt8ArrayCid:
1110 case kUint8ArrayCid:
1111 case kUint8ClampedArrayCid:
1112 case kExternalUint8ArrayCid:
1113 case kExternalUint8ClampedArrayCid:
1114 case kInt16ArrayCid:
1115 case kUint16ArrayCid:
1116 case kTypedDataInt8ArrayCid: 1125 case kTypedDataInt8ArrayCid:
1117 case kTypedDataUint8ArrayCid: 1126 case kTypedDataUint8ArrayCid:
1118 case kTypedDataUint8ClampedArrayCid: 1127 case kTypedDataUint8ClampedArrayCid:
1119 case kExternalTypedDataUint8ArrayCid: 1128 case kExternalTypedDataUint8ArrayCid:
1120 case kExternalTypedDataUint8ClampedArrayCid: 1129 case kExternalTypedDataUint8ClampedArrayCid:
1121 case kTypedDataInt16ArrayCid: 1130 case kTypedDataInt16ArrayCid:
1122 case kTypedDataUint16ArrayCid: 1131 case kTypedDataUint16ArrayCid:
1123 case kOneByteStringCid: 1132 case kOneByteStringCid:
1124 case kTwoByteStringCid: 1133 case kTwoByteStringCid:
1125 return CompileType::FromCid(kSmiCid); 1134 return CompileType::FromCid(kSmiCid);
1126 1135
1127 case kInt32ArrayCid:
1128 case kUint32ArrayCid:
1129 case kTypedDataInt32ArrayCid: 1136 case kTypedDataInt32ArrayCid:
1130 case kTypedDataUint32ArrayCid: 1137 case kTypedDataUint32ArrayCid:
1131 // Result can be Smi or Mint when boxed. 1138 // Result can be Smi or Mint when boxed.
1132 // Instruction can deoptimize if we optimistically assumed that the result 1139 // Instruction can deoptimize if we optimistically assumed that the result
1133 // fits into Smi. 1140 // fits into Smi.
1134 return CanDeoptimize() ? CompileType::FromCid(kSmiCid) 1141 return CanDeoptimize() ? CompileType::FromCid(kSmiCid)
1135 : CompileType::Int(); 1142 : CompileType::Int();
1136 1143
1137 default: 1144 default:
1138 UNIMPLEMENTED(); 1145 UNIMPLEMENTED();
1139 return CompileType::Dynamic(); 1146 return CompileType::Dynamic();
1140 } 1147 }
1141 } 1148 }
1142 1149
1143 1150
1144 Representation LoadIndexedInstr::representation() const { 1151 Representation LoadIndexedInstr::representation() const {
1145 switch (class_id_) { 1152 switch (class_id_) {
1146 case kArrayCid: 1153 case kArrayCid:
1147 case kImmutableArrayCid: 1154 case kImmutableArrayCid:
1148 case kInt8ArrayCid:
1149 case kUint8ArrayCid:
1150 case kUint8ClampedArrayCid:
1151 case kExternalUint8ArrayCid:
1152 case kExternalUint8ClampedArrayCid:
1153 case kInt16ArrayCid:
1154 case kUint16ArrayCid:
1155 case kTypedDataInt8ArrayCid: 1155 case kTypedDataInt8ArrayCid:
1156 case kTypedDataUint8ArrayCid: 1156 case kTypedDataUint8ArrayCid:
1157 case kTypedDataUint8ClampedArrayCid: 1157 case kTypedDataUint8ClampedArrayCid:
1158 case kExternalTypedDataUint8ArrayCid: 1158 case kExternalTypedDataUint8ArrayCid:
1159 case kExternalTypedDataUint8ClampedArrayCid: 1159 case kExternalTypedDataUint8ClampedArrayCid:
1160 case kTypedDataInt16ArrayCid: 1160 case kTypedDataInt16ArrayCid:
1161 case kTypedDataUint16ArrayCid: 1161 case kTypedDataUint16ArrayCid:
1162 case kOneByteStringCid: 1162 case kOneByteStringCid:
1163 case kTwoByteStringCid: 1163 case kTwoByteStringCid:
1164 return kTagged; 1164 return kTagged;
1165 case kInt32ArrayCid:
1166 case kUint32ArrayCid:
1167 case kTypedDataInt32ArrayCid: 1165 case kTypedDataInt32ArrayCid:
1168 case kTypedDataUint32ArrayCid: 1166 case kTypedDataUint32ArrayCid:
1169 // Instruction can deoptimize if we optimistically assumed that the result 1167 // Instruction can deoptimize if we optimistically assumed that the result
1170 // fits into Smi. 1168 // fits into Smi.
1171 return CanDeoptimize() ? kTagged : kUnboxedMint; 1169 return CanDeoptimize() ? kTagged : kUnboxedMint;
1172 case kFloat32ArrayCid :
1173 case kFloat64ArrayCid :
1174 case kTypedDataFloat32ArrayCid: 1170 case kTypedDataFloat32ArrayCid:
1175 case kTypedDataFloat64ArrayCid: 1171 case kTypedDataFloat64ArrayCid:
1176 return kUnboxedDouble; 1172 return kUnboxedDouble;
1177 default: 1173 default:
1178 UNIMPLEMENTED(); 1174 UNIMPLEMENTED();
1179 return kTagged; 1175 return kTagged;
1180 } 1176 }
1181 } 1177 }
1182 1178
1183 1179
(...skipping 22 matching lines...) Expand all
1206 locs->set_out(Location::RequiresRegister()); 1202 locs->set_out(Location::RequiresRegister());
1207 } 1203 }
1208 return locs; 1204 return locs;
1209 } 1205 }
1210 1206
1211 1207
1212 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1208 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1213 Register array = locs()->in(0).reg(); 1209 Register array = locs()->in(0).reg();
1214 Location index = locs()->in(1); 1210 Location index = locs()->in(1);
1215 1211
1216 if ((class_id() == kExternalUint8ArrayCid) || 1212 Address element_address(kNoRegister, 0);
1217 (class_id() == kExternalUint8ClampedArrayCid) || 1213 if (IsExternal()) {
1218 (class_id() == kExternalTypedDataUint8ArrayCid) || 1214 element_address = index.IsRegister()
1219 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
1220 Register result = locs()->out().reg();
1221 const Address& element_address = index.IsRegister()
1222 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( 1215 ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
1223 index_scale(), result, index.reg()) 1216 index_scale(), array, index.reg())
1224 : FlowGraphCompiler::ExternalElementAddressForIntIndex( 1217 : FlowGraphCompiler::ExternalElementAddressForIntIndex(
1225 index_scale(), result, Smi::Cast(index.constant()).Value()); 1218 index_scale(), array, Smi::Cast(index.constant()).Value());
1226 ASSERT(index_scale() == 1); 1219 } else {
1227 if (index.IsRegister()) { 1220 ASSERT(this->array()->definition()->representation() == kTagged);
1228 __ SmiUntag(index.reg()); 1221 element_address = index.IsRegister()
1229 } 1222 ? FlowGraphCompiler::ElementAddressForRegIndex(
1230 __ movl(result, 1223 class_id(), index_scale(), array, index.reg())
1231 FieldAddress(array, ExternalUint8Array::data_offset())); 1224 : FlowGraphCompiler::ElementAddressForIntIndex(
1232 __ movzxb(result, element_address); 1225 class_id(), index_scale(), array,
1233 __ SmiTag(result); 1226 Smi::Cast(index.constant()).Value());
1234 return;
1235 } 1227 }
1236 1228
1237 FieldAddress element_address = index.IsRegister()
1238 ? FlowGraphCompiler::ElementAddressForRegIndex(
1239 class_id(), index_scale(), array, index.reg())
1240 : FlowGraphCompiler::ElementAddressForIntIndex(
1241 class_id(), index_scale(), array,
1242 Smi::Cast(index.constant()).Value());
1243
1244 if ((representation() == kUnboxedDouble) || 1229 if ((representation() == kUnboxedDouble) ||
1245 (representation() == kUnboxedMint)) { 1230 (representation() == kUnboxedMint)) {
1246 XmmRegister result = locs()->out().fpu_reg(); 1231 XmmRegister result = locs()->out().fpu_reg();
1247 if ((index_scale() == 1) && index.IsRegister()) { 1232 if ((index_scale() == 1) && index.IsRegister()) {
1248 __ SmiUntag(index.reg()); 1233 __ SmiUntag(index.reg());
1249 } 1234 }
1250 switch (class_id()) { 1235 switch (class_id()) {
1251 case kInt32ArrayCid:
1252 case kTypedDataInt32ArrayCid: 1236 case kTypedDataInt32ArrayCid:
1253 __ movss(result, element_address); 1237 __ movss(result, element_address);
1254 __ pmovsxdq(result, result); 1238 __ pmovsxdq(result, result);
1255 break; 1239 break;
1256 case kUint32ArrayCid:
1257 case kTypedDataUint32ArrayCid: 1240 case kTypedDataUint32ArrayCid:
1258 __ xorpd(result, result); 1241 __ xorpd(result, result);
1259 __ movss(result, element_address); 1242 __ movss(result, element_address);
1260 break; 1243 break;
1261 case kFloat32ArrayCid:
1262 case kTypedDataFloat32ArrayCid: 1244 case kTypedDataFloat32ArrayCid:
1263 // Load single precision float and promote to double. 1245 // Load single precision float and promote to double.
1264 __ movss(result, element_address); 1246 __ movss(result, element_address);
1265 __ cvtss2sd(result, locs()->out().fpu_reg()); 1247 __ cvtss2sd(result, locs()->out().fpu_reg());
1266 break; 1248 break;
1267 case kFloat64ArrayCid:
1268 case kTypedDataFloat64ArrayCid: 1249 case kTypedDataFloat64ArrayCid:
1269 __ movsd(result, element_address); 1250 __ movsd(result, element_address);
1270 break; 1251 break;
1271 } 1252 }
1272 return; 1253 return;
1273 } 1254 }
1274 1255
1275 Register result = locs()->out().reg(); 1256 Register result = locs()->out().reg();
1276 if ((index_scale() == 1) && index.IsRegister()) { 1257 if ((index_scale() == 1) && index.IsRegister()) {
1277 __ SmiUntag(index.reg()); 1258 __ SmiUntag(index.reg());
1278 } 1259 }
1279 switch (class_id()) { 1260 switch (class_id()) {
1280 case kInt8ArrayCid:
1281 case kTypedDataInt8ArrayCid: 1261 case kTypedDataInt8ArrayCid:
1282 ASSERT(index_scale() == 1); 1262 ASSERT(index_scale() == 1);
1283 __ movsxb(result, element_address); 1263 __ movsxb(result, element_address);
1284 __ SmiTag(result); 1264 __ SmiTag(result);
1285 break; 1265 break;
1286 case kUint8ArrayCid:
1287 case kUint8ClampedArrayCid:
1288 case kTypedDataUint8ArrayCid: 1266 case kTypedDataUint8ArrayCid:
1289 case kTypedDataUint8ClampedArrayCid: 1267 case kTypedDataUint8ClampedArrayCid:
1268 case kExternalTypedDataUint8ArrayCid:
1269 case kExternalTypedDataUint8ClampedArrayCid:
1290 case kOneByteStringCid: 1270 case kOneByteStringCid:
1291 ASSERT(index_scale() == 1); 1271 ASSERT(index_scale() == 1);
1292 __ movzxb(result, element_address); 1272 __ movzxb(result, element_address);
1293 __ SmiTag(result); 1273 __ SmiTag(result);
1294 break; 1274 break;
1295 case kInt16ArrayCid:
1296 case kTypedDataInt16ArrayCid: 1275 case kTypedDataInt16ArrayCid:
1297 __ movsxw(result, element_address); 1276 __ movsxw(result, element_address);
1298 __ SmiTag(result); 1277 __ SmiTag(result);
1299 break; 1278 break;
1300 case kUint16ArrayCid:
1301 case kTypedDataUint16ArrayCid: 1279 case kTypedDataUint16ArrayCid:
1302 case kTwoByteStringCid: 1280 case kTwoByteStringCid:
1303 __ movzxw(result, element_address); 1281 __ movzxw(result, element_address);
1304 __ SmiTag(result); 1282 __ SmiTag(result);
1305 break; 1283 break;
1306 case kInt32ArrayCid:
1307 case kTypedDataInt32ArrayCid: { 1284 case kTypedDataInt32ArrayCid: {
1308 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); 1285 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
1309 __ movl(result, element_address); 1286 __ movl(result, element_address);
1310 // Verify that the signed value in 'result' can fit inside a Smi. 1287 // Verify that the signed value in 'result' can fit inside a Smi.
1311 __ cmpl(result, Immediate(0xC0000000)); 1288 __ cmpl(result, Immediate(0xC0000000));
1312 __ j(NEGATIVE, deopt); 1289 __ j(NEGATIVE, deopt);
1313 __ SmiTag(result); 1290 __ SmiTag(result);
1314 } 1291 }
1315 break; 1292 break;
1316 case kUint32ArrayCid:
1317 case kTypedDataUint32ArrayCid: { 1293 case kTypedDataUint32ArrayCid: {
1318 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); 1294 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
1319 __ movl(result, element_address); 1295 __ movl(result, element_address);
1320 // Verify that the unsigned value in 'result' can fit inside a Smi. 1296 // Verify that the unsigned value in 'result' can fit inside a Smi.
1321 __ testl(result, Immediate(0xC0000000)); 1297 __ testl(result, Immediate(0xC0000000));
1322 __ j(NOT_ZERO, deopt); 1298 __ j(NOT_ZERO, deopt);
1323 __ SmiTag(result); 1299 __ SmiTag(result);
1324 } 1300 }
1325 break; 1301 break;
1326 default: 1302 default:
1327 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1303 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1328 __ movl(result, element_address); 1304 __ movl(result, element_address);
1329 break; 1305 break;
1330 } 1306 }
1331 } 1307 }
1332 1308
1333 1309
1334 Representation StoreIndexedInstr::RequiredInputRepresentation( 1310 Representation StoreIndexedInstr::RequiredInputRepresentation(
1335 intptr_t idx) const { 1311 intptr_t idx) const {
1336 if ((idx == 0) || (idx == 1)) return kTagged; 1312 // Array can be a Dart object or a pointer to external data.
1313 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1314 if (idx == 1) return kTagged; // Index is a smi.
1337 ASSERT(idx == 2); 1315 ASSERT(idx == 2);
1338 switch (class_id_) { 1316 switch (class_id_) {
1339 case kArrayCid: 1317 case kArrayCid:
1340 case kInt8ArrayCid:
1341 case kUint8ArrayCid:
1342 case kExternalUint8ArrayCid:
1343 case kUint8ClampedArrayCid:
1344 case kExternalUint8ClampedArrayCid:
1345 case kInt16ArrayCid:
1346 case kUint16ArrayCid:
1347 case kTypedDataInt8ArrayCid: 1318 case kTypedDataInt8ArrayCid:
1348 case kTypedDataUint8ArrayCid: 1319 case kTypedDataUint8ArrayCid:
1349 case kExternalTypedDataUint8ArrayCid: 1320 case kExternalTypedDataUint8ArrayCid:
1350 case kTypedDataUint8ClampedArrayCid: 1321 case kTypedDataUint8ClampedArrayCid:
1351 case kExternalTypedDataUint8ClampedArrayCid: 1322 case kExternalTypedDataUint8ClampedArrayCid:
1352 case kTypedDataInt16ArrayCid: 1323 case kTypedDataInt16ArrayCid:
1353 case kTypedDataUint16ArrayCid: 1324 case kTypedDataUint16ArrayCid:
1354 return kTagged; 1325 return kTagged;
1355 case kInt32ArrayCid:
1356 case kUint32ArrayCid:
1357 case kTypedDataInt32ArrayCid: 1326 case kTypedDataInt32ArrayCid:
1358 case kTypedDataUint32ArrayCid: 1327 case kTypedDataUint32ArrayCid:
1359 return value()->IsSmiValue() ? kTagged : kUnboxedMint; 1328 return value()->IsSmiValue() ? kTagged : kUnboxedMint;
1360 case kFloat32ArrayCid : 1329 case kTypedDataFloat32ArrayCid:
1361 case kFloat64ArrayCid : 1330 case kTypedDataFloat64ArrayCid:
1362 case kTypedDataFloat32ArrayCid :
1363 case kTypedDataFloat64ArrayCid :
1364 return kUnboxedDouble; 1331 return kUnboxedDouble;
1365 default: 1332 default:
1366 UNIMPLEMENTED(); 1333 UNIMPLEMENTED();
1367 return kTagged; 1334 return kTagged;
1368 } 1335 }
1369 } 1336 }
1370 1337
1371 1338
1372 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1339 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1373 const intptr_t kNumInputs = 3; 1340 const intptr_t kNumInputs = 3;
(...skipping 13 matching lines...) Expand all
1387 ? Location::Constant( 1354 ? Location::Constant(
1388 index()->definition()->AsConstant()->value()) 1355 index()->definition()->AsConstant()->value())
1389 : Location::RequiresRegister()); 1356 : Location::RequiresRegister());
1390 } 1357 }
1391 switch (class_id()) { 1358 switch (class_id()) {
1392 case kArrayCid: 1359 case kArrayCid:
1393 locs->set_in(2, ShouldEmitStoreBarrier() 1360 locs->set_in(2, ShouldEmitStoreBarrier()
1394 ? Location::WritableRegister() 1361 ? Location::WritableRegister()
1395 : Location::RegisterOrConstant(value())); 1362 : Location::RegisterOrConstant(value()));
1396 break; 1363 break;
1397 case kExternalUint8ArrayCid:
1398 case kExternalUint8ClampedArrayCid:
1399 case kExternalTypedDataUint8ArrayCid: 1364 case kExternalTypedDataUint8ArrayCid:
1400 case kExternalTypedDataUint8ClampedArrayCid: 1365 case kExternalTypedDataUint8ClampedArrayCid:
1401 // Need temp register to load the external array's data array.
1402 locs->AddTemp(Location::RequiresRegister());
1403 // Fall through.
1404 case kInt8ArrayCid:
1405 case kUint8ArrayCid:
1406 case kUint8ClampedArrayCid:
1407 case kTypedDataInt8ArrayCid: 1366 case kTypedDataInt8ArrayCid:
1408 case kTypedDataUint8ArrayCid: 1367 case kTypedDataUint8ArrayCid:
1409 case kTypedDataUint8ClampedArrayCid: 1368 case kTypedDataUint8ClampedArrayCid:
1410 // TODO(fschneider): Add location constraint for byte registers (EAX, 1369 // TODO(fschneider): Add location constraint for byte registers (EAX,
1411 // EBX, ECX, EDX) instead of using a fixed register. 1370 // EBX, ECX, EDX) instead of using a fixed register.
1412 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); 1371 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX));
1413 break; 1372 break;
1414 case kInt16ArrayCid:
1415 case kUint16ArrayCid:
1416 case kTypedDataInt16ArrayCid: 1373 case kTypedDataInt16ArrayCid:
1417 case kTypedDataUint16ArrayCid: 1374 case kTypedDataUint16ArrayCid:
1418 // Writable register because the value must be untagged before storing. 1375 // Writable register because the value must be untagged before storing.
1419 locs->set_in(2, Location::WritableRegister()); 1376 locs->set_in(2, Location::WritableRegister());
1420 break; 1377 break;
1421 case kInt32ArrayCid:
1422 case kUint32ArrayCid:
1423 case kTypedDataInt32ArrayCid: 1378 case kTypedDataInt32ArrayCid:
1424 case kTypedDataUint32ArrayCid: 1379 case kTypedDataUint32ArrayCid:
1425 // Mints are stored in XMM registers. For smis, use a writable register 1380 // Mints are stored in XMM registers. For smis, use a writable register
1426 // because the value must be untagged before storing. 1381 // because the value must be untagged before storing.
1427 locs->set_in(2, value()->IsSmiValue() 1382 locs->set_in(2, value()->IsSmiValue()
1428 ? Location::WritableRegister() 1383 ? Location::WritableRegister()
1429 : Location::RequiresFpuRegister()); 1384 : Location::RequiresFpuRegister());
1430 break; 1385 break;
1431 case kFloat32ArrayCid:
1432 case kTypedDataFloat32ArrayCid: 1386 case kTypedDataFloat32ArrayCid:
1433 // Need temp register for float-to-double conversion. 1387 // Need temp register for float-to-double conversion.
1434 locs->AddTemp(Location::RequiresFpuRegister()); 1388 locs->AddTemp(Location::RequiresFpuRegister());
1435 // Fall through. 1389 // Fall through.
1436 case kFloat64ArrayCid:
1437 case kTypedDataFloat64ArrayCid: 1390 case kTypedDataFloat64ArrayCid:
1438 // TODO(srdjan): Support Float64 constants. 1391 // TODO(srdjan): Support Float64 constants.
1439 locs->set_in(2, Location::RequiresFpuRegister()); 1392 locs->set_in(2, Location::RequiresFpuRegister());
1440 break; 1393 break;
1441 default: 1394 default:
1442 UNREACHABLE(); 1395 UNREACHABLE();
1443 return NULL; 1396 return NULL;
1444 } 1397 }
1445 return locs; 1398 return locs;
1446 } 1399 }
1447 1400
1448 1401
1449 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1402 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1450 Register array = locs()->in(0).reg(); 1403 Register array = locs()->in(0).reg();
1451 Location index = locs()->in(1); 1404 Location index = locs()->in(1);
1452 1405
1453 Address element_address(kNoRegister, 0); 1406 Address element_address(kNoRegister, 0);
1454 if ((class_id() == kExternalUint8ArrayCid) || 1407 if (IsExternal()) {
1455 (class_id() == kExternalUint8ClampedArrayCid) ||
1456 (class_id() == kExternalTypedDataUint8ArrayCid) ||
1457 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
1458 Register temp = locs()->temp(0).reg();
1459 element_address = index.IsRegister() 1408 element_address = index.IsRegister()
1460 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( 1409 ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
1461 index_scale(), temp, index.reg()) 1410 index_scale(), array, index.reg())
1462 : FlowGraphCompiler::ExternalElementAddressForIntIndex( 1411 : FlowGraphCompiler::ExternalElementAddressForIntIndex(
1463 index_scale(), temp, Smi::Cast(index.constant()).Value()); 1412 index_scale(), array, Smi::Cast(index.constant()).Value());
1464 __ movl(temp,
1465 FieldAddress(array, ExternalUint8Array::data_offset()));
1466 } else { 1413 } else {
1414 ASSERT(this->array()->definition()->representation() == kTagged);
1467 element_address = index.IsRegister() 1415 element_address = index.IsRegister()
1468 ? FlowGraphCompiler::ElementAddressForRegIndex( 1416 ? FlowGraphCompiler::ElementAddressForRegIndex(
1469 class_id(), index_scale(), array, index.reg()) 1417 class_id(), index_scale(), array, index.reg())
1470 : FlowGraphCompiler::ElementAddressForIntIndex( 1418 : FlowGraphCompiler::ElementAddressForIntIndex(
1471 class_id(), index_scale(), array, 1419 class_id(), index_scale(), array,
1472 Smi::Cast(index.constant()).Value()); 1420 Smi::Cast(index.constant()).Value());
1473 } 1421 }
1474 1422
1475 if ((index_scale() == 1) && index.IsRegister()) { 1423 if ((index_scale() == 1) && index.IsRegister()) {
1476 __ SmiUntag(index.reg()); 1424 __ SmiUntag(index.reg());
1477 } 1425 }
1478 switch (class_id()) { 1426 switch (class_id()) {
1479 case kArrayCid: 1427 case kArrayCid:
1480 if (ShouldEmitStoreBarrier()) { 1428 if (ShouldEmitStoreBarrier()) {
1481 Register value = locs()->in(2).reg(); 1429 Register value = locs()->in(2).reg();
1482 __ StoreIntoObject(array, element_address, value); 1430 __ StoreIntoObject(array, element_address, value);
1483 } else if (locs()->in(2).IsConstant()) { 1431 } else if (locs()->in(2).IsConstant()) {
1484 const Object& constant = locs()->in(2).constant(); 1432 const Object& constant = locs()->in(2).constant();
1485 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1433 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1486 } else { 1434 } else {
1487 Register value = locs()->in(2).reg(); 1435 Register value = locs()->in(2).reg();
1488 __ StoreIntoObjectNoBarrier(array, element_address, value); 1436 __ StoreIntoObjectNoBarrier(array, element_address, value);
1489 } 1437 }
1490 break; 1438 break;
1491 case kInt8ArrayCid:
1492 case kUint8ArrayCid:
1493 case kExternalUint8ArrayCid:
1494 case kTypedDataInt8ArrayCid: 1439 case kTypedDataInt8ArrayCid:
1495 case kTypedDataUint8ArrayCid: 1440 case kTypedDataUint8ArrayCid:
1496 case kExternalTypedDataUint8ArrayCid: 1441 case kExternalTypedDataUint8ArrayCid:
1497 if (locs()->in(2).IsConstant()) { 1442 if (locs()->in(2).IsConstant()) {
1498 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1443 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1499 __ movb(element_address, 1444 __ movb(element_address,
1500 Immediate(static_cast<int8_t>(constant.Value()))); 1445 Immediate(static_cast<int8_t>(constant.Value())));
1501 } else { 1446 } else {
1502 ASSERT(locs()->in(2).reg() == EAX); 1447 ASSERT(locs()->in(2).reg() == EAX);
1503 __ SmiUntag(EAX); 1448 __ SmiUntag(EAX);
1504 __ movb(element_address, AL); 1449 __ movb(element_address, AL);
1505 } 1450 }
1506 break; 1451 break;
1507 case kUint8ClampedArrayCid:
1508 case kExternalUint8ClampedArrayCid:
1509 case kTypedDataUint8ClampedArrayCid: 1452 case kTypedDataUint8ClampedArrayCid:
1510 case kExternalTypedDataUint8ClampedArrayCid: { 1453 case kExternalTypedDataUint8ClampedArrayCid: {
1511 if (locs()->in(2).IsConstant()) { 1454 if (locs()->in(2).IsConstant()) {
1512 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1455 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1513 intptr_t value = constant.Value(); 1456 intptr_t value = constant.Value();
1514 // Clamp to 0x0 or 0xFF respectively. 1457 // Clamp to 0x0 or 0xFF respectively.
1515 if (value > 0xFF) { 1458 if (value > 0xFF) {
1516 value = 0xFF; 1459 value = 0xFF;
1517 } else if (value < 0) { 1460 } else if (value < 0) {
1518 value = 0; 1461 value = 0;
(...skipping 10 matching lines...) Expand all
1529 __ j(GREATER, &store_0xff); 1472 __ j(GREATER, &store_0xff);
1530 __ xorl(EAX, EAX); 1473 __ xorl(EAX, EAX);
1531 __ jmp(&store_value, Assembler::kNearJump); 1474 __ jmp(&store_value, Assembler::kNearJump);
1532 __ Bind(&store_0xff); 1475 __ Bind(&store_0xff);
1533 __ movl(EAX, Immediate(0xFF)); 1476 __ movl(EAX, Immediate(0xFF));
1534 __ Bind(&store_value); 1477 __ Bind(&store_value);
1535 __ movb(element_address, AL); 1478 __ movb(element_address, AL);
1536 } 1479 }
1537 break; 1480 break;
1538 } 1481 }
1539 case kInt16ArrayCid:
1540 case kUint16ArrayCid:
1541 case kTypedDataInt16ArrayCid: 1482 case kTypedDataInt16ArrayCid:
1542 case kTypedDataUint16ArrayCid: { 1483 case kTypedDataUint16ArrayCid: {
1543 Register value = locs()->in(2).reg(); 1484 Register value = locs()->in(2).reg();
1544 __ SmiUntag(value); 1485 __ SmiUntag(value);
1545 __ movw(element_address, value); 1486 __ movw(element_address, value);
1546 break; 1487 break;
1547 } 1488 }
1548 case kInt32ArrayCid:
1549 case kUint32ArrayCid:
1550 case kTypedDataInt32ArrayCid: 1489 case kTypedDataInt32ArrayCid:
1551 case kTypedDataUint32ArrayCid: 1490 case kTypedDataUint32ArrayCid:
1552 if (value()->IsSmiValue()) { 1491 if (value()->IsSmiValue()) {
1553 ASSERT(RequiredInputRepresentation(2) == kTagged); 1492 ASSERT(RequiredInputRepresentation(2) == kTagged);
1554 Register value = locs()->in(2).reg(); 1493 Register value = locs()->in(2).reg();
1555 __ SmiUntag(value); 1494 __ SmiUntag(value);
1556 __ movl(element_address, value); 1495 __ movl(element_address, value);
1557 } else { 1496 } else {
1558 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); 1497 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint);
1559 __ movss(element_address, locs()->in(2).fpu_reg()); 1498 __ movss(element_address, locs()->in(2).fpu_reg());
1560 } 1499 }
1561 break; 1500 break;
1562 case kFloat32ArrayCid:
1563 case kTypedDataFloat32ArrayCid: 1501 case kTypedDataFloat32ArrayCid:
1564 // Convert to single precision. 1502 // Convert to single precision.
1565 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1503 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1566 // Store. 1504 // Store.
1567 __ movss(element_address, locs()->temp(0).fpu_reg()); 1505 __ movss(element_address, locs()->temp(0).fpu_reg());
1568 break; 1506 break;
1569 case kFloat64ArrayCid:
1570 case kTypedDataFloat64ArrayCid: 1507 case kTypedDataFloat64ArrayCid:
1571 __ movsd(element_address, locs()->in(2).fpu_reg()); 1508 __ movsd(element_address, locs()->in(2).fpu_reg());
1572 break; 1509 break;
1573 default: 1510 default:
1574 UNREACHABLE(); 1511 UNREACHABLE();
1575 } 1512 }
1576 } 1513 }
1577 1514
1578 1515
1579 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 1516 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const {
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 UNREACHABLE(); 2739 UNREACHABLE();
2803 } 2740 }
2804 } 2741 }
2805 2742
2806 2743
2807 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { 2744 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
2808 ASSERT((InputCount() == 1) || (InputCount() == 2)); 2745 ASSERT((InputCount() == 1) || (InputCount() == 2));
2809 const intptr_t kNumTemps = 0; 2746 const intptr_t kNumTemps = 0;
2810 LocationSummary* result = 2747 LocationSummary* result =
2811 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 2748 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
2812 result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); 2749 result->set_in(0, Location::FpuRegisterLocation(XMM1, kUnboxedDouble));
2813 if (InputCount() == 2) { 2750 if (InputCount() == 2) {
2814 result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); 2751 result->set_in(1, Location::FpuRegisterLocation(XMM2, kUnboxedDouble));
2815 } 2752 }
2816 result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); 2753 result->set_out(Location::FpuRegisterLocation(XMM1, kUnboxedDouble));
2817 return result; 2754 return result;
2818 } 2755 }
2819 2756
2820 2757
2821 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2758 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2822 __ EnterFrame(0); 2759 __ EnterFrame(0);
2823 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 2760 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
2824 for (intptr_t i = 0; i < InputCount(); i++) { 2761 for (intptr_t i = 0; i < InputCount(); i++) {
2825 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg()); 2762 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg());
2826 } 2763 }
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
3622 PcDescriptors::kOther, 3559 PcDescriptors::kOther,
3623 locs()); 3560 locs());
3624 __ Drop(2); // Discard type arguments and receiver. 3561 __ Drop(2); // Discard type arguments and receiver.
3625 } 3562 }
3626 3563
3627 } // namespace dart 3564 } // namespace dart
3628 3565
3629 #undef __ 3566 #undef __
3630 3567
3631 #endif // defined TARGET_ARCH_IA32 3568 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698