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

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: fixed math library, passes all tests 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
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::SameAsFirstInput());
1104 return locs;
1105 }
1106
1107
1108 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1109 Register object = locs()->in(0).reg();
1110 ASSERT(locs()->out().reg() == object);
1111 __ movl(object, 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 const bool is_external =
1217 (class_id() == kExternalUint8ClampedArrayCid) || 1213 (this->array()->definition()->representation() == kUntagged);
1218 (class_id() == kExternalTypedDataUint8ArrayCid) || 1214 Address element_address(kNoRegister, 0);
1219 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { 1215 if (is_external) {
1220 Register result = locs()->out().reg(); 1216 element_address = index.IsRegister()
1221 const Address& element_address = index.IsRegister()
1222 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( 1217 ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
1223 index_scale(), result, index.reg()) 1218 index_scale(), array, index.reg())
1224 : FlowGraphCompiler::ExternalElementAddressForIntIndex( 1219 : FlowGraphCompiler::ExternalElementAddressForIntIndex(
1225 index_scale(), result, Smi::Cast(index.constant()).Value()); 1220 index_scale(), array, Smi::Cast(index.constant()).Value());
1226 ASSERT(index_scale() == 1); 1221 } else {
1227 if (index.IsRegister()) { 1222 ASSERT(this->array()->definition()->representation() == kTagged);
1228 __ SmiUntag(index.reg()); 1223 element_address = index.IsRegister()
1229 } 1224 ? FlowGraphCompiler::ElementAddressForRegIndex(
1230 __ movl(result, 1225 class_id(), index_scale(), array, index.reg())
1231 FieldAddress(array, ExternalUint8Array::data_offset())); 1226 : FlowGraphCompiler::ElementAddressForIntIndex(
1232 __ movzxb(result, element_address); 1227 class_id(), index_scale(), array,
1233 __ SmiTag(result); 1228 Smi::Cast(index.constant()).Value());
1234 return;
1235 } 1229 }
1236 1230
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) || 1231 if ((representation() == kUnboxedDouble) ||
1245 (representation() == kUnboxedMint)) { 1232 (representation() == kUnboxedMint)) {
1246 XmmRegister result = locs()->out().fpu_reg(); 1233 XmmRegister result = locs()->out().fpu_reg();
1247 if ((index_scale() == 1) && index.IsRegister()) { 1234 if ((index_scale() == 1) && index.IsRegister()) {
1248 __ SmiUntag(index.reg()); 1235 __ SmiUntag(index.reg());
1249 } 1236 }
1250 switch (class_id()) { 1237 switch (class_id()) {
1251 case kInt32ArrayCid:
1252 case kTypedDataInt32ArrayCid: 1238 case kTypedDataInt32ArrayCid:
1253 __ movss(result, element_address); 1239 __ movss(result, element_address);
1254 __ pmovsxdq(result, result); 1240 __ pmovsxdq(result, result);
1255 break; 1241 break;
1256 case kUint32ArrayCid:
1257 case kTypedDataUint32ArrayCid: 1242 case kTypedDataUint32ArrayCid:
1258 __ xorpd(result, result); 1243 __ xorpd(result, result);
1259 __ movss(result, element_address); 1244 __ movss(result, element_address);
1260 break; 1245 break;
1261 case kFloat32ArrayCid:
1262 case kTypedDataFloat32ArrayCid: 1246 case kTypedDataFloat32ArrayCid:
1263 // Load single precision float and promote to double. 1247 // Load single precision float and promote to double.
1264 __ movss(result, element_address); 1248 __ movss(result, element_address);
1265 __ cvtss2sd(result, locs()->out().fpu_reg()); 1249 __ cvtss2sd(result, locs()->out().fpu_reg());
1266 break; 1250 break;
1267 case kFloat64ArrayCid:
1268 case kTypedDataFloat64ArrayCid: 1251 case kTypedDataFloat64ArrayCid:
1269 __ movsd(result, element_address); 1252 __ movsd(result, element_address);
1270 break; 1253 break;
1271 } 1254 }
1272 return; 1255 return;
1273 } 1256 }
1274 1257
1275 Register result = locs()->out().reg(); 1258 Register result = locs()->out().reg();
1276 if ((index_scale() == 1) && index.IsRegister()) { 1259 if ((index_scale() == 1) && index.IsRegister()) {
1277 __ SmiUntag(index.reg()); 1260 __ SmiUntag(index.reg());
1278 } 1261 }
1279 switch (class_id()) { 1262 switch (class_id()) {
1280 case kInt8ArrayCid:
1281 case kTypedDataInt8ArrayCid: 1263 case kTypedDataInt8ArrayCid:
1282 ASSERT(index_scale() == 1); 1264 ASSERT(index_scale() == 1);
1283 __ movsxb(result, element_address); 1265 __ movsxb(result, element_address);
1284 __ SmiTag(result); 1266 __ SmiTag(result);
1285 break; 1267 break;
1286 case kUint8ArrayCid:
1287 case kUint8ClampedArrayCid:
1288 case kTypedDataUint8ArrayCid: 1268 case kTypedDataUint8ArrayCid:
1289 case kTypedDataUint8ClampedArrayCid: 1269 case kTypedDataUint8ClampedArrayCid:
1270 case kExternalTypedDataUint8ArrayCid:
1271 case kExternalTypedDataUint8ClampedArrayCid:
1290 case kOneByteStringCid: 1272 case kOneByteStringCid:
1291 ASSERT(index_scale() == 1); 1273 ASSERT(index_scale() == 1);
1292 __ movzxb(result, element_address); 1274 __ movzxb(result, element_address);
1293 __ SmiTag(result); 1275 __ SmiTag(result);
1294 break; 1276 break;
1295 case kInt16ArrayCid:
1296 case kTypedDataInt16ArrayCid: 1277 case kTypedDataInt16ArrayCid:
1297 __ movsxw(result, element_address); 1278 __ movsxw(result, element_address);
1298 __ SmiTag(result); 1279 __ SmiTag(result);
1299 break; 1280 break;
1300 case kUint16ArrayCid:
1301 case kTypedDataUint16ArrayCid: 1281 case kTypedDataUint16ArrayCid:
1302 case kTwoByteStringCid: 1282 case kTwoByteStringCid:
1303 __ movzxw(result, element_address); 1283 __ movzxw(result, element_address);
1304 __ SmiTag(result); 1284 __ SmiTag(result);
1305 break; 1285 break;
1306 case kInt32ArrayCid:
1307 case kTypedDataInt32ArrayCid: { 1286 case kTypedDataInt32ArrayCid: {
1308 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); 1287 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
1309 __ movl(result, element_address); 1288 __ movl(result, element_address);
1310 // Verify that the signed value in 'result' can fit inside a Smi. 1289 // Verify that the signed value in 'result' can fit inside a Smi.
1311 __ cmpl(result, Immediate(0xC0000000)); 1290 __ cmpl(result, Immediate(0xC0000000));
1312 __ j(NEGATIVE, deopt); 1291 __ j(NEGATIVE, deopt);
1313 __ SmiTag(result); 1292 __ SmiTag(result);
1314 } 1293 }
1315 break; 1294 break;
1316 case kUint32ArrayCid:
1317 case kTypedDataUint32ArrayCid: { 1295 case kTypedDataUint32ArrayCid: {
1318 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); 1296 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
1319 __ movl(result, element_address); 1297 __ movl(result, element_address);
1320 // Verify that the unsigned value in 'result' can fit inside a Smi. 1298 // Verify that the unsigned value in 'result' can fit inside a Smi.
1321 __ testl(result, Immediate(0xC0000000)); 1299 __ testl(result, Immediate(0xC0000000));
1322 __ j(NOT_ZERO, deopt); 1300 __ j(NOT_ZERO, deopt);
1323 __ SmiTag(result); 1301 __ SmiTag(result);
1324 } 1302 }
1325 break; 1303 break;
1326 default: 1304 default:
1327 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1305 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1328 __ movl(result, element_address); 1306 __ movl(result, element_address);
1329 break; 1307 break;
1330 } 1308 }
1331 } 1309 }
1332 1310
1333 1311
1334 Representation StoreIndexedInstr::RequiredInputRepresentation( 1312 Representation StoreIndexedInstr::RequiredInputRepresentation(
1335 intptr_t idx) const { 1313 intptr_t idx) const {
1336 if ((idx == 0) || (idx == 1)) return kTagged; 1314 if (idx == 0) return kNoRepresentation; // Array can be tagged or untagged.
Vyacheslav Egorov (Google) 2013/03/18 18:42:29 Comment is somewhat confusing. Array can be either
Florian Schneider 2013/03/19 11:48:57 Done.
1315 if (idx == 1) return kTagged; // Index is a smi.
1337 ASSERT(idx == 2); 1316 ASSERT(idx == 2);
1338 switch (class_id_) { 1317 switch (class_id_) {
1339 case kArrayCid: 1318 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: 1319 case kTypedDataInt8ArrayCid:
1348 case kTypedDataUint8ArrayCid: 1320 case kTypedDataUint8ArrayCid:
1349 case kExternalTypedDataUint8ArrayCid: 1321 case kExternalTypedDataUint8ArrayCid:
1350 case kTypedDataUint8ClampedArrayCid: 1322 case kTypedDataUint8ClampedArrayCid:
1351 case kExternalTypedDataUint8ClampedArrayCid: 1323 case kExternalTypedDataUint8ClampedArrayCid:
1352 case kTypedDataInt16ArrayCid: 1324 case kTypedDataInt16ArrayCid:
1353 case kTypedDataUint16ArrayCid: 1325 case kTypedDataUint16ArrayCid:
1354 return kTagged; 1326 return kTagged;
1355 case kInt32ArrayCid:
1356 case kUint32ArrayCid:
1357 case kTypedDataInt32ArrayCid: 1327 case kTypedDataInt32ArrayCid:
1358 case kTypedDataUint32ArrayCid: 1328 case kTypedDataUint32ArrayCid:
1359 return value()->IsSmiValue() ? kTagged : kUnboxedMint; 1329 return value()->IsSmiValue() ? kTagged : kUnboxedMint;
1360 case kFloat32ArrayCid : 1330 case kTypedDataFloat32ArrayCid:
1361 case kFloat64ArrayCid : 1331 case kTypedDataFloat64ArrayCid:
1362 case kTypedDataFloat32ArrayCid :
1363 case kTypedDataFloat64ArrayCid :
1364 return kUnboxedDouble; 1332 return kUnboxedDouble;
1365 default: 1333 default:
1366 UNIMPLEMENTED(); 1334 UNIMPLEMENTED();
1367 return kTagged; 1335 return kTagged;
1368 } 1336 }
1369 } 1337 }
1370 1338
1371 1339
1372 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1340 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1373 const intptr_t kNumInputs = 3; 1341 const intptr_t kNumInputs = 3;
(...skipping 13 matching lines...) Expand all
1387 ? Location::Constant( 1355 ? Location::Constant(
1388 index()->definition()->AsConstant()->value()) 1356 index()->definition()->AsConstant()->value())
1389 : Location::RequiresRegister()); 1357 : Location::RequiresRegister());
1390 } 1358 }
1391 switch (class_id()) { 1359 switch (class_id()) {
1392 case kArrayCid: 1360 case kArrayCid:
1393 locs->set_in(2, ShouldEmitStoreBarrier() 1361 locs->set_in(2, ShouldEmitStoreBarrier()
1394 ? Location::WritableRegister() 1362 ? Location::WritableRegister()
1395 : Location::RegisterOrConstant(value())); 1363 : Location::RegisterOrConstant(value()));
1396 break; 1364 break;
1397 case kExternalUint8ArrayCid:
1398 case kExternalUint8ClampedArrayCid:
1399 case kExternalTypedDataUint8ArrayCid: 1365 case kExternalTypedDataUint8ArrayCid:
1400 case kExternalTypedDataUint8ClampedArrayCid: 1366 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: 1367 case kTypedDataInt8ArrayCid:
1408 case kTypedDataUint8ArrayCid: 1368 case kTypedDataUint8ArrayCid:
1409 case kTypedDataUint8ClampedArrayCid: 1369 case kTypedDataUint8ClampedArrayCid:
1410 // TODO(fschneider): Add location constraint for byte registers (EAX, 1370 // TODO(fschneider): Add location constraint for byte registers (EAX,
1411 // EBX, ECX, EDX) instead of using a fixed register. 1371 // EBX, ECX, EDX) instead of using a fixed register.
1412 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); 1372 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX));
1413 break; 1373 break;
1414 case kInt16ArrayCid:
1415 case kUint16ArrayCid:
1416 case kTypedDataInt16ArrayCid: 1374 case kTypedDataInt16ArrayCid:
1417 case kTypedDataUint16ArrayCid: 1375 case kTypedDataUint16ArrayCid:
1418 // Writable register because the value must be untagged before storing. 1376 // Writable register because the value must be untagged before storing.
1419 locs->set_in(2, Location::WritableRegister()); 1377 locs->set_in(2, Location::WritableRegister());
1420 break; 1378 break;
1421 case kInt32ArrayCid:
1422 case kUint32ArrayCid:
1423 case kTypedDataInt32ArrayCid: 1379 case kTypedDataInt32ArrayCid:
1424 case kTypedDataUint32ArrayCid: 1380 case kTypedDataUint32ArrayCid:
1425 // Mints are stored in XMM registers. For smis, use a writable register 1381 // Mints are stored in XMM registers. For smis, use a writable register
1426 // because the value must be untagged before storing. 1382 // because the value must be untagged before storing.
1427 locs->set_in(2, value()->IsSmiValue() 1383 locs->set_in(2, value()->IsSmiValue()
1428 ? Location::WritableRegister() 1384 ? Location::WritableRegister()
1429 : Location::RequiresFpuRegister()); 1385 : Location::RequiresFpuRegister());
1430 break; 1386 break;
1431 case kFloat32ArrayCid:
1432 case kTypedDataFloat32ArrayCid: 1387 case kTypedDataFloat32ArrayCid:
1433 // Need temp register for float-to-double conversion. 1388 // Need temp register for float-to-double conversion.
1434 locs->AddTemp(Location::RequiresFpuRegister()); 1389 locs->AddTemp(Location::RequiresFpuRegister());
1435 // Fall through. 1390 // Fall through.
1436 case kFloat64ArrayCid:
1437 case kTypedDataFloat64ArrayCid: 1391 case kTypedDataFloat64ArrayCid:
1438 // TODO(srdjan): Support Float64 constants. 1392 // TODO(srdjan): Support Float64 constants.
1439 locs->set_in(2, Location::RequiresFpuRegister()); 1393 locs->set_in(2, Location::RequiresFpuRegister());
1440 break; 1394 break;
1441 default: 1395 default:
1442 UNREACHABLE(); 1396 UNREACHABLE();
1443 return NULL; 1397 return NULL;
1444 } 1398 }
1445 return locs; 1399 return locs;
1446 } 1400 }
1447 1401
1448 1402
1449 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1403 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1450 Register array = locs()->in(0).reg(); 1404 Register array = locs()->in(0).reg();
1451 Location index = locs()->in(1); 1405 Location index = locs()->in(1);
1452 1406
1453 Address element_address(kNoRegister, 0); 1407 Address element_address(kNoRegister, 0);
1454 if ((class_id() == kExternalUint8ArrayCid) || 1408 const bool is_external =
Vyacheslav Egorov (Google) 2013/03/18 18:42:29 consider creating helper method {Store,Load}Indexe
Florian Schneider 2013/03/19 11:48:57 Done.
1455 (class_id() == kExternalUint8ClampedArrayCid) || 1409 (this->array()->definition()->representation() == kUntagged);
1456 (class_id() == kExternalTypedDataUint8ArrayCid) || 1410 if (is_external) {
1457 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
1458 Register temp = locs()->temp(0).reg();
1459 element_address = index.IsRegister() 1411 element_address = index.IsRegister()
1460 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( 1412 ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
1461 index_scale(), temp, index.reg()) 1413 index_scale(), array, index.reg())
1462 : FlowGraphCompiler::ExternalElementAddressForIntIndex( 1414 : FlowGraphCompiler::ExternalElementAddressForIntIndex(
1463 index_scale(), temp, Smi::Cast(index.constant()).Value()); 1415 index_scale(), array, Smi::Cast(index.constant()).Value());
1464 __ movl(temp,
1465 FieldAddress(array, ExternalUint8Array::data_offset()));
1466 } else { 1416 } else {
1417 ASSERT(this->array()->definition()->representation() == kTagged);
1467 element_address = index.IsRegister() 1418 element_address = index.IsRegister()
1468 ? FlowGraphCompiler::ElementAddressForRegIndex( 1419 ? FlowGraphCompiler::ElementAddressForRegIndex(
1469 class_id(), index_scale(), array, index.reg()) 1420 class_id(), index_scale(), array, index.reg())
1470 : FlowGraphCompiler::ElementAddressForIntIndex( 1421 : FlowGraphCompiler::ElementAddressForIntIndex(
1471 class_id(), index_scale(), array, 1422 class_id(), index_scale(), array,
1472 Smi::Cast(index.constant()).Value()); 1423 Smi::Cast(index.constant()).Value());
1473 } 1424 }
1474 1425
1475 if ((index_scale() == 1) && index.IsRegister()) { 1426 if ((index_scale() == 1) && index.IsRegister()) {
1476 __ SmiUntag(index.reg()); 1427 __ SmiUntag(index.reg());
1477 } 1428 }
1478 switch (class_id()) { 1429 switch (class_id()) {
1479 case kArrayCid: 1430 case kArrayCid:
1480 if (ShouldEmitStoreBarrier()) { 1431 if (ShouldEmitStoreBarrier()) {
1481 Register value = locs()->in(2).reg(); 1432 Register value = locs()->in(2).reg();
1482 __ StoreIntoObject(array, element_address, value); 1433 __ StoreIntoObject(array, element_address, value);
1483 } else if (locs()->in(2).IsConstant()) { 1434 } else if (locs()->in(2).IsConstant()) {
1484 const Object& constant = locs()->in(2).constant(); 1435 const Object& constant = locs()->in(2).constant();
1485 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1436 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1486 } else { 1437 } else {
1487 Register value = locs()->in(2).reg(); 1438 Register value = locs()->in(2).reg();
1488 __ StoreIntoObjectNoBarrier(array, element_address, value); 1439 __ StoreIntoObjectNoBarrier(array, element_address, value);
1489 } 1440 }
1490 break; 1441 break;
1491 case kInt8ArrayCid:
1492 case kUint8ArrayCid:
1493 case kExternalUint8ArrayCid:
1494 case kTypedDataInt8ArrayCid: 1442 case kTypedDataInt8ArrayCid:
1495 case kTypedDataUint8ArrayCid: 1443 case kTypedDataUint8ArrayCid:
1496 case kExternalTypedDataUint8ArrayCid: 1444 case kExternalTypedDataUint8ArrayCid:
1497 if (locs()->in(2).IsConstant()) { 1445 if (locs()->in(2).IsConstant()) {
1498 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1446 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1499 __ movb(element_address, 1447 __ movb(element_address,
1500 Immediate(static_cast<int8_t>(constant.Value()))); 1448 Immediate(static_cast<int8_t>(constant.Value())));
1501 } else { 1449 } else {
1502 ASSERT(locs()->in(2).reg() == EAX); 1450 ASSERT(locs()->in(2).reg() == EAX);
1503 __ SmiUntag(EAX); 1451 __ SmiUntag(EAX);
1504 __ movb(element_address, AL); 1452 __ movb(element_address, AL);
1505 } 1453 }
1506 break; 1454 break;
1507 case kUint8ClampedArrayCid:
1508 case kExternalUint8ClampedArrayCid:
1509 case kTypedDataUint8ClampedArrayCid: 1455 case kTypedDataUint8ClampedArrayCid:
1510 case kExternalTypedDataUint8ClampedArrayCid: { 1456 case kExternalTypedDataUint8ClampedArrayCid: {
1511 if (locs()->in(2).IsConstant()) { 1457 if (locs()->in(2).IsConstant()) {
1512 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1458 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1513 intptr_t value = constant.Value(); 1459 intptr_t value = constant.Value();
1514 // Clamp to 0x0 or 0xFF respectively. 1460 // Clamp to 0x0 or 0xFF respectively.
1515 if (value > 0xFF) { 1461 if (value > 0xFF) {
1516 value = 0xFF; 1462 value = 0xFF;
1517 } else if (value < 0) { 1463 } else if (value < 0) {
1518 value = 0; 1464 value = 0;
(...skipping 10 matching lines...) Expand all
1529 __ j(GREATER, &store_0xff); 1475 __ j(GREATER, &store_0xff);
1530 __ xorl(EAX, EAX); 1476 __ xorl(EAX, EAX);
1531 __ jmp(&store_value, Assembler::kNearJump); 1477 __ jmp(&store_value, Assembler::kNearJump);
1532 __ Bind(&store_0xff); 1478 __ Bind(&store_0xff);
1533 __ movl(EAX, Immediate(0xFF)); 1479 __ movl(EAX, Immediate(0xFF));
1534 __ Bind(&store_value); 1480 __ Bind(&store_value);
1535 __ movb(element_address, AL); 1481 __ movb(element_address, AL);
1536 } 1482 }
1537 break; 1483 break;
1538 } 1484 }
1539 case kInt16ArrayCid:
1540 case kUint16ArrayCid:
1541 case kTypedDataInt16ArrayCid: 1485 case kTypedDataInt16ArrayCid:
1542 case kTypedDataUint16ArrayCid: { 1486 case kTypedDataUint16ArrayCid: {
1543 Register value = locs()->in(2).reg(); 1487 Register value = locs()->in(2).reg();
1544 __ SmiUntag(value); 1488 __ SmiUntag(value);
1545 __ movw(element_address, value); 1489 __ movw(element_address, value);
1546 break; 1490 break;
1547 } 1491 }
1548 case kInt32ArrayCid:
1549 case kUint32ArrayCid:
1550 case kTypedDataInt32ArrayCid: 1492 case kTypedDataInt32ArrayCid:
1551 case kTypedDataUint32ArrayCid: 1493 case kTypedDataUint32ArrayCid:
1552 if (value()->IsSmiValue()) { 1494 if (value()->IsSmiValue()) {
1553 ASSERT(RequiredInputRepresentation(2) == kTagged); 1495 ASSERT(RequiredInputRepresentation(2) == kTagged);
1554 Register value = locs()->in(2).reg(); 1496 Register value = locs()->in(2).reg();
1555 __ SmiUntag(value); 1497 __ SmiUntag(value);
1556 __ movl(element_address, value); 1498 __ movl(element_address, value);
1557 } else { 1499 } else {
1558 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); 1500 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint);
1559 __ movss(element_address, locs()->in(2).fpu_reg()); 1501 __ movss(element_address, locs()->in(2).fpu_reg());
1560 } 1502 }
1561 break; 1503 break;
1562 case kFloat32ArrayCid:
1563 case kTypedDataFloat32ArrayCid: 1504 case kTypedDataFloat32ArrayCid:
1564 // Convert to single precision. 1505 // Convert to single precision.
1565 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1506 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1566 // Store. 1507 // Store.
1567 __ movss(element_address, locs()->temp(0).fpu_reg()); 1508 __ movss(element_address, locs()->temp(0).fpu_reg());
1568 break; 1509 break;
1569 case kFloat64ArrayCid:
1570 case kTypedDataFloat64ArrayCid: 1510 case kTypedDataFloat64ArrayCid:
1571 __ movsd(element_address, locs()->in(2).fpu_reg()); 1511 __ movsd(element_address, locs()->in(2).fpu_reg());
1572 break; 1512 break;
1573 default: 1513 default:
1574 UNREACHABLE(); 1514 UNREACHABLE();
1575 } 1515 }
1576 } 1516 }
1577 1517
1578 1518
1579 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 1519 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const {
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 UNREACHABLE(); 2742 UNREACHABLE();
2803 } 2743 }
2804 } 2744 }
2805 2745
2806 2746
2807 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { 2747 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
2808 ASSERT((InputCount() == 1) || (InputCount() == 2)); 2748 ASSERT((InputCount() == 1) || (InputCount() == 2));
2809 const intptr_t kNumTemps = 0; 2749 const intptr_t kNumTemps = 0;
2810 LocationSummary* result = 2750 LocationSummary* result =
2811 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 2751 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
2812 result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); 2752 result->set_in(0, Location::FpuRegisterLocation(XMM1, kUnboxedDouble));
2813 if (InputCount() == 2) { 2753 if (InputCount() == 2) {
2814 result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); 2754 result->set_in(1, Location::FpuRegisterLocation(XMM2, kUnboxedDouble));
2815 } 2755 }
2816 result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); 2756 result->set_out(Location::FpuRegisterLocation(XMM1, kUnboxedDouble));
2817 return result; 2757 return result;
2818 } 2758 }
2819 2759
2820 2760
2821 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2761 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2822 __ EnterFrame(0); 2762 __ EnterFrame(0);
2823 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 2763 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
2824 for (intptr_t i = 0; i < InputCount(); i++) { 2764 for (intptr_t i = 0; i < InputCount(); i++) {
2825 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg()); 2765 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg());
2826 } 2766 }
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
3622 PcDescriptors::kOther, 3562 PcDescriptors::kOther,
3623 locs()); 3563 locs());
3624 __ Drop(2); // Discard type arguments and receiver. 3564 __ Drop(2); // Discard type arguments and receiver.
3625 } 3565 }
3626 3566
3627 } // namespace dart 3567 } // namespace dart
3628 3568
3629 #undef __ 3569 #undef __
3630 3570
3631 #endif // defined TARGET_ARCH_IA32 3571 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698