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

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

Issue 23156006: [v8-dev] ARM: Improve Lithium register constraints. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 LUnallocated::USED_AT_START)); 476 LUnallocated::USED_AT_START));
477 } 477 }
478 478
479 479
480 LOperand* LChunkBuilder::UseTempRegister(HValue* value) { 480 LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
481 return Use(value, new(zone()) LUnallocated(LUnallocated::WRITABLE_REGISTER)); 481 return Use(value, new(zone()) LUnallocated(LUnallocated::WRITABLE_REGISTER));
482 } 482 }
483 483
484 484
485 LOperand* LChunkBuilder::Use(HValue* value) { 485 LOperand* LChunkBuilder::Use(HValue* value) {
486 return Use(value, new(zone()) LUnallocated(LUnallocated::NONE)); 486 if (value->UseCount() == 1) {
danno 2013/08/20 14:53:20 What is the concrete motivation behind this change
vincent.belliard.fr 2013/08/22 12:35:48 The register allocation has been made for IA32. Th
487 return Use(value, new(zone()) LUnallocated(LUnallocated::NONE));
488 } else {
489 return UseRegister(value);
490 }
487 } 491 }
488 492
489 493
490 LOperand* LChunkBuilder::UseAtStart(HValue* value) { 494 LOperand* LChunkBuilder::UseAtStart(HValue* value) {
491 return Use(value, new(zone()) LUnallocated(LUnallocated::NONE, 495 if (value->UseCount() == 1) {
492 LUnallocated::USED_AT_START)); 496 return Use(value, new(zone()) LUnallocated(LUnallocated::NONE,
497 LUnallocated::USED_AT_START));
498 } else {
499 return UseRegisterAtStart(value);
500 }
493 } 501 }
494 502
495 503
496 LOperand* LChunkBuilder::UseOrConstant(HValue* value) { 504 LOperand* LChunkBuilder::UseOrConstant(HValue* value) {
497 return value->IsConstant() 505 return value->IsConstant()
498 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 506 ? chunk_->DefineConstantOperand(HConstant::cast(value))
499 : Use(value); 507 : Use(value);
500 } 508 }
501 509
502 510
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 return does_deopt ? AssignEnvironment(result) : result; 757 return does_deopt ? AssignEnvironment(result) : result;
750 } 758 }
751 759
752 760
753 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 761 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
754 HArithmeticBinaryOperation* instr) { 762 HArithmeticBinaryOperation* instr) {
755 ASSERT(instr->representation().IsDouble()); 763 ASSERT(instr->representation().IsDouble());
756 ASSERT(instr->left()->representation().IsDouble()); 764 ASSERT(instr->left()->representation().IsDouble());
757 ASSERT(instr->right()->representation().IsDouble()); 765 ASSERT(instr->right()->representation().IsDouble());
758 ASSERT(op != Token::MOD); 766 ASSERT(op != Token::MOD);
759 LOperand* left = UseRegisterAtStart(instr->left()); 767 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
760 LOperand* right = UseRegisterAtStart(instr->right()); 768 LOperand* right = UseAtStart(instr->BetterRightOperand());
761 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); 769 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
762 return DefineAsRegister(result); 770 return DefineAsRegister(result);
763 } 771 }
764 772
765 773
766 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, 774 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
767 HArithmeticBinaryOperation* instr) { 775 HArithmeticBinaryOperation* instr) {
768 ASSERT(op == Token::ADD || 776 ASSERT(op == Token::ADD ||
769 op == Token::DIV || 777 op == Token::DIV ||
770 op == Token::MOD || 778 op == Token::MOD ||
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 LApplyArguments* result = new(zone()) LApplyArguments(function, 1085 LApplyArguments* result = new(zone()) LApplyArguments(function,
1078 receiver, 1086 receiver,
1079 length, 1087 length,
1080 elements); 1088 elements);
1081 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1089 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1082 } 1090 }
1083 1091
1084 1092
1085 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1093 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1086 ++argument_count_; 1094 ++argument_count_;
1087 LOperand* argument = Use(instr->argument()); 1095 LOperand* argument = UseRegisterAtStart(instr->argument());
1088 return new(zone()) LPushArgument(argument); 1096 return new(zone()) LPushArgument(argument);
1089 } 1097 }
1090 1098
1091 1099
1092 LInstruction* LChunkBuilder::DoInnerAllocatedObject( 1100 LInstruction* LChunkBuilder::DoInnerAllocatedObject(
1093 HInnerAllocatedObject* inner_object) { 1101 HInnerAllocatedObject* inner_object) {
1094 LOperand* base_object = UseRegisterAtStart(inner_object->base_object()); 1102 LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
1095 LInnerAllocatedObject* result = 1103 LInnerAllocatedObject* result =
1096 new(zone()) LInnerAllocatedObject(base_object); 1104 new(zone()) LInnerAllocatedObject(base_object);
1097 return DefineAsRegister(result); 1105 return DefineAsRegister(result);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) { 1228 LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) {
1221 LOperand* input = UseFixedDouble(instr->value(), d2); 1229 LOperand* input = UseFixedDouble(instr->value(), d2);
1222 LMathTan* result = new(zone()) LMathTan(input); 1230 LMathTan* result = new(zone()) LMathTan(input);
1223 return MarkAsCall(DefineFixedDouble(result, d2), instr); 1231 return MarkAsCall(DefineFixedDouble(result, d2), instr);
1224 } 1232 }
1225 1233
1226 1234
1227 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { 1235 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1228 ASSERT(instr->representation().IsDouble()); 1236 ASSERT(instr->representation().IsDouble());
1229 ASSERT(instr->value()->representation().IsDouble()); 1237 ASSERT(instr->value()->representation().IsDouble());
1230 LOperand* input = UseTempRegister(instr->value()); 1238 LOperand* input = UseRegister(instr->value());
1231 LOperand* temp1 = TempRegister(); 1239 LOperand* temp1 = TempRegister();
1232 LOperand* temp2 = TempRegister(); 1240 LOperand* temp2 = TempRegister();
1233 LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll. 1241 LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll.
1234 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); 1242 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2);
1235 return DefineAsRegister(result); 1243 return DefineAsRegister(result);
1236 } 1244 }
1237 1245
1238 1246
1239 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { 1247 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1240 LOperand* input = UseRegister(instr->value()); 1248 LOperand* input = UseRegister(instr->value());
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1359 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1352 if (instr->representation().IsDouble()) { 1360 if (instr->representation().IsDouble()) {
1353 return DoArithmeticD(Token::DIV, instr); 1361 return DoArithmeticD(Token::DIV, instr);
1354 } else if (instr->representation().IsSmiOrInteger32()) { 1362 } else if (instr->representation().IsSmiOrInteger32()) {
1355 ASSERT(instr->left()->representation().Equals(instr->representation())); 1363 ASSERT(instr->left()->representation().Equals(instr->representation()));
1356 ASSERT(instr->right()->representation().Equals(instr->representation())); 1364 ASSERT(instr->right()->representation().Equals(instr->representation()));
1357 if (instr->HasPowerOf2Divisor()) { 1365 if (instr->HasPowerOf2Divisor()) {
1358 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); 1366 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1359 LOperand* value = UseRegisterAtStart(instr->left()); 1367 LOperand* value = UseRegisterAtStart(instr->left());
1360 LDivI* div = 1368 LDivI* div =
1361 new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); 1369 new(zone()) LDivI(value, UseConstant(instr->right()), NULL);
1362 return AssignEnvironment(DefineSameAsFirst(div)); 1370 return AssignEnvironment(DefineAsRegister(div));
1363 } 1371 }
1364 LOperand* dividend = UseRegister(instr->left()); 1372 LOperand* dividend = UseRegister(instr->left());
1365 LOperand* divisor = UseRegister(instr->right()); 1373 LOperand* divisor = UseRegister(instr->right());
1366 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); 1374 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
1367 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); 1375 LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
1368 return AssignEnvironment(DefineAsRegister(div)); 1376 return AssignEnvironment(DefineAsRegister(div));
1369 } else { 1377 } else {
1370 return DoArithmeticT(Token::DIV, instr); 1378 return DoArithmeticT(Token::DIV, instr);
1371 } 1379 }
1372 } 1380 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 divisor->block()->zone()); 1428 divisor->block()->zone());
1421 } 1429 }
1422 } 1430 }
1423 1431
1424 return NULL; 1432 return NULL;
1425 } 1433 }
1426 1434
1427 1435
1428 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { 1436 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1429 HValue* right = instr->right(); 1437 HValue* right = instr->right();
1430 LOperand* dividend = UseRegister(instr->left());
1431 LOperand* divisor = CpuFeatures::IsSupported(SUDIV)
1432 ? UseRegister(right)
1433 : UseOrConstant(right);
1434 LOperand* remainder = TempRegister();
1435 ASSERT(CpuFeatures::IsSupported(SUDIV) || 1438 ASSERT(CpuFeatures::IsSupported(SUDIV) ||
1436 (right->IsConstant() && 1439 (right->IsConstant() &&
1437 HConstant::cast(right)->HasInteger32Value() && 1440 HConstant::cast(right)->HasInteger32Value() &&
1438 HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()))); 1441 HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value())));
1442
1443 LOperand* dividend = UseRegister(instr->left());
1444 LOperand* divisor = CpuFeatures::IsSupported(SUDIV)
1445 ? UseRegister(right)
1446 : UseConstant(right);
1447 LOperand* remainder = TempRegister();
1439 return AssignEnvironment(DefineAsRegister( 1448 return AssignEnvironment(DefineAsRegister(
1440 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); 1449 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder)));
1441 } 1450 }
1442 1451
1443 1452
1444 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1453 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1445 HValue* left = instr->left(); 1454 HValue* left = instr->left();
1446 HValue* right = instr->right(); 1455 HValue* right = instr->right();
1447 if (instr->representation().IsSmiOrInteger32()) { 1456 if (instr->representation().IsSmiOrInteger32()) {
1448 ASSERT(instr->left()->representation().Equals(instr->representation())); 1457 ASSERT(instr->left()->representation().Equals(instr->representation()));
1449 ASSERT(instr->right()->representation().Equals(instr->representation())); 1458 ASSERT(instr->right()->representation().Equals(instr->representation()));
1450 if (instr->HasPowerOf2Divisor()) { 1459 if (instr->HasPowerOf2Divisor()) {
1451 ASSERT(!right->CanBeZero()); 1460 ASSERT(!right->CanBeZero());
1452 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), 1461 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
1453 UseOrConstant(right)); 1462 UseConstant(right));
1454 LInstruction* result = DefineAsRegister(mod); 1463 LInstruction* result = DefineAsRegister(mod);
1455 return (left->CanBeNegative() && 1464 return (left->CanBeNegative() &&
1456 instr->CheckFlag(HValue::kBailoutOnMinusZero)) 1465 instr->CheckFlag(HValue::kBailoutOnMinusZero))
1457 ? AssignEnvironment(result) 1466 ? AssignEnvironment(result)
1458 : result; 1467 : result;
1459 } else if (instr->fixed_right_arg().has_value) { 1468 } else if (instr->fixed_right_arg().has_value) {
1460 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), 1469 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
1461 UseRegisterAtStart(right)); 1470 UseRegisterAtStart(right));
1462 return AssignEnvironment(DefineAsRegister(mod)); 1471 return AssignEnvironment(DefineAsRegister(mod));
1463 } else if (CpuFeatures::IsSupported(SUDIV)) { 1472 } else if (CpuFeatures::IsSupported(SUDIV)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 UseFixedDouble(right, d2)); 1507 UseFixedDouble(right, d2));
1499 return MarkAsCall(DefineFixedDouble(mod, d1), instr); 1508 return MarkAsCall(DefineFixedDouble(mod, d1), instr);
1500 } 1509 }
1501 } 1510 }
1502 1511
1503 1512
1504 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1513 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1505 if (instr->representation().IsSmiOrInteger32()) { 1514 if (instr->representation().IsSmiOrInteger32()) {
1506 ASSERT(instr->left()->representation().Equals(instr->representation())); 1515 ASSERT(instr->left()->representation().Equals(instr->representation()));
1507 ASSERT(instr->right()->representation().Equals(instr->representation())); 1516 ASSERT(instr->right()->representation().Equals(instr->representation()));
1508 LOperand* left; 1517 HValue* left = instr->BetterLeftOperand();
1509 LOperand* right = UseOrConstant(instr->BetterRightOperand()); 1518 HValue* right = instr->BetterRightOperand();
1510 LOperand* temp = NULL; 1519 LOperand* left_op;
1511 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) && 1520 LOperand* right_op;
1512 (instr->CheckFlag(HValue::kCanOverflow) || 1521 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1513 !right->IsConstantOperand())) { 1522 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
1514 left = UseRegister(instr->BetterLeftOperand()); 1523
1515 temp = TempRegister(); 1524 if (can_overflow) {
1525 if (bailout_on_minus_zero) {
1526 // If the result is zero, the sign of left and right will be checked,
1527 // so they need to be kept alive.
1528 left_op = UseRegister(left);
1529 right_op = UseRegister(right);
1530 } else {
1531 left_op = UseRegisterAtStart(left);
1532 right_op = UseRegisterAtStart(right);
1533 }
1516 } else { 1534 } else {
1517 left = UseRegisterAtStart(instr->BetterLeftOperand()); 1535 if (bailout_on_minus_zero && !right->IsConstant()) {
1536 // If the result is zero, the sign of left and right will be checked,
1537 // so they need to be kept alive. Multiplication by a constant is
1538 // handled differently.
1539 left_op = UseRegister(left);
1540 right_op = UseRegister(right);
1541 } else {
1542 left_op = UseRegisterAtStart(left);
1543 right_op = UseRegisterOrConstantAtStart(right);
1544 }
1518 } 1545 }
1519 LMulI* mul = new(zone()) LMulI(left, right, temp); 1546 LMulI* mul = new(zone()) LMulI(left_op, right_op);
1520 if (instr->CheckFlag(HValue::kCanOverflow) || 1547 if (can_overflow || bailout_on_minus_zero) {
1521 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1522 AssignEnvironment(mul); 1548 AssignEnvironment(mul);
1523 } 1549 }
1524 return DefineAsRegister(mul); 1550 return DefineAsRegister(mul);
1525 1551
1526 } else if (instr->representation().IsDouble()) { 1552 } else if (instr->representation().IsDouble()) {
1527 if (instr->UseCount() == 1 && (instr->uses().value()->IsAdd() || 1553 if (instr->UseCount() == 1 && (instr->uses().value()->IsAdd() ||
1528 instr->uses().value()->IsSub())) { 1554 instr->uses().value()->IsSub())) {
1529 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value()); 1555 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());
1530 1556
1531 if (use->IsAdd() && instr == use->left()) { 1557 if (use->IsAdd() && instr == use->left()) {
(...skipping 18 matching lines...) Expand all
1550 return DoArithmeticT(Token::MUL, instr); 1576 return DoArithmeticT(Token::MUL, instr);
1551 } 1577 }
1552 } 1578 }
1553 1579
1554 1580
1555 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1581 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1556 if (instr->representation().IsSmiOrInteger32()) { 1582 if (instr->representation().IsSmiOrInteger32()) {
1557 ASSERT(instr->left()->representation().Equals(instr->representation())); 1583 ASSERT(instr->left()->representation().Equals(instr->representation()));
1558 ASSERT(instr->right()->representation().Equals(instr->representation())); 1584 ASSERT(instr->right()->representation().Equals(instr->representation()));
1559 1585
1560 if (instr->left()->IsConstant()) { 1586 if (instr->left()->IsConstant() ||
1561 // If lhs is constant, do reverse subtraction instead. 1587 ((instr->left()->UseCount() == 1) &&
1588 (instr->right()->UseCount() > 1))) {
1589 // If lhs is better right, do reverse subtraction instead.
1562 return DoRSub(instr); 1590 return DoRSub(instr);
1563 } 1591 }
1564 1592
1565 LOperand* left = UseRegisterAtStart(instr->left()); 1593 LOperand* left = UseRegisterAtStart(instr->left());
1566 LOperand* right = UseOrConstantAtStart(instr->right()); 1594 LOperand* right = UseOrConstantAtStart(instr->right());
1567 LSubI* sub = new(zone()) LSubI(left, right); 1595 LSubI* sub = new(zone()) LSubI(left, right);
1568 LInstruction* result = DefineAsRegister(sub); 1596 LInstruction* result = DefineAsRegister(sub);
1569 if (instr->CheckFlag(HValue::kCanOverflow)) { 1597 if (instr->CheckFlag(HValue::kCanOverflow)) {
1570 result = AssignEnvironment(result); 1598 result = AssignEnvironment(result);
1571 } 1599 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 } 1678 }
1651 1679
1652 1680
1653 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { 1681 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1654 LOperand* left = NULL; 1682 LOperand* left = NULL;
1655 LOperand* right = NULL; 1683 LOperand* right = NULL;
1656 if (instr->representation().IsSmiOrInteger32()) { 1684 if (instr->representation().IsSmiOrInteger32()) {
1657 ASSERT(instr->left()->representation().Equals(instr->representation())); 1685 ASSERT(instr->left()->representation().Equals(instr->representation()));
1658 ASSERT(instr->right()->representation().Equals(instr->representation())); 1686 ASSERT(instr->right()->representation().Equals(instr->representation()));
1659 left = UseRegisterAtStart(instr->BetterLeftOperand()); 1687 left = UseRegisterAtStart(instr->BetterLeftOperand());
1660 right = UseOrConstantAtStart(instr->BetterRightOperand()); 1688 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand());
1661 } else { 1689 } else {
1662 ASSERT(instr->representation().IsDouble()); 1690 ASSERT(instr->representation().IsDouble());
1663 ASSERT(instr->left()->representation().IsDouble()); 1691 ASSERT(instr->left()->representation().IsDouble());
1664 ASSERT(instr->right()->representation().IsDouble()); 1692 ASSERT(instr->right()->representation().IsDouble());
1665 left = UseRegisterAtStart(instr->left()); 1693 left = UseRegister(instr->BetterLeftOperand());
1666 right = UseRegisterAtStart(instr->right()); 1694 right = Use(instr->BetterRightOperand());
1667 } 1695 }
1668 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); 1696 return DefineAsRegister(new(zone()) LMathMinMax(left, right));
1669 } 1697 }
1670 1698
1671 1699
1672 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1700 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1673 ASSERT(instr->representation().IsDouble()); 1701 ASSERT(instr->representation().IsDouble());
1674 // We call a C function for double power. It can't trigger a GC. 1702 // We call a C function for double power. It can't trigger a GC.
1675 // We need to use fixed result register for the call. 1703 // We need to use fixed result register for the call.
1676 Representation exponent_type = instr->right()->representation(); 1704 Representation exponent_type = instr->right()->representation();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { 1779 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1752 ASSERT(instr->value()->representation().IsTagged()); 1780 ASSERT(instr->value()->representation().IsTagged());
1753 LOperand* value = UseRegisterAtStart(instr->value()); 1781 LOperand* value = UseRegisterAtStart(instr->value());
1754 LOperand* temp = TempRegister(); 1782 LOperand* temp = TempRegister();
1755 return new(zone()) LIsStringAndBranch(value, temp); 1783 return new(zone()) LIsStringAndBranch(value, temp);
1756 } 1784 }
1757 1785
1758 1786
1759 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { 1787 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1760 ASSERT(instr->value()->representation().IsTagged()); 1788 ASSERT(instr->value()->representation().IsTagged());
1761 return new(zone()) LIsSmiAndBranch(Use(instr->value())); 1789 return new(zone()) LIsSmiAndBranch(UseRegisterAtStart(instr->value()));
1762 } 1790 }
1763 1791
1764 1792
1765 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( 1793 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1766 HIsUndetectableAndBranch* instr) { 1794 HIsUndetectableAndBranch* instr) {
1767 ASSERT(instr->value()->representation().IsTagged()); 1795 ASSERT(instr->value()->representation().IsTagged());
1768 LOperand* value = UseRegisterAtStart(instr->value()); 1796 LOperand* value = UseRegisterAtStart(instr->value());
1769 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); 1797 return new(zone()) LIsUndetectableAndBranch(value, TempRegister());
1770 } 1798 }
1771 1799
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { 1865 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1838 LOperand* object = UseFixed(instr->value(), r0); 1866 LOperand* object = UseFixed(instr->value(), r0);
1839 LDateField* result = 1867 LDateField* result =
1840 new(zone()) LDateField(object, FixedTemp(r1), instr->index()); 1868 new(zone()) LDateField(object, FixedTemp(r1), instr->index());
1841 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1869 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1842 } 1870 }
1843 1871
1844 1872
1845 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { 1873 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1846 LOperand* string = UseRegister(instr->string()); 1874 LOperand* string = UseRegister(instr->string());
1847 LOperand* index = UseRegister(instr->index()); 1875 LOperand* index = UseRegisterOrConstant(instr->index());
1848 LOperand* value = UseTempRegister(instr->value()); 1876 LOperand* value = UseRegister(instr->value());
1849 LSeqStringSetChar* result = 1877 LSeqStringSetChar* result =
1850 new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); 1878 new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value);
1851 return DefineAsRegister(result); 1879 return result;
1852 } 1880 }
1853 1881
1854 1882
1855 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1883 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1856 LOperand* value = UseRegisterOrConstantAtStart(instr->index()); 1884 LOperand* value = UseRegisterOrConstantAtStart(instr->index());
1857 LOperand* length = UseRegister(instr->length()); 1885 LOperand* length = UseRegister(instr->length());
1858 return AssignEnvironment(new(zone()) LBoundsCheck(value, length)); 1886 return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
1859 } 1887 }
1860 1888
1861 1889
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1984 return result; 2012 return result;
1985 } 2013 }
1986 return AssignEnvironment(result); 2014 return AssignEnvironment(result);
1987 } else { 2015 } else {
1988 ASSERT(to.IsDouble()); 2016 ASSERT(to.IsDouble());
1989 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 2017 if (instr->value()->CheckFlag(HInstruction::kUint32)) {
1990 return DefineAsRegister( 2018 return DefineAsRegister(
1991 new(zone()) LUint32ToDouble(UseRegister(instr->value()))); 2019 new(zone()) LUint32ToDouble(UseRegister(instr->value())));
1992 } else { 2020 } else {
1993 return DefineAsRegister( 2021 return DefineAsRegister(
1994 new(zone()) LInteger32ToDouble(Use(instr->value()))); 2022 new(zone()) LInteger32ToDouble(UseRegister(instr->value())));
1995 } 2023 }
1996 } 2024 }
1997 } 2025 }
1998 UNREACHABLE(); 2026 UNREACHABLE();
1999 return NULL; 2027 return NULL;
2000 } 2028 }
2001 2029
2002 2030
2003 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 2031 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
2004 LOperand* value = UseRegisterAtStart(instr->value()); 2032 LOperand* value = UseRegisterAtStart(instr->value());
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2174 } 2202 }
2175 2203
2176 2204
2177 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { 2205 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2178 ASSERT(instr->key()->representation().IsSmiOrInteger32()); 2206 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2179 ElementsKind elements_kind = instr->elements_kind(); 2207 ElementsKind elements_kind = instr->elements_kind();
2180 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2208 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2181 LLoadKeyed* result = NULL; 2209 LLoadKeyed* result = NULL;
2182 2210
2183 if (!instr->is_external()) { 2211 if (!instr->is_external()) {
2184 LOperand* obj = NULL; 2212 ASSERT(instr->representation().IsSmiOrTagged() ||
2185 if (instr->representation().IsDouble()) { 2213 instr->representation().IsDouble());
2186 obj = UseTempRegister(instr->elements()); 2214 LOperand* obj = UseRegisterAtStart(instr->elements());
2187 } else {
2188 ASSERT(instr->representation().IsSmiOrTagged());
2189 obj = UseRegisterAtStart(instr->elements());
2190 }
2191 result = new(zone()) LLoadKeyed(obj, key); 2215 result = new(zone()) LLoadKeyed(obj, key);
2192 } else { 2216 } else {
2193 ASSERT( 2217 ASSERT(
2194 (instr->representation().IsInteger32() && 2218 (instr->representation().IsInteger32() &&
2195 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && 2219 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
2196 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || 2220 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
2197 (instr->representation().IsDouble() && 2221 (instr->representation().IsDouble() &&
2198 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || 2222 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
2199 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); 2223 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
2200 LOperand* external_pointer = UseRegister(instr->elements()); 2224 LOperand* external_pointer = UseRegister(instr->elements());
(...skipping 13 matching lines...) Expand all
2214 LOperand* object = UseFixed(instr->object(), r1); 2238 LOperand* object = UseFixed(instr->object(), r1);
2215 LOperand* key = UseFixed(instr->key(), r0); 2239 LOperand* key = UseFixed(instr->key(), r0);
2216 2240
2217 LInstruction* result = 2241 LInstruction* result =
2218 DefineFixed(new(zone()) LLoadKeyedGeneric(object, key), r0); 2242 DefineFixed(new(zone()) LLoadKeyedGeneric(object, key), r0);
2219 return MarkAsCall(result, instr); 2243 return MarkAsCall(result, instr);
2220 } 2244 }
2221 2245
2222 2246
2223 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { 2247 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2248 #ifdef DEBUG
2224 ElementsKind elements_kind = instr->elements_kind(); 2249 ElementsKind elements_kind = instr->elements_kind();
2250 #endif
2225 2251
2226 if (!instr->is_external()) { 2252 if (!instr->is_external()) {
2227 ASSERT(instr->elements()->representation().IsTagged()); 2253 ASSERT(instr->elements()->representation().IsTagged());
2228 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2254 bool needs_write_barrier = instr->NeedsWriteBarrier();
2229 LOperand* object = NULL; 2255 LOperand* object = NULL;
2230 LOperand* key = NULL; 2256 LOperand* key = NULL;
2231 LOperand* val = NULL; 2257 LOperand* val = NULL;
2232 2258
2233 if (instr->value()->representation().IsDouble()) { 2259 if (instr->value()->representation().IsDouble()) {
2234 object = UseRegisterAtStart(instr->elements()); 2260 object = UseRegisterAtStart(instr->elements());
2235 val = UseTempRegister(instr->value()); 2261 val = UseRegisterAtStart(instr->value());
2236 key = UseRegisterOrConstantAtStart(instr->key()); 2262 key = UseRegisterOrConstantAtStart(instr->key());
2237 } else { 2263 } else {
2238 ASSERT(instr->value()->representation().IsSmiOrTagged()); 2264 ASSERT(instr->value()->representation().IsSmiOrTagged());
2239 object = UseTempRegister(instr->elements()); 2265 if (needs_write_barrier) {
2240 val = needs_write_barrier ? UseTempRegister(instr->value()) 2266 object = UseTempRegister(instr->elements());
2241 : UseRegisterAtStart(instr->value()); 2267 val = UseTempRegister(instr->value());
2242 key = needs_write_barrier ? UseTempRegister(instr->key()) 2268 key = UseTempRegister(instr->key());
2243 : UseRegisterOrConstantAtStart(instr->key()); 2269 } else {
2270 object = UseRegisterAtStart(instr->elements());
2271 val = UseRegisterAtStart(instr->value());
2272 key = UseRegisterOrConstantAtStart(instr->key());
2273 }
2244 } 2274 }
2245 2275
2246 return new(zone()) LStoreKeyed(object, key, val); 2276 return new(zone()) LStoreKeyed(object, key, val);
2247 } 2277 }
2248 2278
2249 ASSERT( 2279 ASSERT(
2250 (instr->value()->representation().IsInteger32() && 2280 (instr->value()->representation().IsInteger32() &&
2251 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && 2281 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
2252 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || 2282 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
2253 (instr->value()->representation().IsDouble() && 2283 (instr->value()->representation().IsDouble() &&
2254 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || 2284 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
2255 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); 2285 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
2256 ASSERT(instr->elements()->representation().IsExternal()); 2286 ASSERT(instr->elements()->representation().IsExternal());
2257 bool val_is_temp_register = 2287 LOperand* val = UseRegister(instr->value());
2258 elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
2259 elements_kind == EXTERNAL_FLOAT_ELEMENTS;
2260 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
2261 : UseRegister(instr->value());
2262 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2288 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2263 LOperand* external_pointer = UseRegister(instr->elements()); 2289 LOperand* external_pointer = UseRegister(instr->elements());
2264 return new(zone()) LStoreKeyed(external_pointer, key, val); 2290 return new(zone()) LStoreKeyed(external_pointer, key, val);
2265 } 2291 }
2266 2292
2267 2293
2268 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 2294 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2269 LOperand* obj = UseFixed(instr->object(), r2); 2295 LOperand* obj = UseFixed(instr->object(), r2);
2270 LOperand* key = UseFixed(instr->key(), r1); 2296 LOperand* key = UseFixed(instr->key(), r1);
2271 LOperand* val = UseFixed(instr->value(), r0); 2297 LOperand* val = UseFixed(instr->value(), r0);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 2399
2374 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2400 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2375 LOperand* char_code = UseRegister(instr->value()); 2401 LOperand* char_code = UseRegister(instr->value());
2376 LStringCharFromCode* result = new(zone()) LStringCharFromCode(char_code); 2402 LStringCharFromCode* result = new(zone()) LStringCharFromCode(char_code);
2377 return AssignPointerMap(DefineAsRegister(result)); 2403 return AssignPointerMap(DefineAsRegister(result));
2378 } 2404 }
2379 2405
2380 2406
2381 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { 2407 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2382 info()->MarkAsDeferredCalling(); 2408 info()->MarkAsDeferredCalling();
2383 LOperand* size = instr->size()->IsConstant() 2409 LOperand* size = UseRegisterOrConstant(instr->size());
2384 ? UseConstant(instr->size())
2385 : UseTempRegister(instr->size());
2386 LOperand* temp1 = TempRegister(); 2410 LOperand* temp1 = TempRegister();
2387 LOperand* temp2 = TempRegister(); 2411 LOperand* temp2 = TempRegister();
2388 LAllocate* result = new(zone()) LAllocate(size, temp1, temp2); 2412 LAllocate* result = new(zone()) LAllocate(size, temp1, temp2);
2389 return AssignPointerMap(DefineAsRegister(result)); 2413 return AssignPointerMap(DefineAsRegister(result));
2390 } 2414 }
2391 2415
2392 2416
2393 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 2417 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2394 return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, r0), instr); 2418 return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, r0), instr);
2395 } 2419 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 2475
2452 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { 2476 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2453 // There are no real uses of a captured object. 2477 // There are no real uses of a captured object.
2454 return NULL; 2478 return NULL;
2455 } 2479 }
2456 2480
2457 2481
2458 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 2482 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2459 info()->MarkAsRequiresFrame(); 2483 info()->MarkAsRequiresFrame();
2460 LOperand* args = UseRegister(instr->arguments()); 2484 LOperand* args = UseRegister(instr->arguments());
2461 LOperand* length; 2485 LOperand* length = UseRegisterOrConstantAtStart(instr->length());
2462 LOperand* index; 2486 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
2463 if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
2464 length = UseRegisterOrConstant(instr->length());
2465 index = UseOrConstant(instr->index());
2466 } else {
2467 length = UseTempRegister(instr->length());
2468 index = UseRegisterAtStart(instr->index());
2469 }
2470 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); 2487 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
2471 } 2488 }
2472 2489
2473 2490
2474 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { 2491 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2475 LOperand* object = UseFixed(instr->value(), r0); 2492 LOperand* object = UseFixed(instr->value(), r0);
2476 LToFastProperties* result = new(zone()) LToFastProperties(object); 2493 LToFastProperties* result = new(zone()) LToFastProperties(object);
2477 return MarkAsCall(DefineFixed(result, r0), instr); 2494 return MarkAsCall(DefineFixed(result, r0), instr);
2478 } 2495 }
2479 2496
2480 2497
2481 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 2498 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2482 LTypeof* result = new(zone()) LTypeof(UseFixed(instr->value(), r0)); 2499 LTypeof* result = new(zone()) LTypeof(UseFixed(instr->value(), r0));
2483 return MarkAsCall(DefineFixed(result, r0), instr); 2500 return MarkAsCall(DefineFixed(result, r0), instr);
2484 } 2501 }
2485 2502
2486 2503
2487 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { 2504 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2488 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); 2505 return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value()));
2489 } 2506 }
2490 2507
2491 2508
2492 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( 2509 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2493 HIsConstructCallAndBranch* instr) { 2510 HIsConstructCallAndBranch* instr) {
2494 return new(zone()) LIsConstructCallAndBranch(TempRegister()); 2511 return new(zone()) LIsConstructCallAndBranch(TempRegister());
2495 } 2512 }
2496 2513
2497 2514
2498 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2515 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2599 2616
2600 2617
2601 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2618 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2602 LOperand* object = UseRegister(instr->object()); 2619 LOperand* object = UseRegister(instr->object());
2603 LOperand* index = UseRegister(instr->index()); 2620 LOperand* index = UseRegister(instr->index());
2604 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); 2621 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
2605 } 2622 }
2606 2623
2607 2624
2608 } } // namespace v8::internal 2625 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698