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

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

Issue 11967012: Optimized loads/stores for scalar list: Uint8Clamped, Int8, Int16, Uint16. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 } 1153 }
1154 1154
1155 1155
1156 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1156 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1157 Register array = locs()->in(0).reg(); 1157 Register array = locs()->in(0).reg();
1158 Location index = locs()->in(1); 1158 Location index = locs()->in(1);
1159 1159
1160 if (class_id() == kExternalUint8ArrayCid) { 1160 if (class_id() == kExternalUint8ArrayCid) {
1161 Register result = locs()->out().reg(); 1161 Register result = locs()->out().reg();
1162 Address element_address = index.IsRegister() 1162 Address element_address = index.IsRegister()
1163 ? Address(result, index.reg(), TIMES_1, 0) 1163 ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
1164 : Address(result, Smi::Cast(index.constant()).Value()); 1164 class_id(), result, index.reg())
1165 : FlowGraphCompiler::ExternalElementAddressForIntIndex(
1166 class_id(), result, Smi::Cast(index.constant()).Value());
1165 if (index.IsRegister()) { 1167 if (index.IsRegister()) {
1166 __ SmiUntag(index.reg()); 1168 __ SmiUntag(index.reg());
1167 } 1169 }
1168 __ movl(result, 1170 __ movl(result,
1169 FieldAddress(array, ExternalUint8Array::external_data_offset())); 1171 FieldAddress(array, ExternalUint8Array::external_data_offset()));
1170 __ movl(result, 1172 __ movl(result,
1171 Address(result, ExternalByteArrayData<uint8_t>::data_offset())); 1173 Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
1172 __ movzxb(result, element_address); 1174 __ movzxb(result, element_address);
1173 __ SmiTag(result); 1175 __ SmiTag(result);
1174 if (index.IsRegister()) { 1176 if (index.IsRegister()) {
1175 __ SmiTag(index.reg()); // Re-tag. 1177 __ SmiTag(index.reg()); // Re-tag.
1176 } 1178 }
1177 return; 1179 return;
1178 } 1180 }
1179 1181
1180 FieldAddress element_address = index.IsRegister() ? 1182 FieldAddress element_address = index.IsRegister()
1181 FlowGraphCompiler::ElementAddressForRegIndex( 1183 ? FlowGraphCompiler::ElementAddressForRegIndex(
1182 class_id(), array, index.reg()) : 1184 class_id(), array, index.reg())
1183 FlowGraphCompiler::ElementAddressForIntIndex( 1185 : FlowGraphCompiler::ElementAddressForIntIndex(
1184 class_id(), array, Smi::Cast(index.constant()).Value()); 1186 class_id(), array, Smi::Cast(index.constant()).Value());
1185 1187
1186 if (representation() == kUnboxedDouble) { 1188 if (representation() == kUnboxedDouble) {
1187 XmmRegister result = locs()->out().xmm_reg(); 1189 XmmRegister result = locs()->out().xmm_reg();
1188 if (class_id() == kFloat32ArrayCid) { 1190 if (class_id() == kFloat32ArrayCid) {
1189 // Load single precision float. 1191 // Load single precision float.
1190 __ movss(result, element_address); 1192 __ movss(result, element_address);
1191 // Promote to double. 1193 // Promote to double.
1192 __ cvtss2sd(result, locs()->out().xmm_reg()); 1194 __ cvtss2sd(result, locs()->out().xmm_reg());
1193 } else { 1195 } else {
1194 ASSERT(class_id() == kFloat64ArrayCid); 1196 ASSERT(class_id() == kFloat64ArrayCid);
1195 __ movsd(result, element_address); 1197 __ movsd(result, element_address);
1196 } 1198 }
1197 return; 1199 return;
1198 } 1200 }
1199 1201
1200 Register result = locs()->out().reg(); 1202 Register result = locs()->out().reg();
1201 if ((class_id() == kUint8ArrayCid) || 1203 switch (class_id()) {
1202 (class_id() == kUint8ClampedArrayCid)) { 1204 case kInt8ArrayCid:
1203 if (index.IsRegister()) { 1205 case kUint8ArrayCid:
1204 __ SmiUntag(index.reg()); 1206 case kUint8ClampedArrayCid:
1205 } 1207 if (index.IsRegister()) {
1206 __ movzxb(result, element_address); 1208 __ SmiUntag(index.reg());
1207 __ SmiTag(result); 1209 }
1208 if (index.IsRegister()) { 1210 if (class_id() == kInt8ArrayCid) {
1209 __ SmiTag(index.reg()); // Re-tag. 1211 __ movsxb(result, element_address);
1210 } 1212 } else {
1211 return; 1213 __ movzxb(result, element_address);
1214 }
1215 __ SmiTag(result);
1216 if (index.IsRegister()) {
1217 __ SmiTag(index.reg()); // Re-tag.
1218 }
1219 break;
1220 case kInt16ArrayCid:
1221 __ movsxw(result, element_address);
1222 __ SmiTag(result);
1223 break;
1224 case kUint16ArrayCid:
1225 __ movzxw(result, element_address);
1226 __ SmiTag(result);
1227 break;
1228 default:
1229 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1230 __ movl(result, element_address);
1231 break;
1212 } 1232 }
1213
1214 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1215 __ movl(result, element_address);
1216 } 1233 }
1217 1234
1218 1235
1219 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1236 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1220 const intptr_t kNumInputs = 3; 1237 const intptr_t kNumInputs = 3;
1221 const intptr_t kNumTemps = 0; 1238 const intptr_t kNumTemps = 0;
1222 LocationSummary* locs = 1239 LocationSummary* locs =
1223 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1240 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1224 locs->set_in(0, Location::RequiresRegister()); 1241 locs->set_in(0, Location::RequiresRegister());
1225 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1242 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
1226 ? Location::RegisterOrSmiConstant(index()) 1243 ? Location::RegisterOrSmiConstant(index())
1227 : Location::RequiresRegister()); 1244 : Location::RequiresRegister());
srdjan 2013/01/16 17:47:33 SInce index gets untagged, do you need writable re
Florian Schneider 2013/01/17 10:27:14 The smi index either gets retagged at the end (ele
1228 switch (class_id()) { 1245 switch (class_id()) {
1229 case kArrayCid: 1246 case kArrayCid:
1230 locs->set_in(2, ShouldEmitStoreBarrier() 1247 locs->set_in(2, ShouldEmitStoreBarrier()
1231 ? Location::WritableRegister() 1248 ? Location::WritableRegister()
1232 : Location::RegisterOrConstant(value())); 1249 : Location::RegisterOrConstant(value()));
1233 break; 1250 break;
1251 case kInt8ArrayCid:
1234 case kUint8ArrayCid: 1252 case kUint8ArrayCid:
1253 case kUint8ClampedArrayCid:
1235 // TODO(fschneider): Add location constraint for byte registers (EAX, 1254 // TODO(fschneider): Add location constraint for byte registers (EAX,
1236 // EBX, ECX, EDX) instead of using a fixed register. 1255 // EBX, ECX, EDX) instead of using a fixed register.
1237 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); 1256 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX));
1238 break; 1257 break;
1258 case kInt16ArrayCid:
1259 case kUint16ArrayCid:
srdjan 2013/01/16 17:47:33 Add a comment why a writable register.
Florian Schneider 2013/01/17 10:27:14 Done.
1260 locs->set_in(2, Location::WritableRegister());
1261 break;
1239 case kFloat32ArrayCid: 1262 case kFloat32ArrayCid:
1240 // Need temp register for float-to-double conversion. 1263 // Need temp register for float-to-double conversion.
1241 locs->AddTemp(Location::RequiresXmmRegister()); 1264 locs->AddTemp(Location::RequiresXmmRegister());
1242 // Fall through. 1265 // Fall through.
1243 case kFloat64ArrayCid: 1266 case kFloat64ArrayCid:
1244 // TODO(srdjan): Support Float64 constants. 1267 // TODO(srdjan): Support Float64 constants.
1245 locs->set_in(2, Location::RequiresXmmRegister()); 1268 locs->set_in(2, Location::RequiresXmmRegister());
1246 break; 1269 break;
1247 default: 1270 default:
1248 UNREACHABLE(); 1271 UNREACHABLE();
(...skipping 19 matching lines...) Expand all
1268 Register value = locs()->in(2).reg(); 1291 Register value = locs()->in(2).reg();
1269 __ StoreIntoObject(array, element_address, value); 1292 __ StoreIntoObject(array, element_address, value);
1270 } else if (locs()->in(2).IsConstant()) { 1293 } else if (locs()->in(2).IsConstant()) {
1271 const Object& constant = locs()->in(2).constant(); 1294 const Object& constant = locs()->in(2).constant();
1272 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1295 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1273 } else { 1296 } else {
1274 Register value = locs()->in(2).reg(); 1297 Register value = locs()->in(2).reg();
1275 __ StoreIntoObjectNoBarrier(array, element_address, value); 1298 __ StoreIntoObjectNoBarrier(array, element_address, value);
1276 } 1299 }
1277 break; 1300 break;
1301 case kInt8ArrayCid:
1278 case kUint8ArrayCid: 1302 case kUint8ArrayCid:
1279 if (index.IsRegister()) { 1303 if (index.IsRegister()) {
1280 __ SmiUntag(index.reg()); 1304 __ SmiUntag(index.reg());
1281 } 1305 }
1282 if (locs()->in(2).IsConstant()) { 1306 if (locs()->in(2).IsConstant()) {
1283 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1307 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1284 __ movb(element_address, 1308 __ movb(element_address,
1285 Immediate(static_cast<int8_t>(constant.Value()))); 1309 Immediate(static_cast<int8_t>(constant.Value())));
1286 } else { 1310 } else {
1287 ASSERT(locs()->in(2).reg() == EAX); 1311 ASSERT(locs()->in(2).reg() == EAX);
1288 __ SmiUntag(EAX); 1312 __ SmiUntag(EAX);
1289 __ movb(element_address, AL); 1313 __ movb(element_address, AL);
1290 } 1314 }
1291 if (index.IsRegister()) { 1315 if (index.IsRegister()) {
1292 __ SmiTag(index.reg()); // Re-tag. 1316 __ SmiTag(index.reg()); // Re-tag.
1293 } 1317 }
1294 break; 1318 break;
1319 case kUint8ClampedArrayCid: {
1320 if (index.IsRegister()) {
1321 __ SmiUntag(index.reg());
1322 }
1323 if (locs()->in(2).IsConstant()) {
1324 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1325 intptr_t value = constant.Value();
1326 // Clamp to 0x0 or 0xFF respectively.
1327 if (value > 0xFF) {
1328 value = 0xFF;
1329 } else if (value < 0) {
1330 value = 0;
1331 }
1332 __ movb(element_address,
1333 Immediate(static_cast<int8_t>(value)));
1334 } else {
1335 ASSERT(locs()->in(2).reg() == EAX);
1336 Label store_value, store_0xff;
1337 __ SmiUntag(EAX);
1338 __ cmpl(EAX, Immediate(0xFF));
1339 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
1340 // Clamp to 0x0 or 0xFF respectively.
1341 __ j(GREATER, &store_0xff);
1342 __ xorl(EAX, EAX);
1343 __ jmp(&store_value, Assembler::kNearJump);
1344 __ Bind(&store_0xff);
1345 __ movl(EAX, Immediate(0xFF));
1346 __ Bind(&store_value);
1347 __ movb(element_address, AL);
1348 }
1349 if (index.IsRegister()) {
1350 __ SmiTag(index.reg()); // Re-tag.
1351 }
1352 break;
1353 }
1354 case kInt16ArrayCid:
1355 case kUint16ArrayCid: {
1356 Register value = locs()->in(2).reg();
1357 __ SmiUntag(value);
1358 __ movw(element_address, value);
1359 break;
1360 }
1295 case kFloat32ArrayCid: 1361 case kFloat32ArrayCid:
1296 // Convert to single precision. 1362 // Convert to single precision.
1297 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg()); 1363 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg());
1298 // Store. 1364 // Store.
1299 __ movss(element_address, locs()->temp(0).xmm_reg()); 1365 __ movss(element_address, locs()->temp(0).xmm_reg());
1300 break; 1366 break;
1301 case kFloat64ArrayCid: 1367 case kFloat64ArrayCid:
1302 __ movsd(element_address, locs()->in(2).xmm_reg()); 1368 __ movsd(element_address, locs()->in(2).xmm_reg());
1303 break; 1369 break;
1304 default: 1370 default:
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1477 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1412 locs->set_in(0, Location::RegisterLocation(ECX)); 1478 locs->set_in(0, Location::RegisterLocation(ECX));
1413 locs->set_out(Location::RegisterLocation(EAX)); 1479 locs->set_out(Location::RegisterLocation(EAX));
1414 return locs; 1480 return locs;
1415 } 1481 }
1416 1482
1417 1483
1418 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1484 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1419 // Allocate the array. EDX = length, ECX = element type. 1485 // Allocate the array. EDX = length, ECX = element type.
1420 ASSERT(locs()->in(0).reg() == ECX); 1486 ASSERT(locs()->in(0).reg() == ECX);
1421 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); 1487 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount())));
1422 compiler->GenerateCall(token_pos(), 1488 compiler->GenerateCall(token_pos(),
1423 &StubCode::AllocateArrayLabel(), 1489 &StubCode::AllocateArrayLabel(),
1424 PcDescriptors::kOther, 1490 PcDescriptors::kOther,
1425 locs()); 1491 locs());
1426 ASSERT(locs()->out().reg() == EAX); 1492 ASSERT(locs()->out().reg() == EAX);
1427 1493
1428 // Pop the element values from the stack into the array. 1494 // Pop the element values from the stack into the array.
1429 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); 1495 __ leal(EDX, FieldAddress(EAX, Array::data_offset()));
1430 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1496 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1431 __ popl(Address(EDX, i * kWordSize)); 1497 __ popl(Address(EDX, i * kWordSize));
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2860 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 2926 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
2861 __ pxor(value, XMM0); 2927 __ pxor(value, XMM0);
2862 } 2928 }
2863 2929
2864 2930
2865 } // namespace dart 2931 } // namespace dart
2866 2932
2867 #undef __ 2933 #undef __
2868 2934
2869 #endif // defined TARGET_ARCH_X64 2935 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698