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

Side by Side Diff: src/arm/lithium-arm.cc

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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 | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 arguments()->PrintTo(stream); 339 arguments()->PrintTo(stream);
340 340
341 stream->Add(" length "); 341 stream->Add(" length ");
342 length()->PrintTo(stream); 342 length()->PrintTo(stream);
343 343
344 stream->Add(" index "); 344 stream->Add(" index ");
345 index()->PrintTo(stream); 345 index()->PrintTo(stream);
346 } 346 }
347 347
348 348
349 void LStoreNamed::PrintDataTo(StringStream* stream) { 349 void LStoreNamedField::PrintDataTo(StringStream* stream) {
350 object()->PrintTo(stream); 350 object()->PrintTo(stream);
351 stream->Add("."); 351 stream->Add(".");
352 stream->Add(*String::cast(*name())->ToCString()); 352 stream->Add(*String::cast(*name())->ToCString());
353 stream->Add(" <- "); 353 stream->Add(" <- ");
354 value()->PrintTo(stream); 354 value()->PrintTo(stream);
355 } 355 }
356 356
357 357
358 void LStoreKeyed::PrintDataTo(StringStream* stream) { 358 void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
359 object()->PrintTo(stream);
360 stream->Add(".");
361 stream->Add(*String::cast(*name())->ToCString());
362 stream->Add(" <- ");
363 value()->PrintTo(stream);
364 }
365
366
367 void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
359 object()->PrintTo(stream); 368 object()->PrintTo(stream);
360 stream->Add("["); 369 stream->Add("[");
361 key()->PrintTo(stream); 370 key()->PrintTo(stream);
362 stream->Add("] <- "); 371 stream->Add("] <- ");
363 value()->PrintTo(stream); 372 value()->PrintTo(stream);
364 } 373 }
365 374
366 375
367 LChunk::LChunk(HGraph* graph) 376 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
377 object()->PrintTo(stream);
378 stream->Add("[");
379 key()->PrintTo(stream);
380 stream->Add("] <- ");
381 value()->PrintTo(stream);
382 }
383
384
385 LChunk::LChunk(CompilationInfo* info, HGraph* graph)
368 : spill_slot_count_(0), 386 : spill_slot_count_(0),
387 info_(info),
369 graph_(graph), 388 graph_(graph),
370 instructions_(32), 389 instructions_(32),
371 pointer_maps_(8), 390 pointer_maps_(8),
372 inlined_closures_(1) { 391 inlined_closures_(1) {
373 } 392 }
374 393
375 394
376 int LChunk::GetNextSpillIndex(bool is_double) { 395 int LChunk::GetNextSpillIndex(bool is_double) {
377 // Skip a slot if for a double-width slot. 396 // Skip a slot if for a double-width slot.
378 if (is_double) spill_slot_count_++; 397 if (is_double) spill_slot_count_++;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { 468 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
450 return LConstantOperand::Create(constant->id()); 469 return LConstantOperand::Create(constant->id());
451 } 470 }
452 471
453 472
454 int LChunk::GetParameterStackSlot(int index) const { 473 int LChunk::GetParameterStackSlot(int index) const {
455 // The receiver is at index 0, the first parameter at index 1, so we 474 // The receiver is at index 0, the first parameter at index 1, so we
456 // shift all parameter indexes down by the number of parameters, and 475 // shift all parameter indexes down by the number of parameters, and
457 // make sure they end up negative so they are distinguishable from 476 // make sure they end up negative so they are distinguishable from
458 // spill slots. 477 // spill slots.
459 int result = index - graph()->info()->scope()->num_parameters() - 1; 478 int result = index - info()->scope()->num_parameters() - 1;
460 ASSERT(result < 0); 479 ASSERT(result < 0);
461 return result; 480 return result;
462 } 481 }
463 482
464 // A parameter relative to ebp in the arguments stub. 483 // A parameter relative to ebp in the arguments stub.
465 int LChunk::ParameterAt(int index) { 484 int LChunk::ParameterAt(int index) {
466 ASSERT(-1 <= index); // -1 is the receiver. 485 ASSERT(-1 <= index); // -1 is the receiver.
467 return (1 + graph()->info()->scope()->num_parameters() - index) * 486 return (1 + info()->scope()->num_parameters() - index) *
468 kPointerSize; 487 kPointerSize;
469 } 488 }
470 489
471 490
472 LGap* LChunk::GetGapAt(int index) const { 491 LGap* LChunk::GetGapAt(int index) const {
473 return LGap::cast(instructions_[index]); 492 return LGap::cast(instructions_[index]);
474 } 493 }
475 494
476 495
477 bool LChunk::IsGapAt(int index) const { 496 bool LChunk::IsGapAt(int index) const {
(...skipping 18 matching lines...) Expand all
496 515
497 516
498 Representation LChunk::LookupLiteralRepresentation( 517 Representation LChunk::LookupLiteralRepresentation(
499 LConstantOperand* operand) const { 518 LConstantOperand* operand) const {
500 return graph_->LookupValue(operand->index())->representation(); 519 return graph_->LookupValue(operand->index())->representation();
501 } 520 }
502 521
503 522
504 LChunk* LChunkBuilder::Build() { 523 LChunk* LChunkBuilder::Build() {
505 ASSERT(is_unused()); 524 ASSERT(is_unused());
506 chunk_ = new LChunk(graph()); 525 chunk_ = new LChunk(info(), graph());
507 HPhase phase("Building chunk", chunk_); 526 HPhase phase("Building chunk", chunk_);
508 status_ = BUILDING; 527 status_ = BUILDING;
509 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 528 const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
510 for (int i = 0; i < blocks->length(); i++) { 529 for (int i = 0; i < blocks->length(); i++) {
511 HBasicBlock* next = NULL; 530 HBasicBlock* next = NULL;
512 if (i < blocks->length() - 1) next = blocks->at(i + 1); 531 if (i < blocks->length() - 1) next = blocks->at(i + 1);
513 DoBasicBlock(blocks->at(i), next); 532 DoBasicBlock(blocks->at(i), next);
514 if (is_aborted()) return NULL; 533 if (is_aborted()) return NULL;
515 } 534 }
516 status_ = DONE; 535 status_ = DONE;
517 return chunk_; 536 return chunk_;
518 } 537 }
519 538
520 539
521 void LChunkBuilder::Abort(const char* format, ...) { 540 void LChunkBuilder::Abort(const char* format, ...) {
522 if (FLAG_trace_bailout) { 541 if (FLAG_trace_bailout) {
523 SmartPointer<char> debug_name = graph()->debug_name()->ToCString(); 542 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
524 PrintF("Aborting LChunk building in @\"%s\": ", *debug_name); 543 PrintF("Aborting LChunk building in @\"%s\": ", *name);
525 va_list arguments; 544 va_list arguments;
526 va_start(arguments, format); 545 va_start(arguments, format);
527 OS::VPrint(format, arguments); 546 OS::VPrint(format, arguments);
528 va_end(arguments); 547 va_end(arguments);
529 PrintF("\n"); 548 PrintF("\n");
530 } 549 }
531 status_ = ABORTED; 550 status_ = ABORTED;
532 } 551 }
533 552
534 553
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 if (can_deopt) AssignEnvironment(result); 867 if (can_deopt) AssignEnvironment(result);
849 return result; 868 return result;
850 } 869 }
851 870
852 871
853 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 872 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
854 HArithmeticBinaryOperation* instr) { 873 HArithmeticBinaryOperation* instr) {
855 ASSERT(instr->representation().IsDouble()); 874 ASSERT(instr->representation().IsDouble());
856 ASSERT(instr->left()->representation().IsDouble()); 875 ASSERT(instr->left()->representation().IsDouble());
857 ASSERT(instr->right()->representation().IsDouble()); 876 ASSERT(instr->right()->representation().IsDouble());
877 ASSERT(op != Token::MOD);
858 LOperand* left = UseRegisterAtStart(instr->left()); 878 LOperand* left = UseRegisterAtStart(instr->left());
859 LOperand* right = UseRegisterAtStart(instr->right()); 879 LOperand* right = UseRegisterAtStart(instr->right());
860 LArithmeticD* result = new LArithmeticD(op, left, right); 880 LArithmeticD* result = new LArithmeticD(op, left, right);
861 return DefineSameAsFirst(result); 881 return DefineSameAsFirst(result);
862 } 882 }
863 883
864 884
865 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, 885 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
866 HArithmeticBinaryOperation* instr) { 886 HArithmeticBinaryOperation* instr) {
867 ASSERT(op == Token::ADD || 887 ASSERT(op == Token::ADD ||
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 new LInstanceOf(UseFixed(instr->left(), r0), 1149 new LInstanceOf(UseFixed(instr->left(), r0),
1130 UseFixed(instr->right(), r1)); 1150 UseFixed(instr->right(), r1));
1131 return MarkAsCall(DefineFixed(result, r0), instr); 1151 return MarkAsCall(DefineFixed(result, r0), instr);
1132 } 1152 }
1133 1153
1134 1154
1135 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1155 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1136 HInstanceOfKnownGlobal* instr) { 1156 HInstanceOfKnownGlobal* instr) {
1137 LInstanceOfKnownGlobal* result = 1157 LInstanceOfKnownGlobal* result =
1138 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4)); 1158 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4));
1139 MarkAsSaveDoubles(result); 1159 return MarkAsCall(DefineFixed(result, r0), instr);
1140 return AssignEnvironment(AssignPointerMap(DefineFixed(result, r0)));
1141 } 1160 }
1142 1161
1143 1162
1144 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1163 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1145 LOperand* function = UseFixed(instr->function(), r1); 1164 LOperand* function = UseFixed(instr->function(), r1);
1146 LOperand* receiver = UseFixed(instr->receiver(), r0); 1165 LOperand* receiver = UseFixed(instr->receiver(), r0);
1147 LOperand* length = UseFixed(instr->length(), r2); 1166 LOperand* length = UseFixed(instr->length(), r2);
1148 LOperand* elements = UseFixed(instr->elements(), r3); 1167 LOperand* elements = UseFixed(instr->elements(), r3);
1149 LApplyArguments* result = new LApplyArguments(function, 1168 LApplyArguments* result = new LApplyArguments(function,
1150 receiver, 1169 receiver,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 1205
1187 LInstruction* LChunkBuilder::DoCallConstantFunction( 1206 LInstruction* LChunkBuilder::DoCallConstantFunction(
1188 HCallConstantFunction* instr) { 1207 HCallConstantFunction* instr) {
1189 argument_count_ -= instr->argument_count(); 1208 argument_count_ -= instr->argument_count();
1190 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr); 1209 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr);
1191 } 1210 }
1192 1211
1193 1212
1194 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1213 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1195 BuiltinFunctionId op = instr->op(); 1214 BuiltinFunctionId op = instr->op();
1196 LOperand* input = UseRegisterAtStart(instr->value()); 1215 if (op == kMathLog || op == kMathSin || op == kMathCos) {
1197 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL; 1216 LOperand* input = UseFixedDouble(instr->value(), d2);
1198 LUnaryMathOperation* result = new LUnaryMathOperation(input, temp); 1217 LUnaryMathOperation* result = new LUnaryMathOperation(input, NULL);
1199 switch (op) { 1218 return MarkAsCall(DefineFixedDouble(result, d2), instr);
1200 case kMathAbs: 1219 } else {
1201 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1220 LOperand* input = UseRegisterAtStart(instr->value());
1202 case kMathFloor: 1221 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
1203 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1222 LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
1204 case kMathSqrt: 1223 switch (op) {
1205 return DefineSameAsFirst(result); 1224 case kMathAbs:
1206 case kMathRound: 1225 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1207 Abort("MathRound LUnaryMathOperation not implemented"); 1226 case kMathFloor:
1208 return NULL; 1227 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1209 case kMathPowHalf: 1228 case kMathSqrt:
1210 Abort("MathPowHalf LUnaryMathOperation not implemented"); 1229 return DefineSameAsFirst(result);
1211 return NULL; 1230 case kMathRound:
1212 case kMathLog: 1231 return AssignEnvironment(DefineAsRegister(result));
1213 Abort("MathLog LUnaryMathOperation not implemented"); 1232 case kMathPowHalf:
1214 return NULL; 1233 return DefineSameAsFirst(result);
1215 case kMathCos: 1234 default:
1216 Abort("MathCos LUnaryMathOperation not implemented"); 1235 UNREACHABLE();
1217 return NULL; 1236 return NULL;
1218 case kMathSin: 1237 }
1219 Abort("MathSin LUnaryMathOperation not implemented");
1220 return NULL;
1221 default:
1222 UNREACHABLE();
1223 return NULL;
1224 } 1238 }
1225 } 1239 }
1226 1240
1227 1241
1228 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1242 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1229 ASSERT(instr->key()->representation().IsTagged()); 1243 ASSERT(instr->key()->representation().IsTagged());
1230 argument_count_ -= instr->argument_count(); 1244 argument_count_ -= instr->argument_count();
1231 LOperand* key = UseFixed(instr->key(), r2); 1245 LOperand* key = UseFixed(instr->key(), r2);
1232 return MarkAsCall(DefineFixed(new LCallKeyed(key), r0), instr); 1246 return MarkAsCall(DefineFixed(new LCallKeyed(key), r0), instr);
1233 } 1247 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 1343
1330 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1344 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1331 if (instr->representation().IsInteger32()) { 1345 if (instr->representation().IsInteger32()) {
1332 // TODO(1042) The fixed register allocation 1346 // TODO(1042) The fixed register allocation
1333 // is needed because we call GenericBinaryOpStub from 1347 // is needed because we call GenericBinaryOpStub from
1334 // the generated code, which requires registers r0 1348 // the generated code, which requires registers r0
1335 // and r1 to be used. We should remove that 1349 // and r1 to be used. We should remove that
1336 // when we provide a native implementation. 1350 // when we provide a native implementation.
1337 ASSERT(instr->left()->representation().IsInteger32()); 1351 ASSERT(instr->left()->representation().IsInteger32());
1338 ASSERT(instr->right()->representation().IsInteger32()); 1352 ASSERT(instr->right()->representation().IsInteger32());
1339 LOperand* value = UseFixed(instr->left(), r0); 1353
1340 LOperand* divisor = UseFixed(instr->right(), r1); 1354 LInstruction* result;
1341 LInstruction* result = DefineFixed(new LModI(value, divisor), r0); 1355 if (instr->HasPowerOf2Divisor()) {
1342 result = AssignEnvironment(AssignPointerMap(result)); 1356 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1357 LOperand* value = UseRegisterAtStart(instr->left());
1358 LModI* mod = new LModI(value, UseOrConstant(instr->right()));
1359 result = DefineSameAsFirst(mod);
1360 result = AssignEnvironment(result);
1361 } else {
1362 LOperand* value = UseFixed(instr->left(), r0);
1363 LOperand* divisor = UseFixed(instr->right(), r1);
1364 result = DefineFixed(new LModI(value, divisor), r0);
1365 result = AssignEnvironment(AssignPointerMap(result));
1366 }
1367
1343 return result; 1368 return result;
1344 } else if (instr->representation().IsTagged()) { 1369 } else if (instr->representation().IsTagged()) {
1345 return DoArithmeticT(Token::MOD, instr); 1370 return DoArithmeticT(Token::MOD, instr);
1346 } else { 1371 } else {
1347 ASSERT(instr->representation().IsDouble()); 1372 ASSERT(instr->representation().IsDouble());
1348 // We call a C function for double modulo. It can't trigger a GC. 1373 // We call a C function for double modulo. It can't trigger a GC.
1349 // We need to use fixed result register for the call. 1374 // We need to use fixed result register for the call.
1350 // TODO(fschneider): Allow any register as input registers. 1375 // TODO(fschneider): Allow any register as input registers.
1351 LOperand* left = UseFixedDouble(instr->left(), d1); 1376 LOperand* left = UseFixedDouble(instr->left(), d1);
1352 LOperand* right = UseFixedDouble(instr->right(), d2); 1377 LOperand* right = UseFixedDouble(instr->right(), d2);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 } else if (instr->representation().IsDouble()) { 1436 } else if (instr->representation().IsDouble()) {
1412 return DoArithmeticD(Token::ADD, instr); 1437 return DoArithmeticD(Token::ADD, instr);
1413 } else { 1438 } else {
1414 ASSERT(instr->representation().IsTagged()); 1439 ASSERT(instr->representation().IsTagged());
1415 return DoArithmeticT(Token::ADD, instr); 1440 return DoArithmeticT(Token::ADD, instr);
1416 } 1441 }
1417 } 1442 }
1418 1443
1419 1444
1420 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1445 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1421 Abort("LPower instruction not implemented on ARM"); 1446 ASSERT(instr->representation().IsDouble());
1422 return NULL; 1447 // We call a C function for double power. It can't trigger a GC.
1448 // We need to use fixed result register for the call.
1449 Representation exponent_type = instr->right()->representation();
1450 ASSERT(instr->left()->representation().IsDouble());
1451 LOperand* left = UseFixedDouble(instr->left(), d1);
1452 LOperand* right = exponent_type.IsDouble() ?
1453 UseFixedDouble(instr->right(), d2) :
1454 UseFixed(instr->right(), r0);
1455 LPower* result = new LPower(left, right);
1456 return MarkAsCall(DefineFixedDouble(result, d3),
1457 instr,
1458 CAN_DEOPTIMIZE_EAGERLY);
1423 } 1459 }
1424 1460
1425 1461
1426 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1462 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1427 Token::Value op = instr->token(); 1463 Token::Value op = instr->token();
1428 Representation r = instr->GetInputRepresentation(); 1464 Representation r = instr->GetInputRepresentation();
1429 if (r.IsInteger32()) { 1465 if (r.IsInteger32()) {
1430 ASSERT(instr->left()->representation().IsInteger32()); 1466 ASSERT(instr->left()->representation().IsInteger32());
1431 ASSERT(instr->right()->representation().IsInteger32()); 1467 ASSERT(instr->right()->representation().IsInteger32());
1432 LOperand* left = UseRegisterAtStart(instr->left()); 1468 LOperand* left = UseRegisterAtStart(instr->left());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 1520
1485 1521
1486 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { 1522 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
1487 ASSERT(instr->value()->representation().IsTagged()); 1523 ASSERT(instr->value()->representation().IsTagged());
1488 LOperand* value = UseRegisterAtStart(instr->value()); 1524 LOperand* value = UseRegisterAtStart(instr->value());
1489 1525
1490 return DefineAsRegister(new LHasInstanceType(value)); 1526 return DefineAsRegister(new LHasInstanceType(value));
1491 } 1527 }
1492 1528
1493 1529
1530 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1531 HGetCachedArrayIndex* instr) {
1532 ASSERT(instr->value()->representation().IsTagged());
1533 LOperand* value = UseRegisterAtStart(instr->value());
1534
1535 return DefineAsRegister(new LGetCachedArrayIndex(value));
1536 }
1537
1538
1494 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( 1539 LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
1495 HHasCachedArrayIndex* instr) { 1540 HHasCachedArrayIndex* instr) {
1496 ASSERT(instr->value()->representation().IsTagged()); 1541 ASSERT(instr->value()->representation().IsTagged());
1497 LOperand* value = UseRegister(instr->value()); 1542 LOperand* value = UseRegister(instr->value());
1498 1543
1499 return DefineAsRegister(new LHasCachedArrayIndex(value)); 1544 return DefineAsRegister(new LHasCachedArrayIndex(value));
1500 } 1545 }
1501 1546
1502 1547
1503 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1548 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1504 ASSERT(instr->value()->representation().IsTagged()); 1549 ASSERT(instr->value()->representation().IsTagged());
1505 LOperand* value = UseTempRegister(instr->value()); 1550 LOperand* value = UseTempRegister(instr->value());
1506 return DefineSameAsFirst(new LClassOfTest(value)); 1551 return DefineSameAsFirst(new LClassOfTest(value));
1507 } 1552 }
1508 1553
1509 1554
1510 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1555 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1511 LOperand* array = UseRegisterAtStart(instr->value()); 1556 LOperand* array = UseRegisterAtStart(instr->value());
1512 return DefineAsRegister(new LJSArrayLength(array)); 1557 return DefineAsRegister(new LJSArrayLength(array));
1513 } 1558 }
1514 1559
1515 1560
1516 LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) { 1561 LInstruction* LChunkBuilder::DoExternalArrayLength(
1562 HExternalArrayLength* instr) {
1517 LOperand* array = UseRegisterAtStart(instr->value()); 1563 LOperand* array = UseRegisterAtStart(instr->value());
1518 return DefineAsRegister(new LPixelArrayLength(array)); 1564 return DefineAsRegister(new LExternalArrayLength(array));
1519 } 1565 }
1520 1566
1521 1567
1522 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1568 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1523 LOperand* array = UseRegisterAtStart(instr->value()); 1569 LOperand* array = UseRegisterAtStart(instr->value());
1524 return DefineAsRegister(new LFixedArrayLength(array)); 1570 return DefineAsRegister(new LFixedArrayLength(array));
1525 } 1571 }
1526 1572
1527 1573
1528 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1574 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
(...skipping 28 matching lines...) Expand all
1557 if (from.IsTagged()) { 1603 if (from.IsTagged()) {
1558 if (to.IsDouble()) { 1604 if (to.IsDouble()) {
1559 LOperand* value = UseRegister(instr->value()); 1605 LOperand* value = UseRegister(instr->value());
1560 LNumberUntagD* res = new LNumberUntagD(value); 1606 LNumberUntagD* res = new LNumberUntagD(value);
1561 return AssignEnvironment(DefineAsRegister(res)); 1607 return AssignEnvironment(DefineAsRegister(res));
1562 } else { 1608 } else {
1563 ASSERT(to.IsInteger32()); 1609 ASSERT(to.IsInteger32());
1564 LOperand* value = UseRegister(instr->value()); 1610 LOperand* value = UseRegister(instr->value());
1565 bool needs_check = !instr->value()->type().IsSmi(); 1611 bool needs_check = !instr->value()->type().IsSmi();
1566 LInstruction* res = NULL; 1612 LInstruction* res = NULL;
1567 if (needs_check) { 1613 if (!needs_check) {
1568 res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1))); 1614 res = DefineSameAsFirst(new LSmiUntag(value, needs_check));
1569 } else { 1615 } else {
1570 res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1616 LOperand* temp1 = TempRegister();
1571 } 1617 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
1572 if (needs_check) { 1618 : NULL;
1619 LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3)
1620 : NULL;
1621 res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3));
1573 res = AssignEnvironment(res); 1622 res = AssignEnvironment(res);
1574 } 1623 }
1575 return res; 1624 return res;
1576 } 1625 }
1577 } else if (from.IsDouble()) { 1626 } else if (from.IsDouble()) {
1578 if (to.IsTagged()) { 1627 if (to.IsTagged()) {
1579 LOperand* value = UseRegister(instr->value()); 1628 LOperand* value = UseRegister(instr->value());
1580 LOperand* temp1 = TempRegister(); 1629 LOperand* temp1 = TempRegister();
1581 LOperand* temp2 = TempRegister(); 1630 LOperand* temp2 = TempRegister();
1582 1631
1583 // Make sure that the temp and result_temp registers are 1632 // Make sure that the temp and result_temp registers are
1584 // different. 1633 // different.
1585 LUnallocated* result_temp = TempRegister(); 1634 LUnallocated* result_temp = TempRegister();
1586 LNumberTagD* result = new LNumberTagD(value, temp1, temp2); 1635 LNumberTagD* result = new LNumberTagD(value, temp1, temp2);
1587 Define(result, result_temp); 1636 Define(result, result_temp);
1588 return AssignPointerMap(result); 1637 return AssignPointerMap(result);
1589 } else { 1638 } else {
1590 ASSERT(to.IsInteger32()); 1639 ASSERT(to.IsInteger32());
1591 LOperand* value = UseRegister(instr->value()); 1640 LOperand* value = UseRegister(instr->value());
1592 LDoubleToI* res = new LDoubleToI(value, TempRegister()); 1641 LDoubleToI* res =
1642 new LDoubleToI(value,
1643 TempRegister(),
1644 instr->CanTruncateToInt32() ? TempRegister() : NULL);
1593 return AssignEnvironment(DefineAsRegister(res)); 1645 return AssignEnvironment(DefineAsRegister(res));
1594 } 1646 }
1595 } else if (from.IsInteger32()) { 1647 } else if (from.IsInteger32()) {
1596 if (to.IsTagged()) { 1648 if (to.IsTagged()) {
1597 HValue* val = instr->value(); 1649 HValue* val = instr->value();
1598 LOperand* value = UseRegister(val); 1650 LOperand* value = UseRegister(val);
1599 if (val->HasRange() && val->range()->IsInSmiRange()) { 1651 if (val->HasRange() && val->range()->IsInSmiRange()) {
1600 return DefineSameAsFirst(new LSmiTag(value)); 1652 return DefineSameAsFirst(new LSmiTag(value));
1601 } else { 1653 } else {
1602 LNumberTagI* result = new LNumberTagI(value); 1654 LNumberTagI* result = new LNumberTagI(value);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 } 1745 }
1694 1746
1695 1747
1696 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 1748 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1697 LOperand* context = UseRegisterAtStart(instr->value()); 1749 LOperand* context = UseRegisterAtStart(instr->value());
1698 return DefineAsRegister(new LLoadContextSlot(context)); 1750 return DefineAsRegister(new LLoadContextSlot(context));
1699 } 1751 }
1700 1752
1701 1753
1702 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { 1754 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1703 LOperand* context = UseTempRegister(instr->context()); 1755 LOperand* context;
1704 LOperand* value; 1756 LOperand* value;
1705 if (instr->NeedsWriteBarrier()) { 1757 if (instr->NeedsWriteBarrier()) {
1758 context = UseTempRegister(instr->context());
1706 value = UseTempRegister(instr->value()); 1759 value = UseTempRegister(instr->value());
1707 } else { 1760 } else {
1761 context = UseRegister(instr->context());
1708 value = UseRegister(instr->value()); 1762 value = UseRegister(instr->value());
1709 } 1763 }
1710 return new LStoreContextSlot(context, value); 1764 return new LStoreContextSlot(context, value);
1711 } 1765 }
1712 1766
1713 1767
1714 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1768 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1715 return DefineAsRegister( 1769 return DefineAsRegister(
1716 new LLoadNamedField(UseRegisterAtStart(instr->object()))); 1770 new LLoadNamedField(UseRegisterAtStart(instr->object())));
1717 } 1771 }
(...skipping 12 matching lines...) Expand all
1730 new LLoadFunctionPrototype(UseRegister(instr->function())))); 1784 new LLoadFunctionPrototype(UseRegister(instr->function()))));
1731 } 1785 }
1732 1786
1733 1787
1734 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { 1788 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1735 LOperand* input = UseRegisterAtStart(instr->value()); 1789 LOperand* input = UseRegisterAtStart(instr->value());
1736 return DefineAsRegister(new LLoadElements(input)); 1790 return DefineAsRegister(new LLoadElements(input));
1737 } 1791 }
1738 1792
1739 1793
1740 LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer( 1794 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
1741 HLoadPixelArrayExternalPointer* instr) { 1795 HLoadExternalArrayPointer* instr) {
1742 LOperand* input = UseRegisterAtStart(instr->value()); 1796 LOperand* input = UseRegisterAtStart(instr->value());
1743 return DefineAsRegister(new LLoadPixelArrayExternalPointer(input)); 1797 return DefineAsRegister(new LLoadExternalArrayPointer(input));
1744 } 1798 }
1745 1799
1746 1800
1747 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1801 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1748 HLoadKeyedFastElement* instr) { 1802 HLoadKeyedFastElement* instr) {
1749 ASSERT(instr->representation().IsTagged()); 1803 ASSERT(instr->representation().IsTagged());
1750 ASSERT(instr->key()->representation().IsInteger32()); 1804 ASSERT(instr->key()->representation().IsInteger32());
1751 LOperand* obj = UseRegisterAtStart(instr->object()); 1805 LOperand* obj = UseRegisterAtStart(instr->object());
1752 LOperand* key = UseRegisterAtStart(instr->key()); 1806 LOperand* key = UseRegisterAtStart(instr->key());
1753 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); 1807 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 ? UseTempRegister(instr->value()) 1844 ? UseTempRegister(instr->value())
1791 : UseRegisterAtStart(instr->value()); 1845 : UseRegisterAtStart(instr->value());
1792 LOperand* key = needs_write_barrier 1846 LOperand* key = needs_write_barrier
1793 ? UseTempRegister(instr->key()) 1847 ? UseTempRegister(instr->key())
1794 : UseRegisterOrConstantAtStart(instr->key()); 1848 : UseRegisterOrConstantAtStart(instr->key());
1795 1849
1796 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); 1850 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1797 } 1851 }
1798 1852
1799 1853
1854 LInstruction* LChunkBuilder::DoStorePixelArrayElement(
1855 HStorePixelArrayElement* instr) {
1856 ASSERT(instr->value()->representation().IsInteger32());
1857 ASSERT(instr->external_pointer()->representation().IsExternal());
1858 ASSERT(instr->key()->representation().IsInteger32());
1859
1860 LOperand* external_pointer = UseRegister(instr->external_pointer());
1861 LOperand* value = UseTempRegister(instr->value()); // changed by clamp.
1862 LOperand* key = UseRegister(instr->key());
1863
1864 return new LStorePixelArrayElement(external_pointer, key, value);
1865 }
1866
1867
1800 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 1868 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
1801 LOperand* obj = UseFixed(instr->object(), r2); 1869 LOperand* obj = UseFixed(instr->object(), r2);
1802 LOperand* key = UseFixed(instr->key(), r1); 1870 LOperand* key = UseFixed(instr->key(), r1);
1803 LOperand* val = UseFixed(instr->value(), r0); 1871 LOperand* val = UseFixed(instr->value(), r0);
1804 1872
1805 ASSERT(instr->object()->representation().IsTagged()); 1873 ASSERT(instr->object()->representation().IsTagged());
1806 ASSERT(instr->key()->representation().IsTagged()); 1874 ASSERT(instr->key()->representation().IsTagged());
1807 ASSERT(instr->value()->representation().IsTagged()); 1875 ASSERT(instr->value()->representation().IsTagged());
1808 1876
1809 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); 1877 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr);
(...skipping 25 matching lines...) Expand all
1835 1903
1836 1904
1837 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 1905 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
1838 LOperand* string = UseRegister(instr->string()); 1906 LOperand* string = UseRegister(instr->string());
1839 LOperand* index = UseRegisterOrConstant(instr->index()); 1907 LOperand* index = UseRegisterOrConstant(instr->index());
1840 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); 1908 LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
1841 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1909 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1842 } 1910 }
1843 1911
1844 1912
1913 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
1914 LOperand* char_code = UseRegister(instr->value());
1915 LStringCharFromCode* result = new LStringCharFromCode(char_code);
1916 return AssignPointerMap(DefineAsRegister(result));
1917 }
1918
1919
1845 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { 1920 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
1846 LOperand* string = UseRegisterAtStart(instr->value()); 1921 LOperand* string = UseRegisterAtStart(instr->value());
1847 return DefineAsRegister(new LStringLength(string)); 1922 return DefineAsRegister(new LStringLength(string));
1848 } 1923 }
1849 1924
1850 1925
1851 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 1926 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1852 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr); 1927 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr);
1853 } 1928 }
1854 1929
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 } 1970 }
1896 1971
1897 1972
1898 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 1973 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
1899 argument_count_ -= instr->argument_count(); 1974 argument_count_ -= instr->argument_count();
1900 return MarkAsCall(DefineFixed(new LCallStub, r0), instr); 1975 return MarkAsCall(DefineFixed(new LCallStub, r0), instr);
1901 } 1976 }
1902 1977
1903 1978
1904 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 1979 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
1905 // There are no real uses of the arguments object (we bail out in all other 1980 // There are no real uses of the arguments object.
1906 // cases). 1981 // arguments.length and element access are supported directly on
1982 // stack arguments, and any real arguments object use causes a bailout.
1983 // So this value is never used.
1907 return NULL; 1984 return NULL;
1908 } 1985 }
1909 1986
1910 1987
1911 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1988 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
1912 LOperand* arguments = UseRegister(instr->arguments()); 1989 LOperand* arguments = UseRegister(instr->arguments());
1913 LOperand* length = UseTempRegister(instr->length()); 1990 LOperand* length = UseTempRegister(instr->length());
1914 LOperand* index = UseRegister(instr->index()); 1991 LOperand* index = UseRegister(instr->index());
1915 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); 1992 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
1916 return AssignEnvironment(DefineAsRegister(result)); 1993 return AssignEnvironment(DefineAsRegister(result));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1985 2062
1986 2063
1987 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2064 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1988 HEnvironment* outer = current_block_->last_environment()->outer(); 2065 HEnvironment* outer = current_block_->last_environment()->outer();
1989 current_block_->UpdateEnvironment(outer); 2066 current_block_->UpdateEnvironment(outer);
1990 return NULL; 2067 return NULL;
1991 } 2068 }
1992 2069
1993 2070
1994 } } // namespace v8::internal 2071 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698