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

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

Issue 7237024: Refactor handling of test expressions in the graph builder. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 1360 __ j(cc, chunk_->GetAssemblyLabel(left_block));
1361 __ jmp(chunk_->GetAssemblyLabel(right_block)); 1361 __ jmp(chunk_->GetAssemblyLabel(right_block));
1362 } 1362 }
1363 } 1363 }
1364 1364
1365 1365
1366 void LCodeGen::DoBranch(LBranch* instr) { 1366 void LCodeGen::DoBranch(LBranch* instr) {
1367 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1367 int true_block = chunk_->LookupDestination(instr->true_block_id());
1368 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1368 int false_block = chunk_->LookupDestination(instr->false_block_id());
1369 1369
1370 Representation r = instr->hydrogen()->representation(); 1370 Representation r = instr->hydrogen()->value()->representation();
1371 if (r.IsInteger32()) { 1371 if (r.IsInteger32()) {
1372 Register reg = ToRegister(instr->InputAt(0)); 1372 Register reg = ToRegister(instr->InputAt(0));
1373 __ test(reg, Operand(reg)); 1373 __ test(reg, Operand(reg));
1374 EmitBranch(true_block, false_block, not_zero); 1374 EmitBranch(true_block, false_block, not_zero);
1375 } else if (r.IsDouble()) { 1375 } else if (r.IsDouble()) {
1376 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); 1376 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1377 __ xorps(xmm0, xmm0); 1377 __ xorps(xmm0, xmm0);
1378 __ ucomisd(reg, xmm0); 1378 __ ucomisd(reg, xmm0);
1379 EmitBranch(true_block, false_block, not_equal); 1379 EmitBranch(true_block, false_block, not_equal);
1380 } else { 1380 } else {
1381 ASSERT(r.IsTagged()); 1381 ASSERT(r.IsTagged());
1382 Register reg = ToRegister(instr->InputAt(0)); 1382 Register reg = ToRegister(instr->InputAt(0));
1383 if (instr->hydrogen()->type().IsBoolean()) { 1383 if (instr->hydrogen()->value()->type().IsBoolean()) {
1384 __ cmp(reg, factory()->true_value()); 1384 __ cmp(reg, factory()->true_value());
1385 EmitBranch(true_block, false_block, equal); 1385 EmitBranch(true_block, false_block, equal);
1386 } else { 1386 } else {
1387 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1387 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1388 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1388 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1389 1389
1390 __ cmp(reg, factory()->undefined_value()); 1390 __ cmp(reg, factory()->undefined_value());
1391 __ j(equal, false_label); 1391 __ j(equal, false_label);
1392 __ cmp(reg, factory()->true_value()); 1392 __ cmp(reg, factory()->true_value());
1393 __ j(equal, true_label); 1393 __ j(equal, true_label);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 1467
1468 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { 1468 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
1469 if (right->IsConstantOperand()) { 1469 if (right->IsConstantOperand()) {
1470 __ cmp(ToOperand(left), ToImmediate(right)); 1470 __ cmp(ToOperand(left), ToImmediate(right));
1471 } else { 1471 } else {
1472 __ cmp(ToRegister(left), ToOperand(right)); 1472 __ cmp(ToRegister(left), ToOperand(right));
1473 } 1473 }
1474 } 1474 }
1475 1475
1476 1476
1477 void LCodeGen::DoCmpID(LCmpID* instr) {
1478 LOperand* left = instr->InputAt(0);
1479 LOperand* right = instr->InputAt(1);
1480 LOperand* result = instr->result();
1481
1482 Label unordered;
1483 if (instr->is_double()) {
1484 // Don't base result on EFLAGS when a NaN is involved. Instead
1485 // jump to the unordered case, which produces a false value.
1486 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1487 __ j(parity_even, &unordered, Label::kNear);
1488 } else {
1489 EmitCmpI(left, right);
1490 }
1491
1492 Label done;
1493 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1494 __ mov(ToRegister(result), factory()->true_value());
1495 __ j(cc, &done, Label::kNear);
1496
1497 __ bind(&unordered);
1498 __ mov(ToRegister(result), factory()->false_value());
1499 __ bind(&done);
1500 }
1501
1502
1503 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1477 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1504 LOperand* left = instr->InputAt(0); 1478 LOperand* left = instr->InputAt(0);
1505 LOperand* right = instr->InputAt(1); 1479 LOperand* right = instr->InputAt(1);
1506 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1480 int false_block = chunk_->LookupDestination(instr->false_block_id());
1507 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1481 int true_block = chunk_->LookupDestination(instr->true_block_id());
1508 1482
1509 if (instr->is_double()) { 1483 if (instr->is_double()) {
1510 // Don't base result on EFLAGS when a NaN is involved. Instead 1484 // Don't base result on EFLAGS when a NaN is involved. Instead
1511 // jump to the false block. 1485 // jump to the false block.
1512 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1486 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1513 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 1487 __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
1514 } else { 1488 } else {
1515 EmitCmpI(left, right); 1489 EmitCmpI(left, right);
1516 } 1490 }
1517 1491
1518 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1492 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1519 EmitBranch(true_block, false_block, cc); 1493 EmitBranch(true_block, false_block, cc);
1520 } 1494 }
1521 1495
1522 1496
1523 void LCodeGen::DoCmpObjectEq(LCmpObjectEq* instr) {
1524 Register left = ToRegister(instr->InputAt(0));
1525 Register right = ToRegister(instr->InputAt(1));
1526 Register result = ToRegister(instr->result());
1527
1528 __ cmp(left, Operand(right));
1529 __ mov(result, factory()->true_value());
1530 Label done;
1531 __ j(equal, &done, Label::kNear);
1532 __ mov(result, factory()->false_value());
1533 __ bind(&done);
1534 }
1535
1536
1537 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1497 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1538 Register left = ToRegister(instr->InputAt(0)); 1498 Register left = ToRegister(instr->InputAt(0));
1539 Register right = ToRegister(instr->InputAt(1)); 1499 Register right = ToRegister(instr->InputAt(1));
1540 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1500 int false_block = chunk_->LookupDestination(instr->false_block_id());
1541 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1501 int true_block = chunk_->LookupDestination(instr->true_block_id());
1542 1502
1543 __ cmp(left, Operand(right)); 1503 __ cmp(left, Operand(right));
1544 EmitBranch(true_block, false_block, equal); 1504 EmitBranch(true_block, false_block, equal);
1545 } 1505 }
1546 1506
1547 1507
1548 void LCodeGen::DoCmpConstantEq(LCmpConstantEq* instr) {
1549 Register left = ToRegister(instr->InputAt(0));
1550 Register result = ToRegister(instr->result());
1551
1552 Label done;
1553 __ cmp(left, instr->hydrogen()->right());
1554 __ mov(result, factory()->true_value());
1555 __ j(equal, &done, Label::kNear);
1556 __ mov(result, factory()->false_value());
1557 __ bind(&done);
1558 }
1559
1560
1561 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1508 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1562 Register left = ToRegister(instr->InputAt(0)); 1509 Register left = ToRegister(instr->InputAt(0));
1563 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1510 int true_block = chunk_->LookupDestination(instr->true_block_id());
1564 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1511 int false_block = chunk_->LookupDestination(instr->false_block_id());
1565 1512
1566 __ cmp(left, instr->hydrogen()->right()); 1513 __ cmp(left, instr->hydrogen()->right());
1567 EmitBranch(true_block, false_block, equal); 1514 EmitBranch(true_block, false_block, equal);
1568 } 1515 }
1569 1516
1570 1517
1571 void LCodeGen::DoIsNull(LIsNull* instr) {
1572 Register reg = ToRegister(instr->InputAt(0));
1573 Register result = ToRegister(instr->result());
1574
1575 // TODO(fsc): If the expression is known to be a smi, then it's
1576 // definitely not null. Materialize false.
1577
1578 __ cmp(reg, factory()->null_value());
1579 if (instr->is_strict()) {
1580 __ mov(result, factory()->true_value());
1581 Label done;
1582 __ j(equal, &done, Label::kNear);
1583 __ mov(result, factory()->false_value());
1584 __ bind(&done);
1585 } else {
1586 Label true_value, false_value, done;
1587 __ j(equal, &true_value, Label::kNear);
1588 __ cmp(reg, factory()->undefined_value());
1589 __ j(equal, &true_value, Label::kNear);
1590 __ JumpIfSmi(reg, &false_value, Label::kNear);
1591 // Check for undetectable objects by looking in the bit field in
1592 // the map. The object has already been smi checked.
1593 Register scratch = result;
1594 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1595 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1596 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1597 __ j(not_zero, &true_value, Label::kNear);
1598 __ bind(&false_value);
1599 __ mov(result, factory()->false_value());
1600 __ jmp(&done, Label::kNear);
1601 __ bind(&true_value);
1602 __ mov(result, factory()->true_value());
1603 __ bind(&done);
1604 }
1605 }
1606
1607
1608 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1518 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1609 Register reg = ToRegister(instr->InputAt(0)); 1519 Register reg = ToRegister(instr->InputAt(0));
1610 1520
1611 // TODO(fsc): If the expression is known to be a smi, then it's 1521 // TODO(fsc): If the expression is known to be a smi, then it's
1612 // definitely not null. Jump to the false block. 1522 // definitely not null. Jump to the false block.
1613 1523
1614 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1524 int true_block = chunk_->LookupDestination(instr->true_block_id());
1615 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1525 int false_block = chunk_->LookupDestination(instr->false_block_id());
1616 1526
1617 __ cmp(reg, factory()->null_value()); 1527 __ cmp(reg, factory()->null_value());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 __ j(not_zero, is_not_object); 1561 __ j(not_zero, is_not_object);
1652 1562
1653 __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset)); 1563 __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset));
1654 __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 1564 __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
1655 __ j(below, is_not_object); 1565 __ j(below, is_not_object);
1656 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 1566 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
1657 return below_equal; 1567 return below_equal;
1658 } 1568 }
1659 1569
1660 1570
1661 void LCodeGen::DoIsObject(LIsObject* instr) {
1662 Register reg = ToRegister(instr->InputAt(0));
1663 Register result = ToRegister(instr->result());
1664 Label is_false, is_true, done;
1665
1666 Condition true_cond = EmitIsObject(reg, result, &is_false, &is_true);
1667 __ j(true_cond, &is_true);
1668
1669 __ bind(&is_false);
1670 __ mov(result, factory()->false_value());
1671 __ jmp(&done);
1672
1673 __ bind(&is_true);
1674 __ mov(result, factory()->true_value());
1675
1676 __ bind(&done);
1677 }
1678
1679
1680 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1571 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1681 Register reg = ToRegister(instr->InputAt(0)); 1572 Register reg = ToRegister(instr->InputAt(0));
1682 Register temp = ToRegister(instr->TempAt(0)); 1573 Register temp = ToRegister(instr->TempAt(0));
1683 1574
1684 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1575 int true_block = chunk_->LookupDestination(instr->true_block_id());
1685 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1576 int false_block = chunk_->LookupDestination(instr->false_block_id());
1686 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1577 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1687 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1578 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1688 1579
1689 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label); 1580 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
1690 1581
1691 EmitBranch(true_block, false_block, true_cond); 1582 EmitBranch(true_block, false_block, true_cond);
1692 } 1583 }
1693 1584
1694 1585
1695 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1696 Operand input = ToOperand(instr->InputAt(0));
1697 Register result = ToRegister(instr->result());
1698
1699 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1700 Label done;
1701 __ mov(result, factory()->true_value());
1702 __ JumpIfSmi(input, &done, Label::kNear);
1703 __ mov(result, factory()->false_value());
1704 __ bind(&done);
1705 }
1706
1707
1708 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1586 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1709 Operand input = ToOperand(instr->InputAt(0)); 1587 Operand input = ToOperand(instr->InputAt(0));
1710 1588
1711 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1589 int true_block = chunk_->LookupDestination(instr->true_block_id());
1712 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1590 int false_block = chunk_->LookupDestination(instr->false_block_id());
1713 1591
1714 __ test(input, Immediate(kSmiTagMask)); 1592 __ test(input, Immediate(kSmiTagMask));
1715 EmitBranch(true_block, false_block, zero); 1593 EmitBranch(true_block, false_block, zero);
1716 } 1594 }
1717 1595
1718 1596
1719 void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) {
1720 Register input = ToRegister(instr->InputAt(0));
1721 Register result = ToRegister(instr->result());
1722
1723 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1724 Label false_label, done;
1725 STATIC_ASSERT(kSmiTag == 0);
1726 __ JumpIfSmi(input, &false_label, Label::kNear);
1727 __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
1728 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
1729 1 << Map::kIsUndetectable);
1730 __ j(zero, &false_label, Label::kNear);
1731 __ mov(result, factory()->true_value());
1732 __ jmp(&done);
1733 __ bind(&false_label);
1734 __ mov(result, factory()->false_value());
1735 __ bind(&done);
1736 }
1737
1738
1739 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 1597 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
1740 Register input = ToRegister(instr->InputAt(0)); 1598 Register input = ToRegister(instr->InputAt(0));
1741 Register temp = ToRegister(instr->TempAt(0)); 1599 Register temp = ToRegister(instr->TempAt(0));
1742 1600
1743 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1601 int true_block = chunk_->LookupDestination(instr->true_block_id());
1744 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1602 int false_block = chunk_->LookupDestination(instr->false_block_id());
1745 1603
1746 STATIC_ASSERT(kSmiTag == 0); 1604 STATIC_ASSERT(kSmiTag == 0);
1747 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 1605 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
1748 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 1606 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
1749 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 1607 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
1750 1 << Map::kIsUndetectable); 1608 1 << Map::kIsUndetectable);
1751 EmitBranch(true_block, false_block, not_zero); 1609 EmitBranch(true_block, false_block, not_zero);
1752 } 1610 }
1753 1611
1754 1612
1755 static InstanceType TestType(HHasInstanceType* instr) { 1613 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
1756 InstanceType from = instr->from(); 1614 InstanceType from = instr->from();
1757 InstanceType to = instr->to(); 1615 InstanceType to = instr->to();
1758 if (from == FIRST_TYPE) return to; 1616 if (from == FIRST_TYPE) return to;
1759 ASSERT(from == to || to == LAST_TYPE); 1617 ASSERT(from == to || to == LAST_TYPE);
1760 return from; 1618 return from;
1761 } 1619 }
1762 1620
1763 1621
1764 static Condition BranchCondition(HHasInstanceType* instr) { 1622 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
1765 InstanceType from = instr->from(); 1623 InstanceType from = instr->from();
1766 InstanceType to = instr->to(); 1624 InstanceType to = instr->to();
1767 if (from == to) return equal; 1625 if (from == to) return equal;
1768 if (to == LAST_TYPE) return above_equal; 1626 if (to == LAST_TYPE) return above_equal;
1769 if (from == FIRST_TYPE) return below_equal; 1627 if (from == FIRST_TYPE) return below_equal;
1770 UNREACHABLE(); 1628 UNREACHABLE();
1771 return equal; 1629 return equal;
1772 } 1630 }
1773 1631
1774 1632
1775 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1776 Register input = ToRegister(instr->InputAt(0));
1777 Register result = ToRegister(instr->result());
1778
1779 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1780 Label done, is_false;
1781 __ JumpIfSmi(input, &is_false, Label::kNear);
1782 __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1783 __ j(NegateCondition(BranchCondition(instr->hydrogen())),
1784 &is_false, Label::kNear);
1785 __ mov(result, factory()->true_value());
1786 __ jmp(&done, Label::kNear);
1787 __ bind(&is_false);
1788 __ mov(result, factory()->false_value());
1789 __ bind(&done);
1790 }
1791
1792
1793 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1633 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1794 Register input = ToRegister(instr->InputAt(0)); 1634 Register input = ToRegister(instr->InputAt(0));
1795 Register temp = ToRegister(instr->TempAt(0)); 1635 Register temp = ToRegister(instr->TempAt(0));
1796 1636
1797 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1637 int true_block = chunk_->LookupDestination(instr->true_block_id());
1798 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1638 int false_block = chunk_->LookupDestination(instr->false_block_id());
1799 1639
1800 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1640 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1801 1641
1802 __ JumpIfSmi(input, false_label); 1642 __ JumpIfSmi(input, false_label);
1803 1643
1804 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 1644 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
1805 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 1645 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1806 } 1646 }
1807 1647
1808 1648
1809 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 1649 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
1810 Register input = ToRegister(instr->InputAt(0)); 1650 Register input = ToRegister(instr->InputAt(0));
1811 Register result = ToRegister(instr->result()); 1651 Register result = ToRegister(instr->result());
1812 1652
1813 if (FLAG_debug_code) { 1653 if (FLAG_debug_code) {
1814 __ AbortIfNotString(input); 1654 __ AbortIfNotString(input);
1815 } 1655 }
1816 1656
1817 __ mov(result, FieldOperand(input, String::kHashFieldOffset)); 1657 __ mov(result, FieldOperand(input, String::kHashFieldOffset));
1818 __ IndexFromHash(result, result); 1658 __ IndexFromHash(result, result);
1819 } 1659 }
1820 1660
1821 1661
1822 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1823 Register input = ToRegister(instr->InputAt(0));
1824 Register result = ToRegister(instr->result());
1825
1826 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1827 __ mov(result, factory()->true_value());
1828 __ test(FieldOperand(input, String::kHashFieldOffset),
1829 Immediate(String::kContainsCachedArrayIndexMask));
1830 Label done;
1831 __ j(zero, &done, Label::kNear);
1832 __ mov(result, factory()->false_value());
1833 __ bind(&done);
1834 }
1835
1836
1837 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1662 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1838 LHasCachedArrayIndexAndBranch* instr) { 1663 LHasCachedArrayIndexAndBranch* instr) {
1839 Register input = ToRegister(instr->InputAt(0)); 1664 Register input = ToRegister(instr->InputAt(0));
1840 1665
1841 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1666 int true_block = chunk_->LookupDestination(instr->true_block_id());
1842 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1667 int false_block = chunk_->LookupDestination(instr->false_block_id());
1843 1668
1844 __ test(FieldOperand(input, String::kHashFieldOffset), 1669 __ test(FieldOperand(input, String::kHashFieldOffset),
1845 Immediate(String::kContainsCachedArrayIndexMask)); 1670 Immediate(String::kContainsCachedArrayIndexMask));
1846 EmitBranch(true_block, false_block, equal); 1671 EmitBranch(true_block, false_block, equal);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 // The name in the constructor is a symbol because of the way the context is 1722 // The name in the constructor is a symbol because of the way the context is
1898 // booted. This routine isn't expected to work for random API-created 1723 // booted. This routine isn't expected to work for random API-created
1899 // classes and it doesn't have to because you can't access it with natives 1724 // classes and it doesn't have to because you can't access it with natives
1900 // syntax. Since both sides are symbols it is sufficient to use an identity 1725 // syntax. Since both sides are symbols it is sufficient to use an identity
1901 // comparison. 1726 // comparison.
1902 __ cmp(temp, class_name); 1727 __ cmp(temp, class_name);
1903 // End with the answer in the z flag. 1728 // End with the answer in the z flag.
1904 } 1729 }
1905 1730
1906 1731
1907 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1908 Register input = ToRegister(instr->InputAt(0));
1909 Register result = ToRegister(instr->result());
1910 ASSERT(input.is(result));
1911 Register temp = ToRegister(instr->TempAt(0));
1912 Handle<String> class_name = instr->hydrogen()->class_name();
1913 Label done;
1914 Label is_true, is_false;
1915
1916 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
1917
1918 __ j(not_equal, &is_false, Label::kNear);
1919
1920 __ bind(&is_true);
1921 __ mov(result, factory()->true_value());
1922 __ jmp(&done, Label::kNear);
1923
1924 __ bind(&is_false);
1925 __ mov(result, factory()->false_value());
1926 __ bind(&done);
1927 }
1928
1929
1930 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1732 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1931 Register input = ToRegister(instr->InputAt(0)); 1733 Register input = ToRegister(instr->InputAt(0));
1932 Register temp = ToRegister(instr->TempAt(0)); 1734 Register temp = ToRegister(instr->TempAt(0));
1933 Register temp2 = ToRegister(instr->TempAt(1)); 1735 Register temp2 = ToRegister(instr->TempAt(1));
1934 if (input.is(temp)) { 1736 if (input.is(temp)) {
1935 // Swap. 1737 // Swap.
1936 Register swapper = temp; 1738 Register swapper = temp;
1937 temp = temp2; 1739 temp = temp2;
1938 temp2 = swapper; 1740 temp2 = swapper;
1939 } 1741 }
(...skipping 2242 matching lines...) Expand 10 before | Expand all | Expand 10 after
4182 LOperand* input = instr->InputAt(0); 3984 LOperand* input = instr->InputAt(0);
4183 if (input->IsConstantOperand()) { 3985 if (input->IsConstantOperand()) {
4184 __ push(ToImmediate(input)); 3986 __ push(ToImmediate(input));
4185 } else { 3987 } else {
4186 __ push(ToOperand(input)); 3988 __ push(ToOperand(input));
4187 } 3989 }
4188 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); 3990 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT);
4189 } 3991 }
4190 3992
4191 3993
4192 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
4193 Register input = ToRegister(instr->InputAt(0));
4194 Register result = ToRegister(instr->result());
4195 Label true_label;
4196 Label false_label;
4197 Label done;
4198
4199 Condition final_branch_condition = EmitTypeofIs(&true_label,
4200 &false_label,
4201 input,
4202 instr->type_literal());
4203 __ j(final_branch_condition, &true_label, Label::kNear);
4204 __ bind(&false_label);
4205 __ mov(result, factory()->false_value());
4206 __ jmp(&done, Label::kNear);
4207
4208 __ bind(&true_label);
4209 __ mov(result, factory()->true_value());
4210
4211 __ bind(&done);
4212 }
4213
4214
4215 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 3994 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
4216 Register input = ToRegister(instr->InputAt(0)); 3995 Register input = ToRegister(instr->InputAt(0));
4217 int true_block = chunk_->LookupDestination(instr->true_block_id()); 3996 int true_block = chunk_->LookupDestination(instr->true_block_id());
4218 int false_block = chunk_->LookupDestination(instr->false_block_id()); 3997 int false_block = chunk_->LookupDestination(instr->false_block_id());
4219 Label* true_label = chunk_->GetAssemblyLabel(true_block); 3998 Label* true_label = chunk_->GetAssemblyLabel(true_block);
4220 Label* false_label = chunk_->GetAssemblyLabel(false_block); 3999 Label* false_label = chunk_->GetAssemblyLabel(false_block);
4221 4000
4222 Condition final_branch_condition = EmitTypeofIs(true_label, 4001 Condition final_branch_condition = EmitTypeofIs(true_label,
4223 false_label, 4002 false_label,
4224 input, 4003 input,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4285 } else { 4064 } else {
4286 final_branch_condition = not_equal; 4065 final_branch_condition = not_equal;
4287 __ jmp(false_label); 4066 __ jmp(false_label);
4288 // A dead branch instruction will be generated after this point. 4067 // A dead branch instruction will be generated after this point.
4289 } 4068 }
4290 4069
4291 return final_branch_condition; 4070 return final_branch_condition;
4292 } 4071 }
4293 4072
4294 4073
4295 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
4296 Register result = ToRegister(instr->result());
4297 Label true_label;
4298 Label done;
4299
4300 EmitIsConstructCall(result);
4301 __ j(equal, &true_label, Label::kNear);
4302
4303 __ mov(result, factory()->false_value());
4304 __ jmp(&done, Label::kNear);
4305
4306 __ bind(&true_label);
4307 __ mov(result, factory()->true_value());
4308
4309 __ bind(&done);
4310 }
4311
4312
4313 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 4074 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
4314 Register temp = ToRegister(instr->TempAt(0)); 4075 Register temp = ToRegister(instr->TempAt(0));
4315 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4076 int true_block = chunk_->LookupDestination(instr->true_block_id());
4316 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4077 int false_block = chunk_->LookupDestination(instr->false_block_id());
4317 4078
4318 EmitIsConstructCall(temp); 4079 EmitIsConstructCall(temp);
4319 EmitBranch(true_block, false_block, equal); 4080 EmitBranch(true_block, false_block, equal);
4320 } 4081 }
4321 4082
4322 4083
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
4461 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4222 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4462 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4223 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4463 } 4224 }
4464 4225
4465 4226
4466 #undef __ 4227 #undef __
4467 4228
4468 } } // namespace v8::internal 4229 } } // namespace v8::internal
4469 4230
4470 #endif // V8_TARGET_ARCH_IA32 4231 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen-instructions.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698