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

Side by Side Diff: src/x87/lithium-codegen-x87.cc

Issue 892843007: Revert of Externalize deoptimization reasons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « src/x64/lithium-codegen-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X87 7 #if V8_TARGET_ARCH_X87
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1406 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1407 Label dividend_is_not_negative, done; 1407 Label dividend_is_not_negative, done;
1408 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 1408 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
1409 __ test(dividend, dividend); 1409 __ test(dividend, dividend);
1410 __ j(not_sign, &dividend_is_not_negative, Label::kNear); 1410 __ j(not_sign, &dividend_is_not_negative, Label::kNear);
1411 // Note that this is correct even for kMinInt operands. 1411 // Note that this is correct even for kMinInt operands.
1412 __ neg(dividend); 1412 __ neg(dividend);
1413 __ and_(dividend, mask); 1413 __ and_(dividend, mask);
1414 __ neg(dividend); 1414 __ neg(dividend);
1415 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1415 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1416 DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); 1416 DeoptimizeIf(zero, instr, "minus zero");
1417 } 1417 }
1418 __ jmp(&done, Label::kNear); 1418 __ jmp(&done, Label::kNear);
1419 } 1419 }
1420 1420
1421 __ bind(&dividend_is_not_negative); 1421 __ bind(&dividend_is_not_negative);
1422 __ and_(dividend, mask); 1422 __ and_(dividend, mask);
1423 __ bind(&done); 1423 __ bind(&done);
1424 } 1424 }
1425 1425
1426 1426
1427 void LCodeGen::DoModByConstI(LModByConstI* instr) { 1427 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1428 Register dividend = ToRegister(instr->dividend()); 1428 Register dividend = ToRegister(instr->dividend());
1429 int32_t divisor = instr->divisor(); 1429 int32_t divisor = instr->divisor();
1430 DCHECK(ToRegister(instr->result()).is(eax)); 1430 DCHECK(ToRegister(instr->result()).is(eax));
1431 1431
1432 if (divisor == 0) { 1432 if (divisor == 0) {
1433 DeoptimizeIf(no_condition, instr, Deoptimizer::kDivisionByZero); 1433 DeoptimizeIf(no_condition, instr, "division by zero");
1434 return; 1434 return;
1435 } 1435 }
1436 1436
1437 __ TruncatingDiv(dividend, Abs(divisor)); 1437 __ TruncatingDiv(dividend, Abs(divisor));
1438 __ imul(edx, edx, Abs(divisor)); 1438 __ imul(edx, edx, Abs(divisor));
1439 __ mov(eax, dividend); 1439 __ mov(eax, dividend);
1440 __ sub(eax, edx); 1440 __ sub(eax, edx);
1441 1441
1442 // Check for negative zero. 1442 // Check for negative zero.
1443 HMod* hmod = instr->hydrogen(); 1443 HMod* hmod = instr->hydrogen();
1444 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1444 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1445 Label remainder_not_zero; 1445 Label remainder_not_zero;
1446 __ j(not_zero, &remainder_not_zero, Label::kNear); 1446 __ j(not_zero, &remainder_not_zero, Label::kNear);
1447 __ cmp(dividend, Immediate(0)); 1447 __ cmp(dividend, Immediate(0));
1448 DeoptimizeIf(less, instr, Deoptimizer::kMinusZero); 1448 DeoptimizeIf(less, instr, "minus zero");
1449 __ bind(&remainder_not_zero); 1449 __ bind(&remainder_not_zero);
1450 } 1450 }
1451 } 1451 }
1452 1452
1453 1453
1454 void LCodeGen::DoModI(LModI* instr) { 1454 void LCodeGen::DoModI(LModI* instr) {
1455 HMod* hmod = instr->hydrogen(); 1455 HMod* hmod = instr->hydrogen();
1456 1456
1457 Register left_reg = ToRegister(instr->left()); 1457 Register left_reg = ToRegister(instr->left());
1458 DCHECK(left_reg.is(eax)); 1458 DCHECK(left_reg.is(eax));
1459 Register right_reg = ToRegister(instr->right()); 1459 Register right_reg = ToRegister(instr->right());
1460 DCHECK(!right_reg.is(eax)); 1460 DCHECK(!right_reg.is(eax));
1461 DCHECK(!right_reg.is(edx)); 1461 DCHECK(!right_reg.is(edx));
1462 Register result_reg = ToRegister(instr->result()); 1462 Register result_reg = ToRegister(instr->result());
1463 DCHECK(result_reg.is(edx)); 1463 DCHECK(result_reg.is(edx));
1464 1464
1465 Label done; 1465 Label done;
1466 // Check for x % 0, idiv would signal a divide error. We have to 1466 // Check for x % 0, idiv would signal a divide error. We have to
1467 // deopt in this case because we can't return a NaN. 1467 // deopt in this case because we can't return a NaN.
1468 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 1468 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
1469 __ test(right_reg, Operand(right_reg)); 1469 __ test(right_reg, Operand(right_reg));
1470 DeoptimizeIf(zero, instr, Deoptimizer::kDivisionByZero); 1470 DeoptimizeIf(zero, instr, "division by zero");
1471 } 1471 }
1472 1472
1473 // Check for kMinInt % -1, idiv would signal a divide error. We 1473 // Check for kMinInt % -1, idiv would signal a divide error. We
1474 // have to deopt if we care about -0, because we can't return that. 1474 // have to deopt if we care about -0, because we can't return that.
1475 if (hmod->CheckFlag(HValue::kCanOverflow)) { 1475 if (hmod->CheckFlag(HValue::kCanOverflow)) {
1476 Label no_overflow_possible; 1476 Label no_overflow_possible;
1477 __ cmp(left_reg, kMinInt); 1477 __ cmp(left_reg, kMinInt);
1478 __ j(not_equal, &no_overflow_possible, Label::kNear); 1478 __ j(not_equal, &no_overflow_possible, Label::kNear);
1479 __ cmp(right_reg, -1); 1479 __ cmp(right_reg, -1);
1480 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1480 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1481 DeoptimizeIf(equal, instr, Deoptimizer::kMinusZero); 1481 DeoptimizeIf(equal, instr, "minus zero");
1482 } else { 1482 } else {
1483 __ j(not_equal, &no_overflow_possible, Label::kNear); 1483 __ j(not_equal, &no_overflow_possible, Label::kNear);
1484 __ Move(result_reg, Immediate(0)); 1484 __ Move(result_reg, Immediate(0));
1485 __ jmp(&done, Label::kNear); 1485 __ jmp(&done, Label::kNear);
1486 } 1486 }
1487 __ bind(&no_overflow_possible); 1487 __ bind(&no_overflow_possible);
1488 } 1488 }
1489 1489
1490 // Sign extend dividend in eax into edx:eax. 1490 // Sign extend dividend in eax into edx:eax.
1491 __ cdq(); 1491 __ cdq();
1492 1492
1493 // If we care about -0, test if the dividend is <0 and the result is 0. 1493 // If we care about -0, test if the dividend is <0 and the result is 0.
1494 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1494 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1495 Label positive_left; 1495 Label positive_left;
1496 __ test(left_reg, Operand(left_reg)); 1496 __ test(left_reg, Operand(left_reg));
1497 __ j(not_sign, &positive_left, Label::kNear); 1497 __ j(not_sign, &positive_left, Label::kNear);
1498 __ idiv(right_reg); 1498 __ idiv(right_reg);
1499 __ test(result_reg, Operand(result_reg)); 1499 __ test(result_reg, Operand(result_reg));
1500 DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); 1500 DeoptimizeIf(zero, instr, "minus zero");
1501 __ jmp(&done, Label::kNear); 1501 __ jmp(&done, Label::kNear);
1502 __ bind(&positive_left); 1502 __ bind(&positive_left);
1503 } 1503 }
1504 __ idiv(right_reg); 1504 __ idiv(right_reg);
1505 __ bind(&done); 1505 __ bind(&done);
1506 } 1506 }
1507 1507
1508 1508
1509 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1509 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1510 Register dividend = ToRegister(instr->dividend()); 1510 Register dividend = ToRegister(instr->dividend());
1511 int32_t divisor = instr->divisor(); 1511 int32_t divisor = instr->divisor();
1512 Register result = ToRegister(instr->result()); 1512 Register result = ToRegister(instr->result());
1513 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 1513 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
1514 DCHECK(!result.is(dividend)); 1514 DCHECK(!result.is(dividend));
1515 1515
1516 // Check for (0 / -x) that will produce negative zero. 1516 // Check for (0 / -x) that will produce negative zero.
1517 HDiv* hdiv = instr->hydrogen(); 1517 HDiv* hdiv = instr->hydrogen();
1518 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1518 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1519 __ test(dividend, dividend); 1519 __ test(dividend, dividend);
1520 DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); 1520 DeoptimizeIf(zero, instr, "minus zero");
1521 } 1521 }
1522 // Check for (kMinInt / -1). 1522 // Check for (kMinInt / -1).
1523 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1523 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
1524 __ cmp(dividend, kMinInt); 1524 __ cmp(dividend, kMinInt);
1525 DeoptimizeIf(zero, instr, Deoptimizer::kOverflow); 1525 DeoptimizeIf(zero, instr, "overflow");
1526 } 1526 }
1527 // Deoptimize if remainder will not be 0. 1527 // Deoptimize if remainder will not be 0.
1528 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1528 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1529 divisor != 1 && divisor != -1) { 1529 divisor != 1 && divisor != -1) {
1530 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1530 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1531 __ test(dividend, Immediate(mask)); 1531 __ test(dividend, Immediate(mask));
1532 DeoptimizeIf(not_zero, instr, Deoptimizer::kLostPrecision); 1532 DeoptimizeIf(not_zero, instr, "lost precision");
1533 } 1533 }
1534 __ Move(result, dividend); 1534 __ Move(result, dividend);
1535 int32_t shift = WhichPowerOf2Abs(divisor); 1535 int32_t shift = WhichPowerOf2Abs(divisor);
1536 if (shift > 0) { 1536 if (shift > 0) {
1537 // The arithmetic shift is always OK, the 'if' is an optimization only. 1537 // The arithmetic shift is always OK, the 'if' is an optimization only.
1538 if (shift > 1) __ sar(result, 31); 1538 if (shift > 1) __ sar(result, 31);
1539 __ shr(result, 32 - shift); 1539 __ shr(result, 32 - shift);
1540 __ add(result, dividend); 1540 __ add(result, dividend);
1541 __ sar(result, shift); 1541 __ sar(result, shift);
1542 } 1542 }
1543 if (divisor < 0) __ neg(result); 1543 if (divisor < 0) __ neg(result);
1544 } 1544 }
1545 1545
1546 1546
1547 void LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1547 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1548 Register dividend = ToRegister(instr->dividend()); 1548 Register dividend = ToRegister(instr->dividend());
1549 int32_t divisor = instr->divisor(); 1549 int32_t divisor = instr->divisor();
1550 DCHECK(ToRegister(instr->result()).is(edx)); 1550 DCHECK(ToRegister(instr->result()).is(edx));
1551 1551
1552 if (divisor == 0) { 1552 if (divisor == 0) {
1553 DeoptimizeIf(no_condition, instr, Deoptimizer::kDivisionByZero); 1553 DeoptimizeIf(no_condition, instr, "division by zero");
1554 return; 1554 return;
1555 } 1555 }
1556 1556
1557 // Check for (0 / -x) that will produce negative zero. 1557 // Check for (0 / -x) that will produce negative zero.
1558 HDiv* hdiv = instr->hydrogen(); 1558 HDiv* hdiv = instr->hydrogen();
1559 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1559 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1560 __ test(dividend, dividend); 1560 __ test(dividend, dividend);
1561 DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); 1561 DeoptimizeIf(zero, instr, "minus zero");
1562 } 1562 }
1563 1563
1564 __ TruncatingDiv(dividend, Abs(divisor)); 1564 __ TruncatingDiv(dividend, Abs(divisor));
1565 if (divisor < 0) __ neg(edx); 1565 if (divisor < 0) __ neg(edx);
1566 1566
1567 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1567 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1568 __ mov(eax, edx); 1568 __ mov(eax, edx);
1569 __ imul(eax, eax, divisor); 1569 __ imul(eax, eax, divisor);
1570 __ sub(eax, dividend); 1570 __ sub(eax, dividend);
1571 DeoptimizeIf(not_equal, instr, Deoptimizer::kLostPrecision); 1571 DeoptimizeIf(not_equal, instr, "lost precision");
1572 } 1572 }
1573 } 1573 }
1574 1574
1575 1575
1576 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1576 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
1577 void LCodeGen::DoDivI(LDivI* instr) { 1577 void LCodeGen::DoDivI(LDivI* instr) {
1578 HBinaryOperation* hdiv = instr->hydrogen(); 1578 HBinaryOperation* hdiv = instr->hydrogen();
1579 Register dividend = ToRegister(instr->dividend()); 1579 Register dividend = ToRegister(instr->dividend());
1580 Register divisor = ToRegister(instr->divisor()); 1580 Register divisor = ToRegister(instr->divisor());
1581 Register remainder = ToRegister(instr->temp()); 1581 Register remainder = ToRegister(instr->temp());
1582 DCHECK(dividend.is(eax)); 1582 DCHECK(dividend.is(eax));
1583 DCHECK(remainder.is(edx)); 1583 DCHECK(remainder.is(edx));
1584 DCHECK(ToRegister(instr->result()).is(eax)); 1584 DCHECK(ToRegister(instr->result()).is(eax));
1585 DCHECK(!divisor.is(eax)); 1585 DCHECK(!divisor.is(eax));
1586 DCHECK(!divisor.is(edx)); 1586 DCHECK(!divisor.is(edx));
1587 1587
1588 // Check for x / 0. 1588 // Check for x / 0.
1589 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1589 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1590 __ test(divisor, divisor); 1590 __ test(divisor, divisor);
1591 DeoptimizeIf(zero, instr, Deoptimizer::kDivisionByZero); 1591 DeoptimizeIf(zero, instr, "division by zero");
1592 } 1592 }
1593 1593
1594 // Check for (0 / -x) that will produce negative zero. 1594 // Check for (0 / -x) that will produce negative zero.
1595 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1595 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1596 Label dividend_not_zero; 1596 Label dividend_not_zero;
1597 __ test(dividend, dividend); 1597 __ test(dividend, dividend);
1598 __ j(not_zero, &dividend_not_zero, Label::kNear); 1598 __ j(not_zero, &dividend_not_zero, Label::kNear);
1599 __ test(divisor, divisor); 1599 __ test(divisor, divisor);
1600 DeoptimizeIf(sign, instr, Deoptimizer::kMinusZero); 1600 DeoptimizeIf(sign, instr, "minus zero");
1601 __ bind(&dividend_not_zero); 1601 __ bind(&dividend_not_zero);
1602 } 1602 }
1603 1603
1604 // Check for (kMinInt / -1). 1604 // Check for (kMinInt / -1).
1605 if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1605 if (hdiv->CheckFlag(HValue::kCanOverflow)) {
1606 Label dividend_not_min_int; 1606 Label dividend_not_min_int;
1607 __ cmp(dividend, kMinInt); 1607 __ cmp(dividend, kMinInt);
1608 __ j(not_zero, &dividend_not_min_int, Label::kNear); 1608 __ j(not_zero, &dividend_not_min_int, Label::kNear);
1609 __ cmp(divisor, -1); 1609 __ cmp(divisor, -1);
1610 DeoptimizeIf(zero, instr, Deoptimizer::kOverflow); 1610 DeoptimizeIf(zero, instr, "overflow");
1611 __ bind(&dividend_not_min_int); 1611 __ bind(&dividend_not_min_int);
1612 } 1612 }
1613 1613
1614 // Sign extend to edx (= remainder). 1614 // Sign extend to edx (= remainder).
1615 __ cdq(); 1615 __ cdq();
1616 __ idiv(divisor); 1616 __ idiv(divisor);
1617 1617
1618 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1618 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1619 // Deoptimize if remainder is not 0. 1619 // Deoptimize if remainder is not 0.
1620 __ test(remainder, remainder); 1620 __ test(remainder, remainder);
1621 DeoptimizeIf(not_zero, instr, Deoptimizer::kLostPrecision); 1621 DeoptimizeIf(not_zero, instr, "lost precision");
1622 } 1622 }
1623 } 1623 }
1624 1624
1625 1625
1626 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { 1626 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1627 Register dividend = ToRegister(instr->dividend()); 1627 Register dividend = ToRegister(instr->dividend());
1628 int32_t divisor = instr->divisor(); 1628 int32_t divisor = instr->divisor();
1629 DCHECK(dividend.is(ToRegister(instr->result()))); 1629 DCHECK(dividend.is(ToRegister(instr->result())));
1630 1630
1631 // If the divisor is positive, things are easy: There can be no deopts and we 1631 // If the divisor is positive, things are easy: There can be no deopts and we
1632 // can simply do an arithmetic right shift. 1632 // can simply do an arithmetic right shift.
1633 if (divisor == 1) return; 1633 if (divisor == 1) return;
1634 int32_t shift = WhichPowerOf2Abs(divisor); 1634 int32_t shift = WhichPowerOf2Abs(divisor);
1635 if (divisor > 1) { 1635 if (divisor > 1) {
1636 __ sar(dividend, shift); 1636 __ sar(dividend, shift);
1637 return; 1637 return;
1638 } 1638 }
1639 1639
1640 // If the divisor is negative, we have to negate and handle edge cases. 1640 // If the divisor is negative, we have to negate and handle edge cases.
1641 __ neg(dividend); 1641 __ neg(dividend);
1642 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1642 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1643 DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); 1643 DeoptimizeIf(zero, instr, "minus zero");
1644 } 1644 }
1645 1645
1646 // Dividing by -1 is basically negation, unless we overflow. 1646 // Dividing by -1 is basically negation, unless we overflow.
1647 if (divisor == -1) { 1647 if (divisor == -1) {
1648 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1648 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1649 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 1649 DeoptimizeIf(overflow, instr, "overflow");
1650 } 1650 }
1651 return; 1651 return;
1652 } 1652 }
1653 1653
1654 // If the negation could not overflow, simply shifting is OK. 1654 // If the negation could not overflow, simply shifting is OK.
1655 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1655 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1656 __ sar(dividend, shift); 1656 __ sar(dividend, shift);
1657 return; 1657 return;
1658 } 1658 }
1659 1659
1660 Label not_kmin_int, done; 1660 Label not_kmin_int, done;
1661 __ j(no_overflow, &not_kmin_int, Label::kNear); 1661 __ j(no_overflow, &not_kmin_int, Label::kNear);
1662 __ mov(dividend, Immediate(kMinInt / divisor)); 1662 __ mov(dividend, Immediate(kMinInt / divisor));
1663 __ jmp(&done, Label::kNear); 1663 __ jmp(&done, Label::kNear);
1664 __ bind(&not_kmin_int); 1664 __ bind(&not_kmin_int);
1665 __ sar(dividend, shift); 1665 __ sar(dividend, shift);
1666 __ bind(&done); 1666 __ bind(&done);
1667 } 1667 }
1668 1668
1669 1669
1670 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1670 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1671 Register dividend = ToRegister(instr->dividend()); 1671 Register dividend = ToRegister(instr->dividend());
1672 int32_t divisor = instr->divisor(); 1672 int32_t divisor = instr->divisor();
1673 DCHECK(ToRegister(instr->result()).is(edx)); 1673 DCHECK(ToRegister(instr->result()).is(edx));
1674 1674
1675 if (divisor == 0) { 1675 if (divisor == 0) {
1676 DeoptimizeIf(no_condition, instr, Deoptimizer::kDivisionByZero); 1676 DeoptimizeIf(no_condition, instr, "division by zero");
1677 return; 1677 return;
1678 } 1678 }
1679 1679
1680 // Check for (0 / -x) that will produce negative zero. 1680 // Check for (0 / -x) that will produce negative zero.
1681 HMathFloorOfDiv* hdiv = instr->hydrogen(); 1681 HMathFloorOfDiv* hdiv = instr->hydrogen();
1682 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1682 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1683 __ test(dividend, dividend); 1683 __ test(dividend, dividend);
1684 DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); 1684 DeoptimizeIf(zero, instr, "minus zero");
1685 } 1685 }
1686 1686
1687 // Easy case: We need no dynamic check for the dividend and the flooring 1687 // Easy case: We need no dynamic check for the dividend and the flooring
1688 // division is the same as the truncating division. 1688 // division is the same as the truncating division.
1689 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 1689 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
1690 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 1690 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
1691 __ TruncatingDiv(dividend, Abs(divisor)); 1691 __ TruncatingDiv(dividend, Abs(divisor));
1692 if (divisor < 0) __ neg(edx); 1692 if (divisor < 0) __ neg(edx);
1693 return; 1693 return;
1694 } 1694 }
(...skipping 26 matching lines...) Expand all
1721 Register result = ToRegister(instr->result()); 1721 Register result = ToRegister(instr->result());
1722 DCHECK(dividend.is(eax)); 1722 DCHECK(dividend.is(eax));
1723 DCHECK(remainder.is(edx)); 1723 DCHECK(remainder.is(edx));
1724 DCHECK(result.is(eax)); 1724 DCHECK(result.is(eax));
1725 DCHECK(!divisor.is(eax)); 1725 DCHECK(!divisor.is(eax));
1726 DCHECK(!divisor.is(edx)); 1726 DCHECK(!divisor.is(edx));
1727 1727
1728 // Check for x / 0. 1728 // Check for x / 0.
1729 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1729 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1730 __ test(divisor, divisor); 1730 __ test(divisor, divisor);
1731 DeoptimizeIf(zero, instr, Deoptimizer::kDivisionByZero); 1731 DeoptimizeIf(zero, instr, "division by zero");
1732 } 1732 }
1733 1733
1734 // Check for (0 / -x) that will produce negative zero. 1734 // Check for (0 / -x) that will produce negative zero.
1735 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1735 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1736 Label dividend_not_zero; 1736 Label dividend_not_zero;
1737 __ test(dividend, dividend); 1737 __ test(dividend, dividend);
1738 __ j(not_zero, &dividend_not_zero, Label::kNear); 1738 __ j(not_zero, &dividend_not_zero, Label::kNear);
1739 __ test(divisor, divisor); 1739 __ test(divisor, divisor);
1740 DeoptimizeIf(sign, instr, Deoptimizer::kMinusZero); 1740 DeoptimizeIf(sign, instr, "minus zero");
1741 __ bind(&dividend_not_zero); 1741 __ bind(&dividend_not_zero);
1742 } 1742 }
1743 1743
1744 // Check for (kMinInt / -1). 1744 // Check for (kMinInt / -1).
1745 if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1745 if (hdiv->CheckFlag(HValue::kCanOverflow)) {
1746 Label dividend_not_min_int; 1746 Label dividend_not_min_int;
1747 __ cmp(dividend, kMinInt); 1747 __ cmp(dividend, kMinInt);
1748 __ j(not_zero, &dividend_not_min_int, Label::kNear); 1748 __ j(not_zero, &dividend_not_min_int, Label::kNear);
1749 __ cmp(divisor, -1); 1749 __ cmp(divisor, -1);
1750 DeoptimizeIf(zero, instr, Deoptimizer::kOverflow); 1750 DeoptimizeIf(zero, instr, "overflow");
1751 __ bind(&dividend_not_min_int); 1751 __ bind(&dividend_not_min_int);
1752 } 1752 }
1753 1753
1754 // Sign extend to edx (= remainder). 1754 // Sign extend to edx (= remainder).
1755 __ cdq(); 1755 __ cdq();
1756 __ idiv(divisor); 1756 __ idiv(divisor);
1757 1757
1758 Label done; 1758 Label done;
1759 __ test(remainder, remainder); 1759 __ test(remainder, remainder);
1760 __ j(zero, &done, Label::kNear); 1760 __ j(zero, &done, Label::kNear);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 __ imul(left, left, constant); 1818 __ imul(left, left, constant);
1819 } 1819 }
1820 } else { 1820 } else {
1821 if (instr->hydrogen()->representation().IsSmi()) { 1821 if (instr->hydrogen()->representation().IsSmi()) {
1822 __ SmiUntag(left); 1822 __ SmiUntag(left);
1823 } 1823 }
1824 __ imul(left, ToOperand(right)); 1824 __ imul(left, ToOperand(right));
1825 } 1825 }
1826 1826
1827 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1827 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1828 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 1828 DeoptimizeIf(overflow, instr, "overflow");
1829 } 1829 }
1830 1830
1831 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1831 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1832 // Bail out if the result is supposed to be negative zero. 1832 // Bail out if the result is supposed to be negative zero.
1833 Label done; 1833 Label done;
1834 __ test(left, Operand(left)); 1834 __ test(left, Operand(left));
1835 __ j(not_zero, &done); 1835 __ j(not_zero, &done);
1836 if (right->IsConstantOperand()) { 1836 if (right->IsConstantOperand()) {
1837 if (ToInteger32(LConstantOperand::cast(right)) < 0) { 1837 if (ToInteger32(LConstantOperand::cast(right)) < 0) {
1838 DeoptimizeIf(no_condition, instr, Deoptimizer::kMinusZero); 1838 DeoptimizeIf(no_condition, instr, "minus zero");
1839 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { 1839 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
1840 __ cmp(ToRegister(instr->temp()), Immediate(0)); 1840 __ cmp(ToRegister(instr->temp()), Immediate(0));
1841 DeoptimizeIf(less, instr, Deoptimizer::kMinusZero); 1841 DeoptimizeIf(less, instr, "minus zero");
1842 } 1842 }
1843 } else { 1843 } else {
1844 // Test the non-zero operand for negative sign. 1844 // Test the non-zero operand for negative sign.
1845 __ or_(ToRegister(instr->temp()), ToOperand(right)); 1845 __ or_(ToRegister(instr->temp()), ToOperand(right));
1846 DeoptimizeIf(sign, instr, Deoptimizer::kMinusZero); 1846 DeoptimizeIf(sign, instr, "minus zero");
1847 } 1847 }
1848 __ bind(&done); 1848 __ bind(&done);
1849 } 1849 }
1850 } 1850 }
1851 1851
1852 1852
1853 void LCodeGen::DoBitI(LBitI* instr) { 1853 void LCodeGen::DoBitI(LBitI* instr) {
1854 LOperand* left = instr->left(); 1854 LOperand* left = instr->left();
1855 LOperand* right = instr->right(); 1855 LOperand* right = instr->right();
1856 DCHECK(left->Equals(instr->result())); 1856 DCHECK(left->Equals(instr->result()));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 case Token::ROR: 1909 case Token::ROR:
1910 __ ror_cl(ToRegister(left)); 1910 __ ror_cl(ToRegister(left));
1911 break; 1911 break;
1912 case Token::SAR: 1912 case Token::SAR:
1913 __ sar_cl(ToRegister(left)); 1913 __ sar_cl(ToRegister(left));
1914 break; 1914 break;
1915 case Token::SHR: 1915 case Token::SHR:
1916 __ shr_cl(ToRegister(left)); 1916 __ shr_cl(ToRegister(left));
1917 if (instr->can_deopt()) { 1917 if (instr->can_deopt()) {
1918 __ test(ToRegister(left), ToRegister(left)); 1918 __ test(ToRegister(left), ToRegister(left));
1919 DeoptimizeIf(sign, instr, Deoptimizer::kNegativeValue); 1919 DeoptimizeIf(sign, instr, "negative value");
1920 } 1920 }
1921 break; 1921 break;
1922 case Token::SHL: 1922 case Token::SHL:
1923 __ shl_cl(ToRegister(left)); 1923 __ shl_cl(ToRegister(left));
1924 break; 1924 break;
1925 default: 1925 default:
1926 UNREACHABLE(); 1926 UNREACHABLE();
1927 break; 1927 break;
1928 } 1928 }
1929 } else { 1929 } else {
1930 int value = ToInteger32(LConstantOperand::cast(right)); 1930 int value = ToInteger32(LConstantOperand::cast(right));
1931 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1931 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
1932 switch (instr->op()) { 1932 switch (instr->op()) {
1933 case Token::ROR: 1933 case Token::ROR:
1934 if (shift_count == 0 && instr->can_deopt()) { 1934 if (shift_count == 0 && instr->can_deopt()) {
1935 __ test(ToRegister(left), ToRegister(left)); 1935 __ test(ToRegister(left), ToRegister(left));
1936 DeoptimizeIf(sign, instr, Deoptimizer::kNegativeValue); 1936 DeoptimizeIf(sign, instr, "negative value");
1937 } else { 1937 } else {
1938 __ ror(ToRegister(left), shift_count); 1938 __ ror(ToRegister(left), shift_count);
1939 } 1939 }
1940 break; 1940 break;
1941 case Token::SAR: 1941 case Token::SAR:
1942 if (shift_count != 0) { 1942 if (shift_count != 0) {
1943 __ sar(ToRegister(left), shift_count); 1943 __ sar(ToRegister(left), shift_count);
1944 } 1944 }
1945 break; 1945 break;
1946 case Token::SHR: 1946 case Token::SHR:
1947 if (shift_count != 0) { 1947 if (shift_count != 0) {
1948 __ shr(ToRegister(left), shift_count); 1948 __ shr(ToRegister(left), shift_count);
1949 } else if (instr->can_deopt()) { 1949 } else if (instr->can_deopt()) {
1950 __ test(ToRegister(left), ToRegister(left)); 1950 __ test(ToRegister(left), ToRegister(left));
1951 DeoptimizeIf(sign, instr, Deoptimizer::kNegativeValue); 1951 DeoptimizeIf(sign, instr, "negative value");
1952 } 1952 }
1953 break; 1953 break;
1954 case Token::SHL: 1954 case Token::SHL:
1955 if (shift_count != 0) { 1955 if (shift_count != 0) {
1956 if (instr->hydrogen_value()->representation().IsSmi() && 1956 if (instr->hydrogen_value()->representation().IsSmi() &&
1957 instr->can_deopt()) { 1957 instr->can_deopt()) {
1958 if (shift_count != 1) { 1958 if (shift_count != 1) {
1959 __ shl(ToRegister(left), shift_count - 1); 1959 __ shl(ToRegister(left), shift_count - 1);
1960 } 1960 }
1961 __ SmiTag(ToRegister(left)); 1961 __ SmiTag(ToRegister(left));
1962 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 1962 DeoptimizeIf(overflow, instr, "overflow");
1963 } else { 1963 } else {
1964 __ shl(ToRegister(left), shift_count); 1964 __ shl(ToRegister(left), shift_count);
1965 } 1965 }
1966 } 1966 }
1967 break; 1967 break;
1968 default: 1968 default:
1969 UNREACHABLE(); 1969 UNREACHABLE();
1970 break; 1970 break;
1971 } 1971 }
1972 } 1972 }
1973 } 1973 }
1974 1974
1975 1975
1976 void LCodeGen::DoSubI(LSubI* instr) { 1976 void LCodeGen::DoSubI(LSubI* instr) {
1977 LOperand* left = instr->left(); 1977 LOperand* left = instr->left();
1978 LOperand* right = instr->right(); 1978 LOperand* right = instr->right();
1979 DCHECK(left->Equals(instr->result())); 1979 DCHECK(left->Equals(instr->result()));
1980 1980
1981 if (right->IsConstantOperand()) { 1981 if (right->IsConstantOperand()) {
1982 __ sub(ToOperand(left), 1982 __ sub(ToOperand(left),
1983 ToImmediate(right, instr->hydrogen()->representation())); 1983 ToImmediate(right, instr->hydrogen()->representation()));
1984 } else { 1984 } else {
1985 __ sub(ToRegister(left), ToOperand(right)); 1985 __ sub(ToRegister(left), ToOperand(right));
1986 } 1986 }
1987 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1987 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1988 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 1988 DeoptimizeIf(overflow, instr, "overflow");
1989 } 1989 }
1990 } 1990 }
1991 1991
1992 1992
1993 void LCodeGen::DoConstantI(LConstantI* instr) { 1993 void LCodeGen::DoConstantI(LConstantI* instr) {
1994 __ Move(ToRegister(instr->result()), Immediate(instr->value())); 1994 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
1995 } 1995 }
1996 1996
1997 1997
1998 void LCodeGen::DoConstantS(LConstantS* instr) { 1998 void LCodeGen::DoConstantS(LConstantS* instr) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2038 void LCodeGen::DoDateField(LDateField* instr) { 2038 void LCodeGen::DoDateField(LDateField* instr) {
2039 Register object = ToRegister(instr->date()); 2039 Register object = ToRegister(instr->date());
2040 Register result = ToRegister(instr->result()); 2040 Register result = ToRegister(instr->result());
2041 Register scratch = ToRegister(instr->temp()); 2041 Register scratch = ToRegister(instr->temp());
2042 Smi* index = instr->index(); 2042 Smi* index = instr->index();
2043 Label runtime, done; 2043 Label runtime, done;
2044 DCHECK(object.is(result)); 2044 DCHECK(object.is(result));
2045 DCHECK(object.is(eax)); 2045 DCHECK(object.is(eax));
2046 2046
2047 __ test(object, Immediate(kSmiTagMask)); 2047 __ test(object, Immediate(kSmiTagMask));
2048 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); 2048 DeoptimizeIf(zero, instr, "Smi");
2049 __ CmpObjectType(object, JS_DATE_TYPE, scratch); 2049 __ CmpObjectType(object, JS_DATE_TYPE, scratch);
2050 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotADateObject); 2050 DeoptimizeIf(not_equal, instr, "not a date object");
2051 2051
2052 if (index->value() == 0) { 2052 if (index->value() == 0) {
2053 __ mov(result, FieldOperand(object, JSDate::kValueOffset)); 2053 __ mov(result, FieldOperand(object, JSDate::kValueOffset));
2054 } else { 2054 } else {
2055 if (index->value() < JSDate::kFirstUncachedField) { 2055 if (index->value() < JSDate::kFirstUncachedField) {
2056 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 2056 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
2057 __ mov(scratch, Operand::StaticVariable(stamp)); 2057 __ mov(scratch, Operand::StaticVariable(stamp));
2058 __ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset)); 2058 __ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
2059 __ j(not_equal, &runtime, Label::kNear); 2059 __ j(not_equal, &runtime, Label::kNear);
2060 __ mov(result, FieldOperand(object, JSDate::kValueOffset + 2060 __ mov(result, FieldOperand(object, JSDate::kValueOffset +
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 __ lea(ToRegister(instr->result()), address); 2170 __ lea(ToRegister(instr->result()), address);
2171 } 2171 }
2172 } else { 2172 } else {
2173 if (right->IsConstantOperand()) { 2173 if (right->IsConstantOperand()) {
2174 __ add(ToOperand(left), 2174 __ add(ToOperand(left),
2175 ToImmediate(right, instr->hydrogen()->representation())); 2175 ToImmediate(right, instr->hydrogen()->representation()));
2176 } else { 2176 } else {
2177 __ add(ToRegister(left), ToOperand(right)); 2177 __ add(ToRegister(left), ToOperand(right));
2178 } 2178 }
2179 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 2179 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
2180 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 2180 DeoptimizeIf(overflow, instr, "overflow");
2181 } 2181 }
2182 } 2182 }
2183 } 2183 }
2184 2184
2185 2185
2186 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 2186 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
2187 LOperand* left = instr->left(); 2187 LOperand* left = instr->left();
2188 LOperand* right = instr->right(); 2188 LOperand* right = instr->right();
2189 DCHECK(left->Equals(instr->result())); 2189 DCHECK(left->Equals(instr->result()));
2190 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 2190 HMathMinMax::Operation operation = instr->hydrogen()->operation();
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2413 } 2413 }
2414 2414
2415 if (expected.Contains(ToBooleanStub::SMI)) { 2415 if (expected.Contains(ToBooleanStub::SMI)) {
2416 // Smis: 0 -> false, all other -> true. 2416 // Smis: 0 -> false, all other -> true.
2417 __ test(reg, Operand(reg)); 2417 __ test(reg, Operand(reg));
2418 __ j(equal, instr->FalseLabel(chunk_)); 2418 __ j(equal, instr->FalseLabel(chunk_));
2419 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2419 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2420 } else if (expected.NeedsMap()) { 2420 } else if (expected.NeedsMap()) {
2421 // If we need a map later and have a Smi -> deopt. 2421 // If we need a map later and have a Smi -> deopt.
2422 __ test(reg, Immediate(kSmiTagMask)); 2422 __ test(reg, Immediate(kSmiTagMask));
2423 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); 2423 DeoptimizeIf(zero, instr, "Smi");
2424 } 2424 }
2425 2425
2426 Register map = no_reg; // Keep the compiler happy. 2426 Register map = no_reg; // Keep the compiler happy.
2427 if (expected.NeedsMap()) { 2427 if (expected.NeedsMap()) {
2428 map = ToRegister(instr->temp()); 2428 map = ToRegister(instr->temp());
2429 DCHECK(!map.is(reg)); 2429 DCHECK(!map.is(reg));
2430 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 2430 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
2431 2431
2432 if (expected.CanBeUndetectable()) { 2432 if (expected.CanBeUndetectable()) {
2433 // Undetectable -> false. 2433 // Undetectable -> false.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2470 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 2470 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
2471 __ FCmp(); 2471 __ FCmp();
2472 __ j(zero, instr->FalseLabel(chunk_)); 2472 __ j(zero, instr->FalseLabel(chunk_));
2473 __ jmp(instr->TrueLabel(chunk_)); 2473 __ jmp(instr->TrueLabel(chunk_));
2474 __ bind(&not_heap_number); 2474 __ bind(&not_heap_number);
2475 } 2475 }
2476 2476
2477 if (!expected.IsGeneric()) { 2477 if (!expected.IsGeneric()) {
2478 // We've seen something for the first time -> deopt. 2478 // We've seen something for the first time -> deopt.
2479 // This can only happen if we are not generic already. 2479 // This can only happen if we are not generic already.
2480 DeoptimizeIf(no_condition, instr, Deoptimizer::kUnexpectedObject); 2480 DeoptimizeIf(no_condition, instr, "unexpected object");
2481 } 2481 }
2482 } 2482 }
2483 } 2483 }
2484 } 2484 }
2485 2485
2486 2486
2487 void LCodeGen::EmitGoto(int block) { 2487 void LCodeGen::EmitGoto(int block) {
2488 if (!IsNextEmittedBlock(block)) { 2488 if (!IsNextEmittedBlock(block)) {
2489 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2489 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2490 } 2490 }
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 info()->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 3110 info()->AddNoFrameRange(no_frame_start, masm_->pc_offset());
3111 } 3111 }
3112 } 3112 }
3113 3113
3114 3114
3115 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 3115 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
3116 Register result = ToRegister(instr->result()); 3116 Register result = ToRegister(instr->result());
3117 __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle())); 3117 __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle()));
3118 if (instr->hydrogen()->RequiresHoleCheck()) { 3118 if (instr->hydrogen()->RequiresHoleCheck()) {
3119 __ cmp(result, factory()->the_hole_value()); 3119 __ cmp(result, factory()->the_hole_value());
3120 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3120 DeoptimizeIf(equal, instr, "hole");
3121 } 3121 }
3122 } 3122 }
3123 3123
3124 3124
3125 template <class T> 3125 template <class T>
3126 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { 3126 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
3127 DCHECK(FLAG_vector_ics); 3127 DCHECK(FLAG_vector_ics);
3128 Register vector_register = ToRegister(instr->temp_vector()); 3128 Register vector_register = ToRegister(instr->temp_vector());
3129 Register slot_register = VectorLoadICDescriptor::SlotRegister(); 3129 Register slot_register = VectorLoadICDescriptor::SlotRegister();
3130 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); 3130 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
(...skipping 28 matching lines...) Expand all
3159 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 3159 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
3160 Register value = ToRegister(instr->value()); 3160 Register value = ToRegister(instr->value());
3161 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle(); 3161 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
3162 3162
3163 // If the cell we are storing to contains the hole it could have 3163 // If the cell we are storing to contains the hole it could have
3164 // been deleted from the property dictionary. In that case, we need 3164 // been deleted from the property dictionary. In that case, we need
3165 // to update the property details in the property dictionary to mark 3165 // to update the property details in the property dictionary to mark
3166 // it as no longer deleted. We deoptimize in that case. 3166 // it as no longer deleted. We deoptimize in that case.
3167 if (instr->hydrogen()->RequiresHoleCheck()) { 3167 if (instr->hydrogen()->RequiresHoleCheck()) {
3168 __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value()); 3168 __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value());
3169 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3169 DeoptimizeIf(equal, instr, "hole");
3170 } 3170 }
3171 3171
3172 // Store the value. 3172 // Store the value.
3173 __ mov(Operand::ForCell(cell_handle), value); 3173 __ mov(Operand::ForCell(cell_handle), value);
3174 // Cells are always rescanned, so no write barrier here. 3174 // Cells are always rescanned, so no write barrier here.
3175 } 3175 }
3176 3176
3177 3177
3178 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 3178 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
3179 Register context = ToRegister(instr->context()); 3179 Register context = ToRegister(instr->context());
3180 Register result = ToRegister(instr->result()); 3180 Register result = ToRegister(instr->result());
3181 __ mov(result, ContextOperand(context, instr->slot_index())); 3181 __ mov(result, ContextOperand(context, instr->slot_index()));
3182 3182
3183 if (instr->hydrogen()->RequiresHoleCheck()) { 3183 if (instr->hydrogen()->RequiresHoleCheck()) {
3184 __ cmp(result, factory()->the_hole_value()); 3184 __ cmp(result, factory()->the_hole_value());
3185 if (instr->hydrogen()->DeoptimizesOnHole()) { 3185 if (instr->hydrogen()->DeoptimizesOnHole()) {
3186 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3186 DeoptimizeIf(equal, instr, "hole");
3187 } else { 3187 } else {
3188 Label is_not_hole; 3188 Label is_not_hole;
3189 __ j(not_equal, &is_not_hole, Label::kNear); 3189 __ j(not_equal, &is_not_hole, Label::kNear);
3190 __ mov(result, factory()->undefined_value()); 3190 __ mov(result, factory()->undefined_value());
3191 __ bind(&is_not_hole); 3191 __ bind(&is_not_hole);
3192 } 3192 }
3193 } 3193 }
3194 } 3194 }
3195 3195
3196 3196
3197 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 3197 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
3198 Register context = ToRegister(instr->context()); 3198 Register context = ToRegister(instr->context());
3199 Register value = ToRegister(instr->value()); 3199 Register value = ToRegister(instr->value());
3200 3200
3201 Label skip_assignment; 3201 Label skip_assignment;
3202 3202
3203 Operand target = ContextOperand(context, instr->slot_index()); 3203 Operand target = ContextOperand(context, instr->slot_index());
3204 if (instr->hydrogen()->RequiresHoleCheck()) { 3204 if (instr->hydrogen()->RequiresHoleCheck()) {
3205 __ cmp(target, factory()->the_hole_value()); 3205 __ cmp(target, factory()->the_hole_value());
3206 if (instr->hydrogen()->DeoptimizesOnHole()) { 3206 if (instr->hydrogen()->DeoptimizesOnHole()) {
3207 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3207 DeoptimizeIf(equal, instr, "hole");
3208 } else { 3208 } else {
3209 __ j(not_equal, &skip_assignment, Label::kNear); 3209 __ j(not_equal, &skip_assignment, Label::kNear);
3210 } 3210 }
3211 } 3211 }
3212 3212
3213 __ mov(target, value); 3213 __ mov(target, value);
3214 if (instr->hydrogen()->NeedsWriteBarrier()) { 3214 if (instr->hydrogen()->NeedsWriteBarrier()) {
3215 SmiCheck check_needed = 3215 SmiCheck check_needed =
3216 instr->hydrogen()->value()->type().IsHeapObject() 3216 instr->hydrogen()->value()->type().IsHeapObject()
3217 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3217 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3291 Register function = ToRegister(instr->function()); 3291 Register function = ToRegister(instr->function());
3292 Register temp = ToRegister(instr->temp()); 3292 Register temp = ToRegister(instr->temp());
3293 Register result = ToRegister(instr->result()); 3293 Register result = ToRegister(instr->result());
3294 3294
3295 // Get the prototype or initial map from the function. 3295 // Get the prototype or initial map from the function.
3296 __ mov(result, 3296 __ mov(result,
3297 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3297 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
3298 3298
3299 // Check that the function has a prototype or an initial map. 3299 // Check that the function has a prototype or an initial map.
3300 __ cmp(Operand(result), Immediate(factory()->the_hole_value())); 3300 __ cmp(Operand(result), Immediate(factory()->the_hole_value()));
3301 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3301 DeoptimizeIf(equal, instr, "hole");
3302 3302
3303 // If the function does not have an initial map, we're done. 3303 // If the function does not have an initial map, we're done.
3304 Label done; 3304 Label done;
3305 __ CmpObjectType(result, MAP_TYPE, temp); 3305 __ CmpObjectType(result, MAP_TYPE, temp);
3306 __ j(not_equal, &done, Label::kNear); 3306 __ j(not_equal, &done, Label::kNear);
3307 3307
3308 // Get the prototype from the initial map. 3308 // Get the prototype from the initial map.
3309 __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); 3309 __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
3310 3310
3311 // All done. 3311 // All done.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 break; 3382 break;
3383 case EXTERNAL_INT32_ELEMENTS: 3383 case EXTERNAL_INT32_ELEMENTS:
3384 case INT32_ELEMENTS: 3384 case INT32_ELEMENTS:
3385 __ mov(result, operand); 3385 __ mov(result, operand);
3386 break; 3386 break;
3387 case EXTERNAL_UINT32_ELEMENTS: 3387 case EXTERNAL_UINT32_ELEMENTS:
3388 case UINT32_ELEMENTS: 3388 case UINT32_ELEMENTS:
3389 __ mov(result, operand); 3389 __ mov(result, operand);
3390 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3390 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3391 __ test(result, Operand(result)); 3391 __ test(result, Operand(result));
3392 DeoptimizeIf(negative, instr, Deoptimizer::kNegativeValue); 3392 DeoptimizeIf(negative, instr, "negative value");
3393 } 3393 }
3394 break; 3394 break;
3395 case EXTERNAL_FLOAT32_ELEMENTS: 3395 case EXTERNAL_FLOAT32_ELEMENTS:
3396 case EXTERNAL_FLOAT64_ELEMENTS: 3396 case EXTERNAL_FLOAT64_ELEMENTS:
3397 case FLOAT32_ELEMENTS: 3397 case FLOAT32_ELEMENTS:
3398 case FLOAT64_ELEMENTS: 3398 case FLOAT64_ELEMENTS:
3399 case FAST_SMI_ELEMENTS: 3399 case FAST_SMI_ELEMENTS:
3400 case FAST_ELEMENTS: 3400 case FAST_ELEMENTS:
3401 case FAST_DOUBLE_ELEMENTS: 3401 case FAST_DOUBLE_ELEMENTS:
3402 case FAST_HOLEY_SMI_ELEMENTS: 3402 case FAST_HOLEY_SMI_ELEMENTS:
3403 case FAST_HOLEY_ELEMENTS: 3403 case FAST_HOLEY_ELEMENTS:
3404 case FAST_HOLEY_DOUBLE_ELEMENTS: 3404 case FAST_HOLEY_DOUBLE_ELEMENTS:
3405 case DICTIONARY_ELEMENTS: 3405 case DICTIONARY_ELEMENTS:
3406 case SLOPPY_ARGUMENTS_ELEMENTS: 3406 case SLOPPY_ARGUMENTS_ELEMENTS:
3407 UNREACHABLE(); 3407 UNREACHABLE();
3408 break; 3408 break;
3409 } 3409 }
3410 } 3410 }
3411 } 3411 }
3412 3412
3413 3413
3414 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3414 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3415 if (instr->hydrogen()->RequiresHoleCheck()) { 3415 if (instr->hydrogen()->RequiresHoleCheck()) {
3416 Operand hole_check_operand = BuildFastArrayOperand( 3416 Operand hole_check_operand = BuildFastArrayOperand(
3417 instr->elements(), instr->key(), 3417 instr->elements(), instr->key(),
3418 instr->hydrogen()->key()->representation(), 3418 instr->hydrogen()->key()->representation(),
3419 FAST_DOUBLE_ELEMENTS, 3419 FAST_DOUBLE_ELEMENTS,
3420 instr->base_offset() + sizeof(kHoleNanLower32)); 3420 instr->base_offset() + sizeof(kHoleNanLower32));
3421 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 3421 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
3422 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3422 DeoptimizeIf(equal, instr, "hole");
3423 } 3423 }
3424 3424
3425 Operand double_load_operand = BuildFastArrayOperand( 3425 Operand double_load_operand = BuildFastArrayOperand(
3426 instr->elements(), 3426 instr->elements(),
3427 instr->key(), 3427 instr->key(),
3428 instr->hydrogen()->key()->representation(), 3428 instr->hydrogen()->key()->representation(),
3429 FAST_DOUBLE_ELEMENTS, 3429 FAST_DOUBLE_ELEMENTS,
3430 instr->base_offset()); 3430 instr->base_offset());
3431 X87Mov(ToX87Register(instr->result()), double_load_operand); 3431 X87Mov(ToX87Register(instr->result()), double_load_operand);
3432 } 3432 }
3433 3433
3434 3434
3435 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3435 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3436 Register result = ToRegister(instr->result()); 3436 Register result = ToRegister(instr->result());
3437 3437
3438 // Load the result. 3438 // Load the result.
3439 __ mov(result, 3439 __ mov(result,
3440 BuildFastArrayOperand(instr->elements(), instr->key(), 3440 BuildFastArrayOperand(instr->elements(), instr->key(),
3441 instr->hydrogen()->key()->representation(), 3441 instr->hydrogen()->key()->representation(),
3442 FAST_ELEMENTS, instr->base_offset())); 3442 FAST_ELEMENTS, instr->base_offset()));
3443 3443
3444 // Check for the hole value. 3444 // Check for the hole value.
3445 if (instr->hydrogen()->RequiresHoleCheck()) { 3445 if (instr->hydrogen()->RequiresHoleCheck()) {
3446 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3446 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3447 __ test(result, Immediate(kSmiTagMask)); 3447 __ test(result, Immediate(kSmiTagMask));
3448 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotASmi); 3448 DeoptimizeIf(not_equal, instr, "not a Smi");
3449 } else { 3449 } else {
3450 __ cmp(result, factory()->the_hole_value()); 3450 __ cmp(result, factory()->the_hole_value());
3451 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3451 DeoptimizeIf(equal, instr, "hole");
3452 } 3452 }
3453 } 3453 }
3454 } 3454 }
3455 3455
3456 3456
3457 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3457 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3458 if (instr->is_typed_elements()) { 3458 if (instr->is_typed_elements()) {
3459 DoLoadKeyedExternalArray(instr); 3459 DoLoadKeyedExternalArray(instr);
3460 } else if (instr->hydrogen()->representation().IsDouble()) { 3460 } else if (instr->hydrogen()->representation().IsDouble()) {
3461 DoLoadKeyedFixedDoubleArray(instr); 3461 DoLoadKeyedFixedDoubleArray(instr);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3588 } 3588 }
3589 3589
3590 // Normal function. Replace undefined or null with global receiver. 3590 // Normal function. Replace undefined or null with global receiver.
3591 __ cmp(receiver, factory()->null_value()); 3591 __ cmp(receiver, factory()->null_value());
3592 __ j(equal, &global_object, Label::kNear); 3592 __ j(equal, &global_object, Label::kNear);
3593 __ cmp(receiver, factory()->undefined_value()); 3593 __ cmp(receiver, factory()->undefined_value());
3594 __ j(equal, &global_object, Label::kNear); 3594 __ j(equal, &global_object, Label::kNear);
3595 3595
3596 // The receiver should be a JS object. 3596 // The receiver should be a JS object.
3597 __ test(receiver, Immediate(kSmiTagMask)); 3597 __ test(receiver, Immediate(kSmiTagMask));
3598 DeoptimizeIf(equal, instr, Deoptimizer::kSmi); 3598 DeoptimizeIf(equal, instr, "Smi");
3599 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); 3599 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
3600 DeoptimizeIf(below, instr, Deoptimizer::kNotAJavaScriptObject); 3600 DeoptimizeIf(below, instr, "not a JavaScript object");
3601 3601
3602 __ jmp(&receiver_ok, Label::kNear); 3602 __ jmp(&receiver_ok, Label::kNear);
3603 __ bind(&global_object); 3603 __ bind(&global_object);
3604 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset)); 3604 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset));
3605 const int global_offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 3605 const int global_offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
3606 __ mov(receiver, Operand(receiver, global_offset)); 3606 __ mov(receiver, Operand(receiver, global_offset));
3607 const int proxy_offset = GlobalObject::kGlobalProxyOffset; 3607 const int proxy_offset = GlobalObject::kGlobalProxyOffset;
3608 __ mov(receiver, FieldOperand(receiver, proxy_offset)); 3608 __ mov(receiver, FieldOperand(receiver, proxy_offset));
3609 __ bind(&receiver_ok); 3609 __ bind(&receiver_ok);
3610 } 3610 }
3611 3611
3612 3612
3613 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3613 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3614 Register receiver = ToRegister(instr->receiver()); 3614 Register receiver = ToRegister(instr->receiver());
3615 Register function = ToRegister(instr->function()); 3615 Register function = ToRegister(instr->function());
3616 Register length = ToRegister(instr->length()); 3616 Register length = ToRegister(instr->length());
3617 Register elements = ToRegister(instr->elements()); 3617 Register elements = ToRegister(instr->elements());
3618 DCHECK(receiver.is(eax)); // Used for parameter count. 3618 DCHECK(receiver.is(eax)); // Used for parameter count.
3619 DCHECK(function.is(edi)); // Required by InvokeFunction. 3619 DCHECK(function.is(edi)); // Required by InvokeFunction.
3620 DCHECK(ToRegister(instr->result()).is(eax)); 3620 DCHECK(ToRegister(instr->result()).is(eax));
3621 3621
3622 // Copy the arguments to this function possibly from the 3622 // Copy the arguments to this function possibly from the
3623 // adaptor frame below it. 3623 // adaptor frame below it.
3624 const uint32_t kArgumentsLimit = 1 * KB; 3624 const uint32_t kArgumentsLimit = 1 * KB;
3625 __ cmp(length, kArgumentsLimit); 3625 __ cmp(length, kArgumentsLimit);
3626 DeoptimizeIf(above, instr, Deoptimizer::kTooManyArguments); 3626 DeoptimizeIf(above, instr, "too many arguments");
3627 3627
3628 __ push(receiver); 3628 __ push(receiver);
3629 __ mov(receiver, length); 3629 __ mov(receiver, length);
3630 3630
3631 // Loop through the arguments pushing them onto the execution 3631 // Loop through the arguments pushing them onto the execution
3632 // stack. 3632 // stack.
3633 Label invoke, loop; 3633 Label invoke, loop;
3634 // length is a small non-negative integer, due to the test above. 3634 // length is a small non-negative integer, due to the test above.
3635 __ test(length, Operand(length)); 3635 __ test(length, Operand(length));
3636 __ j(zero, &invoke, Label::kNear); 3636 __ j(zero, &invoke, Label::kNear);
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3841 } 3841 }
3842 3842
3843 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3843 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3844 } 3844 }
3845 3845
3846 3846
3847 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3847 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3848 Register input_reg = ToRegister(instr->value()); 3848 Register input_reg = ToRegister(instr->value());
3849 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3849 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3850 factory()->heap_number_map()); 3850 factory()->heap_number_map());
3851 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); 3851 DeoptimizeIf(not_equal, instr, "not a heap number");
3852 3852
3853 Label slow, allocated, done; 3853 Label slow, allocated, done;
3854 Register tmp = input_reg.is(eax) ? ecx : eax; 3854 Register tmp = input_reg.is(eax) ? ecx : eax;
3855 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; 3855 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx;
3856 3856
3857 // Preserve the value of all registers. 3857 // Preserve the value of all registers.
3858 PushSafepointRegistersScope scope(this); 3858 PushSafepointRegistersScope scope(this);
3859 3859
3860 __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3860 __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
3861 // Check the sign of the argument. If the argument is positive, just 3861 // Check the sign of the argument. If the argument is positive, just
(...skipping 26 matching lines...) Expand all
3888 __ bind(&done); 3888 __ bind(&done);
3889 } 3889 }
3890 3890
3891 3891
3892 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3892 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3893 Register input_reg = ToRegister(instr->value()); 3893 Register input_reg = ToRegister(instr->value());
3894 __ test(input_reg, Operand(input_reg)); 3894 __ test(input_reg, Operand(input_reg));
3895 Label is_positive; 3895 Label is_positive;
3896 __ j(not_sign, &is_positive, Label::kNear); 3896 __ j(not_sign, &is_positive, Label::kNear);
3897 __ neg(input_reg); // Sets flags. 3897 __ neg(input_reg); // Sets flags.
3898 DeoptimizeIf(negative, instr, Deoptimizer::kOverflow); 3898 DeoptimizeIf(negative, instr, "overflow");
3899 __ bind(&is_positive); 3899 __ bind(&is_positive);
3900 } 3900 }
3901 3901
3902 3902
3903 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3903 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3904 // Class for deferred case. 3904 // Class for deferred case.
3905 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode { 3905 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode {
3906 public: 3906 public:
3907 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3907 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3908 LMathAbs* instr, 3908 LMathAbs* instr,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3941 void LCodeGen::DoMathFloor(LMathFloor* instr) { 3941 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3942 Register output_reg = ToRegister(instr->result()); 3942 Register output_reg = ToRegister(instr->result());
3943 X87Register input_reg = ToX87Register(instr->value()); 3943 X87Register input_reg = ToX87Register(instr->value());
3944 X87Fxch(input_reg); 3944 X87Fxch(input_reg);
3945 3945
3946 Label not_minus_zero, done; 3946 Label not_minus_zero, done;
3947 // Deoptimize on unordered. 3947 // Deoptimize on unordered.
3948 __ fldz(); 3948 __ fldz();
3949 __ fld(1); 3949 __ fld(1);
3950 __ FCmp(); 3950 __ FCmp();
3951 DeoptimizeIf(parity_even, instr, Deoptimizer::kNaN); 3951 DeoptimizeIf(parity_even, instr, "NaN");
3952 __ j(below, &not_minus_zero, Label::kNear); 3952 __ j(below, &not_minus_zero, Label::kNear);
3953 3953
3954 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3954 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3955 // Check for negative zero. 3955 // Check for negative zero.
3956 __ j(not_equal, &not_minus_zero, Label::kNear); 3956 __ j(not_equal, &not_minus_zero, Label::kNear);
3957 // +- 0.0. 3957 // +- 0.0.
3958 __ fld(0); 3958 __ fld(0);
3959 __ FXamSign(); 3959 __ FXamSign();
3960 DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); 3960 DeoptimizeIf(not_zero, instr, "minus zero");
3961 __ Move(output_reg, Immediate(0)); 3961 __ Move(output_reg, Immediate(0));
3962 __ jmp(&done, Label::kFar); 3962 __ jmp(&done, Label::kFar);
3963 } 3963 }
3964 3964
3965 // Positive input. 3965 // Positive input.
3966 // rc=01B, round down. 3966 // rc=01B, round down.
3967 __ bind(&not_minus_zero); 3967 __ bind(&not_minus_zero);
3968 __ fnclex(); 3968 __ fnclex();
3969 __ X87SetRC(0x0400); 3969 __ X87SetRC(0x0400);
3970 __ sub(esp, Immediate(kPointerSize)); 3970 __ sub(esp, Immediate(kPointerSize));
3971 __ fist_s(Operand(esp, 0)); 3971 __ fist_s(Operand(esp, 0));
3972 __ pop(output_reg); 3972 __ pop(output_reg);
3973 __ X87CheckIA(); 3973 __ X87CheckIA();
3974 DeoptimizeIf(equal, instr, Deoptimizer::kOverflow); 3974 DeoptimizeIf(equal, instr, "overflow");
3975 __ fnclex(); 3975 __ fnclex();
3976 __ X87SetRC(0x0000); 3976 __ X87SetRC(0x0000);
3977 __ bind(&done); 3977 __ bind(&done);
3978 } 3978 }
3979 3979
3980 3980
3981 void LCodeGen::DoMathRound(LMathRound* instr) { 3981 void LCodeGen::DoMathRound(LMathRound* instr) {
3982 X87Register input_reg = ToX87Register(instr->value()); 3982 X87Register input_reg = ToX87Register(instr->value());
3983 Register result = ToRegister(instr->result()); 3983 Register result = ToRegister(instr->result());
3984 X87Fxch(input_reg); 3984 X87Fxch(input_reg);
(...skipping 13 matching lines...) Expand all
3998 __ fadd_d(Operand::StaticVariable(one_half)); 3998 __ fadd_d(Operand::StaticVariable(one_half));
3999 // rc=11B, round toward zero. 3999 // rc=11B, round toward zero.
4000 __ X87SetRC(0x0c00); 4000 __ X87SetRC(0x0c00);
4001 __ sub(esp, Immediate(kPointerSize)); 4001 __ sub(esp, Immediate(kPointerSize));
4002 // Clear exception bits. 4002 // Clear exception bits.
4003 __ fnclex(); 4003 __ fnclex();
4004 __ fistp_s(MemOperand(esp, 0)); 4004 __ fistp_s(MemOperand(esp, 0));
4005 // Check overflow. 4005 // Check overflow.
4006 __ X87CheckIA(); 4006 __ X87CheckIA();
4007 __ pop(result); 4007 __ pop(result);
4008 DeoptimizeIf(equal, instr, Deoptimizer::kConversionOverflow); 4008 DeoptimizeIf(equal, instr, "conversion overflow");
4009 __ fnclex(); 4009 __ fnclex();
4010 // Restore round mode. 4010 // Restore round mode.
4011 __ X87SetRC(0x0000); 4011 __ X87SetRC(0x0000);
4012 __ jmp(&done); 4012 __ jmp(&done);
4013 4013
4014 __ bind(&below_one_half); 4014 __ bind(&below_one_half);
4015 __ fld_d(Operand::StaticVariable(minus_one_half)); 4015 __ fld_d(Operand::StaticVariable(minus_one_half));
4016 __ fld(1); 4016 __ fld(1);
4017 __ FCmp(); 4017 __ FCmp();
4018 __ j(carry, &below_minus_one_half); 4018 __ j(carry, &below_minus_one_half);
4019 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 4019 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
4020 // we can ignore the difference between a result of -0 and +0. 4020 // we can ignore the difference between a result of -0 and +0.
4021 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4021 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4022 // If the sign is positive, we return +0. 4022 // If the sign is positive, we return +0.
4023 __ fld(0); 4023 __ fld(0);
4024 __ FXamSign(); 4024 __ FXamSign();
4025 DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); 4025 DeoptimizeIf(not_zero, instr, "minus zero");
4026 } 4026 }
4027 __ Move(result, Immediate(0)); 4027 __ Move(result, Immediate(0));
4028 __ jmp(&done); 4028 __ jmp(&done);
4029 4029
4030 __ bind(&below_minus_one_half); 4030 __ bind(&below_minus_one_half);
4031 __ fld(0); 4031 __ fld(0);
4032 __ fadd_d(Operand::StaticVariable(one_half)); 4032 __ fadd_d(Operand::StaticVariable(one_half));
4033 // rc=01B, round down. 4033 // rc=01B, round down.
4034 __ X87SetRC(0x0400); 4034 __ X87SetRC(0x0400);
4035 __ sub(esp, Immediate(kPointerSize)); 4035 __ sub(esp, Immediate(kPointerSize));
4036 // Clear exception bits. 4036 // Clear exception bits.
4037 __ fnclex(); 4037 __ fnclex();
4038 __ fistp_s(MemOperand(esp, 0)); 4038 __ fistp_s(MemOperand(esp, 0));
4039 // Check overflow. 4039 // Check overflow.
4040 __ X87CheckIA(); 4040 __ X87CheckIA();
4041 __ pop(result); 4041 __ pop(result);
4042 DeoptimizeIf(equal, instr, Deoptimizer::kConversionOverflow); 4042 DeoptimizeIf(equal, instr, "conversion overflow");
4043 __ fnclex(); 4043 __ fnclex();
4044 // Restore round mode. 4044 // Restore round mode.
4045 __ X87SetRC(0x0000); 4045 __ X87SetRC(0x0000);
4046 4046
4047 __ bind(&done); 4047 __ bind(&done);
4048 } 4048 }
4049 4049
4050 4050
4051 void LCodeGen::DoMathFround(LMathFround* instr) { 4051 void LCodeGen::DoMathFround(LMathFround* instr) {
4052 X87Register input_reg = ToX87Register(instr->value()); 4052 X87Register input_reg = ToX87Register(instr->value());
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
4164 __ push(exponent); 4164 __ push(exponent);
4165 __ fild_s(MemOperand(esp, 0)); 4165 __ fild_s(MemOperand(esp, 0));
4166 __ pop(exponent); 4166 __ pop(exponent);
4167 } else if (exponent_type.IsTagged()) { 4167 } else if (exponent_type.IsTagged()) {
4168 Register exponent = ToRegister(instr->right()); 4168 Register exponent = ToRegister(instr->right());
4169 Register temp = exponent.is(ecx) ? eax : ecx; 4169 Register temp = exponent.is(ecx) ? eax : ecx;
4170 Label no_deopt, done; 4170 Label no_deopt, done;
4171 X87LoadForUsage(base); 4171 X87LoadForUsage(base);
4172 __ JumpIfSmi(exponent, &no_deopt); 4172 __ JumpIfSmi(exponent, &no_deopt);
4173 __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, temp); 4173 __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, temp);
4174 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); 4174 DeoptimizeIf(not_equal, instr, "not a heap number");
4175 // Heap number(double) 4175 // Heap number(double)
4176 __ fld_d(FieldOperand(exponent, HeapNumber::kValueOffset)); 4176 __ fld_d(FieldOperand(exponent, HeapNumber::kValueOffset));
4177 __ jmp(&done); 4177 __ jmp(&done);
4178 // SMI 4178 // SMI
4179 __ bind(&no_deopt); 4179 __ bind(&no_deopt);
4180 __ SmiUntag(exponent); 4180 __ SmiUntag(exponent);
4181 __ push(exponent); 4181 __ push(exponent);
4182 __ fild_s(MemOperand(esp, 0)); 4182 __ fild_s(MemOperand(esp, 0));
4183 __ pop(exponent); 4183 __ pop(exponent);
4184 __ bind(&done); 4184 __ bind(&done);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
4565 instr->hydrogen()->index()->representation())); 4565 instr->hydrogen()->index()->representation()));
4566 } else { 4566 } else {
4567 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 4567 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4568 } 4568 }
4569 if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4569 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4570 Label done; 4570 Label done;
4571 __ j(NegateCondition(cc), &done, Label::kNear); 4571 __ j(NegateCondition(cc), &done, Label::kNear);
4572 __ int3(); 4572 __ int3();
4573 __ bind(&done); 4573 __ bind(&done);
4574 } else { 4574 } else {
4575 DeoptimizeIf(cc, instr, Deoptimizer::kOutOfBounds); 4575 DeoptimizeIf(cc, instr, "out of bounds");
4576 } 4576 }
4577 } 4577 }
4578 4578
4579 4579
4580 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4580 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4581 ElementsKind elements_kind = instr->elements_kind(); 4581 ElementsKind elements_kind = instr->elements_kind();
4582 LOperand* key = instr->key(); 4582 LOperand* key = instr->key();
4583 if (!key->IsConstantOperand() && 4583 if (!key->IsConstantOperand() &&
4584 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 4584 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
4585 elements_kind)) { 4585 elements_kind)) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
4758 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code(); 4758 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
4759 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4759 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4760 } 4760 }
4761 4761
4762 4762
4763 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4763 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4764 Register object = ToRegister(instr->object()); 4764 Register object = ToRegister(instr->object());
4765 Register temp = ToRegister(instr->temp()); 4765 Register temp = ToRegister(instr->temp());
4766 Label no_memento_found; 4766 Label no_memento_found;
4767 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 4767 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4768 DeoptimizeIf(equal, instr, Deoptimizer::kMementoFound); 4768 DeoptimizeIf(equal, instr, "memento found");
4769 __ bind(&no_memento_found); 4769 __ bind(&no_memento_found);
4770 } 4770 }
4771 4771
4772 4772
4773 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4773 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4774 Register object_reg = ToRegister(instr->object()); 4774 Register object_reg = ToRegister(instr->object());
4775 4775
4776 Handle<Map> from_map = instr->original_map(); 4776 Handle<Map> from_map = instr->original_map();
4777 Handle<Map> to_map = instr->transitioned_map(); 4777 Handle<Map> to_map = instr->transitioned_map();
4778 ElementsKind from_kind = instr->from_kind(); 4778 ElementsKind from_kind = instr->from_kind();
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
5130 __ StoreToSafepointRegisterSlot(reg, eax); 5130 __ StoreToSafepointRegisterSlot(reg, eax);
5131 } 5131 }
5132 5132
5133 5133
5134 void LCodeGen::DoSmiTag(LSmiTag* instr) { 5134 void LCodeGen::DoSmiTag(LSmiTag* instr) {
5135 HChange* hchange = instr->hydrogen(); 5135 HChange* hchange = instr->hydrogen();
5136 Register input = ToRegister(instr->value()); 5136 Register input = ToRegister(instr->value());
5137 if (hchange->CheckFlag(HValue::kCanOverflow) && 5137 if (hchange->CheckFlag(HValue::kCanOverflow) &&
5138 hchange->value()->CheckFlag(HValue::kUint32)) { 5138 hchange->value()->CheckFlag(HValue::kUint32)) {
5139 __ test(input, Immediate(0xc0000000)); 5139 __ test(input, Immediate(0xc0000000));
5140 DeoptimizeIf(not_zero, instr, Deoptimizer::kOverflow); 5140 DeoptimizeIf(not_zero, instr, "overflow");
5141 } 5141 }
5142 __ SmiTag(input); 5142 __ SmiTag(input);
5143 if (hchange->CheckFlag(HValue::kCanOverflow) && 5143 if (hchange->CheckFlag(HValue::kCanOverflow) &&
5144 !hchange->value()->CheckFlag(HValue::kUint32)) { 5144 !hchange->value()->CheckFlag(HValue::kUint32)) {
5145 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 5145 DeoptimizeIf(overflow, instr, "overflow");
5146 } 5146 }
5147 } 5147 }
5148 5148
5149 5149
5150 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 5150 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
5151 LOperand* input = instr->value(); 5151 LOperand* input = instr->value();
5152 Register result = ToRegister(input); 5152 Register result = ToRegister(input);
5153 DCHECK(input->IsRegister() && input->Equals(instr->result())); 5153 DCHECK(input->IsRegister() && input->Equals(instr->result()));
5154 if (instr->needs_check()) { 5154 if (instr->needs_check()) {
5155 __ test(result, Immediate(kSmiTagMask)); 5155 __ test(result, Immediate(kSmiTagMask));
5156 DeoptimizeIf(not_zero, instr, Deoptimizer::kNotASmi); 5156 DeoptimizeIf(not_zero, instr, "not a Smi");
5157 } else { 5157 } else {
5158 __ AssertSmi(result); 5158 __ AssertSmi(result);
5159 } 5159 }
5160 __ SmiUntag(result); 5160 __ SmiUntag(result);
5161 } 5161 }
5162 5162
5163 5163
5164 void LCodeGen::EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input_reg, 5164 void LCodeGen::EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input_reg,
5165 Register temp_reg, X87Register res_reg, 5165 Register temp_reg, X87Register res_reg,
5166 NumberUntagDMode mode) { 5166 NumberUntagDMode mode) {
5167 bool can_convert_undefined_to_nan = 5167 bool can_convert_undefined_to_nan =
5168 instr->hydrogen()->can_convert_undefined_to_nan(); 5168 instr->hydrogen()->can_convert_undefined_to_nan();
5169 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero(); 5169 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
5170 5170
5171 Label load_smi, done; 5171 Label load_smi, done;
5172 5172
5173 X87PrepareToWrite(res_reg); 5173 X87PrepareToWrite(res_reg);
5174 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 5174 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
5175 // Smi check. 5175 // Smi check.
5176 __ JumpIfSmi(input_reg, &load_smi); 5176 __ JumpIfSmi(input_reg, &load_smi);
5177 5177
5178 // Heap number map check. 5178 // Heap number map check.
5179 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5179 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5180 factory()->heap_number_map()); 5180 factory()->heap_number_map());
5181 if (!can_convert_undefined_to_nan) { 5181 if (!can_convert_undefined_to_nan) {
5182 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); 5182 DeoptimizeIf(not_equal, instr, "not a heap number");
5183 } else { 5183 } else {
5184 Label heap_number, convert; 5184 Label heap_number, convert;
5185 __ j(equal, &heap_number); 5185 __ j(equal, &heap_number);
5186 5186
5187 // Convert undefined (or hole) to NaN. 5187 // Convert undefined (or hole) to NaN.
5188 __ cmp(input_reg, factory()->undefined_value()); 5188 __ cmp(input_reg, factory()->undefined_value());
5189 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined); 5189 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
5190 5190
5191 __ bind(&convert); 5191 __ bind(&convert);
5192 ExternalReference nan = 5192 ExternalReference nan =
5193 ExternalReference::address_of_canonical_non_hole_nan(); 5193 ExternalReference::address_of_canonical_non_hole_nan();
5194 __ fld_d(Operand::StaticVariable(nan)); 5194 __ fld_d(Operand::StaticVariable(nan));
5195 __ jmp(&done, Label::kNear); 5195 __ jmp(&done, Label::kNear);
5196 5196
5197 __ bind(&heap_number); 5197 __ bind(&heap_number);
5198 } 5198 }
5199 // Heap number to x87 conversion. 5199 // Heap number to x87 conversion.
5200 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5200 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5201 if (deoptimize_on_minus_zero) { 5201 if (deoptimize_on_minus_zero) {
5202 __ fldz(); 5202 __ fldz();
5203 __ FCmp(); 5203 __ FCmp();
5204 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5204 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5205 __ j(not_zero, &done, Label::kNear); 5205 __ j(not_zero, &done, Label::kNear);
5206 5206
5207 // Use general purpose registers to check if we have -0.0 5207 // Use general purpose registers to check if we have -0.0
5208 __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5208 __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
5209 __ test(temp_reg, Immediate(HeapNumber::kSignMask)); 5209 __ test(temp_reg, Immediate(HeapNumber::kSignMask));
5210 __ j(zero, &done, Label::kNear); 5210 __ j(zero, &done, Label::kNear);
5211 5211
5212 // Pop FPU stack before deoptimizing. 5212 // Pop FPU stack before deoptimizing.
5213 __ fstp(0); 5213 __ fstp(0);
5214 DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); 5214 DeoptimizeIf(not_zero, instr, "minus zero");
5215 } 5215 }
5216 __ jmp(&done, Label::kNear); 5216 __ jmp(&done, Label::kNear);
5217 } else { 5217 } else {
5218 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 5218 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI);
5219 } 5219 }
5220 5220
5221 __ bind(&load_smi); 5221 __ bind(&load_smi);
5222 // Clobbering a temp is faster than re-tagging the 5222 // Clobbering a temp is faster than re-tagging the
5223 // input register since we avoid dependencies. 5223 // input register since we avoid dependencies.
5224 __ mov(temp_reg, input_reg); 5224 __ mov(temp_reg, input_reg);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5257 __ jmp(done); 5257 __ jmp(done);
5258 5258
5259 __ bind(&check_bools); 5259 __ bind(&check_bools);
5260 __ cmp(input_reg, factory()->true_value()); 5260 __ cmp(input_reg, factory()->true_value());
5261 __ j(not_equal, &check_false, Label::kNear); 5261 __ j(not_equal, &check_false, Label::kNear);
5262 __ Move(input_reg, Immediate(1)); 5262 __ Move(input_reg, Immediate(1));
5263 __ jmp(done); 5263 __ jmp(done);
5264 5264
5265 __ bind(&check_false); 5265 __ bind(&check_false);
5266 __ cmp(input_reg, factory()->false_value()); 5266 __ cmp(input_reg, factory()->false_value());
5267 DeoptimizeIf(not_equal, instr, 5267 DeoptimizeIf(not_equal, instr, "not a heap number/undefined/true/false");
5268 Deoptimizer::kNotAHeapNumberUndefinedTrueFalse);
5269 __ Move(input_reg, Immediate(0)); 5268 __ Move(input_reg, Immediate(0));
5270 } else { 5269 } else {
5271 // TODO(olivf) Converting a number on the fpu is actually quite slow. We 5270 // TODO(olivf) Converting a number on the fpu is actually quite slow. We
5272 // should first try a fast conversion and then bailout to this slow case. 5271 // should first try a fast conversion and then bailout to this slow case.
5273 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5272 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5274 isolate()->factory()->heap_number_map()); 5273 isolate()->factory()->heap_number_map());
5275 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); 5274 DeoptimizeIf(not_equal, instr, "not a heap number");
5276 5275
5277 __ sub(esp, Immediate(kPointerSize)); 5276 __ sub(esp, Immediate(kPointerSize));
5278 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5277 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5279 5278
5280 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { 5279 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
5281 Label no_precision_lost, not_nan, zero_check; 5280 Label no_precision_lost, not_nan, zero_check;
5282 __ fld(0); 5281 __ fld(0);
5283 5282
5284 __ fist_s(MemOperand(esp, 0)); 5283 __ fist_s(MemOperand(esp, 0));
5285 __ fild_s(MemOperand(esp, 0)); 5284 __ fild_s(MemOperand(esp, 0));
5286 __ FCmp(); 5285 __ FCmp();
5287 __ pop(input_reg); 5286 __ pop(input_reg);
5288 5287
5289 __ j(equal, &no_precision_lost, Label::kNear); 5288 __ j(equal, &no_precision_lost, Label::kNear);
5290 __ fstp(0); 5289 __ fstp(0);
5291 DeoptimizeIf(no_condition, instr, Deoptimizer::kLostPrecision); 5290 DeoptimizeIf(no_condition, instr, "lost precision");
5292 __ bind(&no_precision_lost); 5291 __ bind(&no_precision_lost);
5293 5292
5294 __ j(parity_odd, &not_nan); 5293 __ j(parity_odd, &not_nan);
5295 __ fstp(0); 5294 __ fstp(0);
5296 DeoptimizeIf(no_condition, instr, Deoptimizer::kNaN); 5295 DeoptimizeIf(no_condition, instr, "NaN");
5297 __ bind(&not_nan); 5296 __ bind(&not_nan);
5298 5297
5299 __ test(input_reg, Operand(input_reg)); 5298 __ test(input_reg, Operand(input_reg));
5300 __ j(zero, &zero_check, Label::kNear); 5299 __ j(zero, &zero_check, Label::kNear);
5301 __ fstp(0); 5300 __ fstp(0);
5302 __ jmp(done); 5301 __ jmp(done);
5303 5302
5304 __ bind(&zero_check); 5303 __ bind(&zero_check);
5305 // To check for minus zero, we load the value again as float, and check 5304 // To check for minus zero, we load the value again as float, and check
5306 // if that is still 0. 5305 // if that is still 0.
5307 __ sub(esp, Immediate(kPointerSize)); 5306 __ sub(esp, Immediate(kPointerSize));
5308 __ fstp_s(Operand(esp, 0)); 5307 __ fstp_s(Operand(esp, 0));
5309 __ pop(input_reg); 5308 __ pop(input_reg);
5310 __ test(input_reg, Operand(input_reg)); 5309 __ test(input_reg, Operand(input_reg));
5311 DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); 5310 DeoptimizeIf(not_zero, instr, "minus zero");
5312 } else { 5311 } else {
5313 __ fist_s(MemOperand(esp, 0)); 5312 __ fist_s(MemOperand(esp, 0));
5314 __ fild_s(MemOperand(esp, 0)); 5313 __ fild_s(MemOperand(esp, 0));
5315 __ FCmp(); 5314 __ FCmp();
5316 __ pop(input_reg); 5315 __ pop(input_reg);
5317 DeoptimizeIf(not_equal, instr, Deoptimizer::kLostPrecision); 5316 DeoptimizeIf(not_equal, instr, "lost precision");
5318 DeoptimizeIf(parity_even, instr, Deoptimizer::kNaN); 5317 DeoptimizeIf(parity_even, instr, "NaN");
5319 } 5318 }
5320 } 5319 }
5321 } 5320 }
5322 5321
5323 5322
5324 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 5323 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5325 class DeferredTaggedToI FINAL : public LDeferredCode { 5324 class DeferredTaggedToI FINAL : public LDeferredCode {
5326 public: 5325 public:
5327 DeferredTaggedToI(LCodeGen* codegen, 5326 DeferredTaggedToI(LCodeGen* codegen,
5328 LTaggedToI* instr, 5327 LTaggedToI* instr,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
5389 X87Fxch(input_reg); 5388 X87Fxch(input_reg);
5390 __ TruncateX87TOSToI(result_reg); 5389 __ TruncateX87TOSToI(result_reg);
5391 } else { 5390 } else {
5392 Label lost_precision, is_nan, minus_zero, done; 5391 Label lost_precision, is_nan, minus_zero, done;
5393 X87Register input_reg = ToX87Register(input); 5392 X87Register input_reg = ToX87Register(input);
5394 X87Fxch(input_reg); 5393 X87Fxch(input_reg);
5395 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 5394 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5396 &lost_precision, &is_nan, &minus_zero); 5395 &lost_precision, &is_nan, &minus_zero);
5397 __ jmp(&done); 5396 __ jmp(&done);
5398 __ bind(&lost_precision); 5397 __ bind(&lost_precision);
5399 DeoptimizeIf(no_condition, instr, Deoptimizer::kLostPrecision); 5398 DeoptimizeIf(no_condition, instr, "lost precision");
5400 __ bind(&is_nan); 5399 __ bind(&is_nan);
5401 DeoptimizeIf(no_condition, instr, Deoptimizer::kNaN); 5400 DeoptimizeIf(no_condition, instr, "NaN");
5402 __ bind(&minus_zero); 5401 __ bind(&minus_zero);
5403 DeoptimizeIf(no_condition, instr, Deoptimizer::kMinusZero); 5402 DeoptimizeIf(no_condition, instr, "minus zero");
5404 __ bind(&done); 5403 __ bind(&done);
5405 } 5404 }
5406 } 5405 }
5407 5406
5408 5407
5409 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5408 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5410 LOperand* input = instr->value(); 5409 LOperand* input = instr->value();
5411 DCHECK(input->IsDoubleRegister()); 5410 DCHECK(input->IsDoubleRegister());
5412 LOperand* result = instr->result(); 5411 LOperand* result = instr->result();
5413 DCHECK(result->IsRegister()); 5412 DCHECK(result->IsRegister());
5414 Register result_reg = ToRegister(result); 5413 Register result_reg = ToRegister(result);
5415 5414
5416 Label lost_precision, is_nan, minus_zero, done; 5415 Label lost_precision, is_nan, minus_zero, done;
5417 X87Register input_reg = ToX87Register(input); 5416 X87Register input_reg = ToX87Register(input);
5418 X87Fxch(input_reg); 5417 X87Fxch(input_reg);
5419 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 5418 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5420 &lost_precision, &is_nan, &minus_zero); 5419 &lost_precision, &is_nan, &minus_zero);
5421 __ jmp(&done); 5420 __ jmp(&done);
5422 __ bind(&lost_precision); 5421 __ bind(&lost_precision);
5423 DeoptimizeIf(no_condition, instr, Deoptimizer::kLostPrecision); 5422 DeoptimizeIf(no_condition, instr, "lost precision");
5424 __ bind(&is_nan); 5423 __ bind(&is_nan);
5425 DeoptimizeIf(no_condition, instr, Deoptimizer::kNaN); 5424 DeoptimizeIf(no_condition, instr, "NaN");
5426 __ bind(&minus_zero); 5425 __ bind(&minus_zero);
5427 DeoptimizeIf(no_condition, instr, Deoptimizer::kMinusZero); 5426 DeoptimizeIf(no_condition, instr, "minus zero");
5428 __ bind(&done); 5427 __ bind(&done);
5429 __ SmiTag(result_reg); 5428 __ SmiTag(result_reg);
5430 DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); 5429 DeoptimizeIf(overflow, instr, "overflow");
5431 } 5430 }
5432 5431
5433 5432
5434 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5433 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5435 LOperand* input = instr->value(); 5434 LOperand* input = instr->value();
5436 __ test(ToOperand(input), Immediate(kSmiTagMask)); 5435 __ test(ToOperand(input), Immediate(kSmiTagMask));
5437 DeoptimizeIf(not_zero, instr, Deoptimizer::kNotASmi); 5436 DeoptimizeIf(not_zero, instr, "not a Smi");
5438 } 5437 }
5439 5438
5440 5439
5441 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5440 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5442 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 5441 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5443 LOperand* input = instr->value(); 5442 LOperand* input = instr->value();
5444 __ test(ToOperand(input), Immediate(kSmiTagMask)); 5443 __ test(ToOperand(input), Immediate(kSmiTagMask));
5445 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); 5444 DeoptimizeIf(zero, instr, "Smi");
5446 } 5445 }
5447 } 5446 }
5448 5447
5449 5448
5450 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5449 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5451 Register input = ToRegister(instr->value()); 5450 Register input = ToRegister(instr->value());
5452 Register temp = ToRegister(instr->temp()); 5451 Register temp = ToRegister(instr->temp());
5453 5452
5454 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 5453 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
5455 5454
5456 if (instr->hydrogen()->is_interval_check()) { 5455 if (instr->hydrogen()->is_interval_check()) {
5457 InstanceType first; 5456 InstanceType first;
5458 InstanceType last; 5457 InstanceType last;
5459 instr->hydrogen()->GetCheckInterval(&first, &last); 5458 instr->hydrogen()->GetCheckInterval(&first, &last);
5460 5459
5461 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 5460 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
5462 static_cast<int8_t>(first)); 5461 static_cast<int8_t>(first));
5463 5462
5464 // If there is only one type in the interval check for equality. 5463 // If there is only one type in the interval check for equality.
5465 if (first == last) { 5464 if (first == last) {
5466 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongInstanceType); 5465 DeoptimizeIf(not_equal, instr, "wrong instance type");
5467 } else { 5466 } else {
5468 DeoptimizeIf(below, instr, Deoptimizer::kWrongInstanceType); 5467 DeoptimizeIf(below, instr, "wrong instance type");
5469 // Omit check for the last type. 5468 // Omit check for the last type.
5470 if (last != LAST_TYPE) { 5469 if (last != LAST_TYPE) {
5471 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 5470 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
5472 static_cast<int8_t>(last)); 5471 static_cast<int8_t>(last));
5473 DeoptimizeIf(above, instr, Deoptimizer::kWrongInstanceType); 5472 DeoptimizeIf(above, instr, "wrong instance type");
5474 } 5473 }
5475 } 5474 }
5476 } else { 5475 } else {
5477 uint8_t mask; 5476 uint8_t mask;
5478 uint8_t tag; 5477 uint8_t tag;
5479 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 5478 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5480 5479
5481 if (base::bits::IsPowerOfTwo32(mask)) { 5480 if (base::bits::IsPowerOfTwo32(mask)) {
5482 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); 5481 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
5483 __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask); 5482 __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask);
5484 DeoptimizeIf(tag == 0 ? not_zero : zero, instr, 5483 DeoptimizeIf(tag == 0 ? not_zero : zero, instr, "wrong instance type");
5485 Deoptimizer::kWrongInstanceType);
5486 } else { 5484 } else {
5487 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); 5485 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
5488 __ and_(temp, mask); 5486 __ and_(temp, mask);
5489 __ cmp(temp, tag); 5487 __ cmp(temp, tag);
5490 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongInstanceType); 5488 DeoptimizeIf(not_equal, instr, "wrong instance type");
5491 } 5489 }
5492 } 5490 }
5493 } 5491 }
5494 5492
5495 5493
5496 void LCodeGen::DoCheckValue(LCheckValue* instr) { 5494 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5497 Handle<HeapObject> object = instr->hydrogen()->object().handle(); 5495 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5498 if (instr->hydrogen()->object_in_new_space()) { 5496 if (instr->hydrogen()->object_in_new_space()) {
5499 Register reg = ToRegister(instr->value()); 5497 Register reg = ToRegister(instr->value());
5500 Handle<Cell> cell = isolate()->factory()->NewCell(object); 5498 Handle<Cell> cell = isolate()->factory()->NewCell(object);
5501 __ cmp(reg, Operand::ForCell(cell)); 5499 __ cmp(reg, Operand::ForCell(cell));
5502 } else { 5500 } else {
5503 Operand operand = ToOperand(instr->value()); 5501 Operand operand = ToOperand(instr->value());
5504 __ cmp(operand, object); 5502 __ cmp(operand, object);
5505 } 5503 }
5506 DeoptimizeIf(not_equal, instr, Deoptimizer::kValueMismatch); 5504 DeoptimizeIf(not_equal, instr, "value mismatch");
5507 } 5505 }
5508 5506
5509 5507
5510 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5508 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5511 { 5509 {
5512 PushSafepointRegistersScope scope(this); 5510 PushSafepointRegistersScope scope(this);
5513 __ push(object); 5511 __ push(object);
5514 __ xor_(esi, esi); 5512 __ xor_(esi, esi);
5515 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5513 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
5516 RecordSafepointWithRegisters( 5514 RecordSafepointWithRegisters(
5517 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5515 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5518 5516
5519 __ test(eax, Immediate(kSmiTagMask)); 5517 __ test(eax, Immediate(kSmiTagMask));
5520 } 5518 }
5521 DeoptimizeIf(zero, instr, Deoptimizer::kInstanceMigrationFailed); 5519 DeoptimizeIf(zero, instr, "instance migration failed");
5522 } 5520 }
5523 5521
5524 5522
5525 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5523 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5526 class DeferredCheckMaps FINAL : public LDeferredCode { 5524 class DeferredCheckMaps FINAL : public LDeferredCode {
5527 public: 5525 public:
5528 DeferredCheckMaps(LCodeGen* codegen, 5526 DeferredCheckMaps(LCodeGen* codegen,
5529 LCheckMaps* instr, 5527 LCheckMaps* instr,
5530 Register object, 5528 Register object,
5531 const X87Stack& x87_stack) 5529 const X87Stack& x87_stack)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5568 Handle<Map> map = maps->at(i).handle(); 5566 Handle<Map> map = maps->at(i).handle();
5569 __ CompareMap(reg, map); 5567 __ CompareMap(reg, map);
5570 __ j(equal, &success, Label::kNear); 5568 __ j(equal, &success, Label::kNear);
5571 } 5569 }
5572 5570
5573 Handle<Map> map = maps->at(maps->size() - 1).handle(); 5571 Handle<Map> map = maps->at(maps->size() - 1).handle();
5574 __ CompareMap(reg, map); 5572 __ CompareMap(reg, map);
5575 if (instr->hydrogen()->HasMigrationTarget()) { 5573 if (instr->hydrogen()->HasMigrationTarget()) {
5576 __ j(not_equal, deferred->entry()); 5574 __ j(not_equal, deferred->entry());
5577 } else { 5575 } else {
5578 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); 5576 DeoptimizeIf(not_equal, instr, "wrong map");
5579 } 5577 }
5580 5578
5581 __ bind(&success); 5579 __ bind(&success);
5582 } 5580 }
5583 5581
5584 5582
5585 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5583 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5586 X87Register value_reg = ToX87Register(instr->unclamped()); 5584 X87Register value_reg = ToX87Register(instr->unclamped());
5587 Register result_reg = ToRegister(instr->result()); 5585 Register result_reg = ToRegister(instr->result());
5588 X87Fxch(value_reg); 5586 X87Fxch(value_reg);
(...skipping 20 matching lines...) Expand all
5609 __ JumpIfSmi(input_reg, &is_smi); 5607 __ JumpIfSmi(input_reg, &is_smi);
5610 5608
5611 // Check for heap number 5609 // Check for heap number
5612 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5610 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5613 factory()->heap_number_map()); 5611 factory()->heap_number_map());
5614 __ j(equal, &heap_number, Label::kNear); 5612 __ j(equal, &heap_number, Label::kNear);
5615 5613
5616 // Check for undefined. Undefined is converted to zero for clamping 5614 // Check for undefined. Undefined is converted to zero for clamping
5617 // conversions. 5615 // conversions.
5618 __ cmp(input_reg, factory()->undefined_value()); 5616 __ cmp(input_reg, factory()->undefined_value());
5619 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined); 5617 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
5620 __ jmp(&zero_result, Label::kNear); 5618 __ jmp(&zero_result, Label::kNear);
5621 5619
5622 // Heap number 5620 // Heap number
5623 __ bind(&heap_number); 5621 __ bind(&heap_number);
5624 5622
5625 // Surprisingly, all of the hand-crafted bit-manipulations below are much 5623 // Surprisingly, all of the hand-crafted bit-manipulations below are much
5626 // faster than the x86 FPU built-in instruction, especially since "banker's 5624 // faster than the x86 FPU built-in instruction, especially since "banker's
5627 // rounding" would be additionally very expensive 5625 // rounding" would be additionally very expensive
5628 5626
5629 // Get exponent word. 5627 // Get exponent word.
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
6180 DCHECK(!environment->HasBeenRegistered()); 6178 DCHECK(!environment->HasBeenRegistered());
6181 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 6179 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
6182 6180
6183 GenerateOsrPrologue(); 6181 GenerateOsrPrologue();
6184 } 6182 }
6185 6183
6186 6184
6187 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 6185 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
6188 DCHECK(ToRegister(instr->context()).is(esi)); 6186 DCHECK(ToRegister(instr->context()).is(esi));
6189 __ cmp(eax, isolate()->factory()->undefined_value()); 6187 __ cmp(eax, isolate()->factory()->undefined_value());
6190 DeoptimizeIf(equal, instr, Deoptimizer::kUndefined); 6188 DeoptimizeIf(equal, instr, "undefined");
6191 6189
6192 __ cmp(eax, isolate()->factory()->null_value()); 6190 __ cmp(eax, isolate()->factory()->null_value());
6193 DeoptimizeIf(equal, instr, Deoptimizer::kNull); 6191 DeoptimizeIf(equal, instr, "null");
6194 6192
6195 __ test(eax, Immediate(kSmiTagMask)); 6193 __ test(eax, Immediate(kSmiTagMask));
6196 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); 6194 DeoptimizeIf(zero, instr, "Smi");
6197 6195
6198 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 6196 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
6199 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); 6197 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx);
6200 DeoptimizeIf(below_equal, instr, Deoptimizer::kWrongInstanceType); 6198 DeoptimizeIf(below_equal, instr, "wrong instance type");
6201 6199
6202 Label use_cache, call_runtime; 6200 Label use_cache, call_runtime;
6203 __ CheckEnumCache(&call_runtime); 6201 __ CheckEnumCache(&call_runtime);
6204 6202
6205 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 6203 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
6206 __ jmp(&use_cache, Label::kNear); 6204 __ jmp(&use_cache, Label::kNear);
6207 6205
6208 // Get the set of properties to enumerate. 6206 // Get the set of properties to enumerate.
6209 __ bind(&call_runtime); 6207 __ bind(&call_runtime);
6210 __ push(eax); 6208 __ push(eax);
6211 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 6209 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
6212 6210
6213 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 6211 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
6214 isolate()->factory()->meta_map()); 6212 isolate()->factory()->meta_map());
6215 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); 6213 DeoptimizeIf(not_equal, instr, "wrong map");
6216 __ bind(&use_cache); 6214 __ bind(&use_cache);
6217 } 6215 }
6218 6216
6219 6217
6220 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 6218 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
6221 Register map = ToRegister(instr->map()); 6219 Register map = ToRegister(instr->map());
6222 Register result = ToRegister(instr->result()); 6220 Register result = ToRegister(instr->result());
6223 Label load_cache, done; 6221 Label load_cache, done;
6224 __ EnumLength(result, map); 6222 __ EnumLength(result, map);
6225 __ cmp(result, Immediate(Smi::FromInt(0))); 6223 __ cmp(result, Immediate(Smi::FromInt(0)));
6226 __ j(not_equal, &load_cache, Label::kNear); 6224 __ j(not_equal, &load_cache, Label::kNear);
6227 __ mov(result, isolate()->factory()->empty_fixed_array()); 6225 __ mov(result, isolate()->factory()->empty_fixed_array());
6228 __ jmp(&done, Label::kNear); 6226 __ jmp(&done, Label::kNear);
6229 6227
6230 __ bind(&load_cache); 6228 __ bind(&load_cache);
6231 __ LoadInstanceDescriptors(map, result); 6229 __ LoadInstanceDescriptors(map, result);
6232 __ mov(result, 6230 __ mov(result,
6233 FieldOperand(result, DescriptorArray::kEnumCacheOffset)); 6231 FieldOperand(result, DescriptorArray::kEnumCacheOffset));
6234 __ mov(result, 6232 __ mov(result,
6235 FieldOperand(result, FixedArray::SizeFor(instr->idx()))); 6233 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
6236 __ bind(&done); 6234 __ bind(&done);
6237 __ test(result, result); 6235 __ test(result, result);
6238 DeoptimizeIf(equal, instr, Deoptimizer::kNoCache); 6236 DeoptimizeIf(equal, instr, "no cache");
6239 } 6237 }
6240 6238
6241 6239
6242 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 6240 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
6243 Register object = ToRegister(instr->value()); 6241 Register object = ToRegister(instr->value());
6244 __ cmp(ToRegister(instr->map()), 6242 __ cmp(ToRegister(instr->map()),
6245 FieldOperand(object, HeapObject::kMapOffset)); 6243 FieldOperand(object, HeapObject::kMapOffset));
6246 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); 6244 DeoptimizeIf(not_equal, instr, "wrong map");
6247 } 6245 }
6248 6246
6249 6247
6250 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 6248 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
6251 Register object, 6249 Register object,
6252 Register index) { 6250 Register index) {
6253 PushSafepointRegistersScope scope(this); 6251 PushSafepointRegistersScope scope(this);
6254 __ push(object); 6252 __ push(object);
6255 __ push(index); 6253 __ push(index);
6256 __ xor_(esi, esi); 6254 __ xor_(esi, esi);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
6332 CallRuntime(Runtime::kPushBlockContext, 2, instr); 6330 CallRuntime(Runtime::kPushBlockContext, 2, instr);
6333 RecordSafepoint(Safepoint::kNoLazyDeopt); 6331 RecordSafepoint(Safepoint::kNoLazyDeopt);
6334 } 6332 }
6335 6333
6336 6334
6337 #undef __ 6335 #undef __
6338 6336
6339 } } // namespace v8::internal 6337 } } // namespace v8::internal
6340 6338
6341 #endif // V8_TARGET_ARCH_X87 6339 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698