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

Side by Side Diff: src/x64/lithium-codegen-x64.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 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 __ jmp(chunk_->GetAssemblyLabel(right_block)); 1356 __ jmp(chunk_->GetAssemblyLabel(right_block));
1357 } 1357 }
1358 } 1358 }
1359 } 1359 }
1360 1360
1361 1361
1362 void LCodeGen::DoBranch(LBranch* instr) { 1362 void LCodeGen::DoBranch(LBranch* instr) {
1363 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1363 int true_block = chunk_->LookupDestination(instr->true_block_id());
1364 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1364 int false_block = chunk_->LookupDestination(instr->false_block_id());
1365 1365
1366 Representation r = instr->hydrogen()->representation(); 1366 Representation r = instr->hydrogen()->value()->representation();
1367 if (r.IsInteger32()) { 1367 if (r.IsInteger32()) {
1368 Register reg = ToRegister(instr->InputAt(0)); 1368 Register reg = ToRegister(instr->InputAt(0));
1369 __ testl(reg, reg); 1369 __ testl(reg, reg);
1370 EmitBranch(true_block, false_block, not_zero); 1370 EmitBranch(true_block, false_block, not_zero);
1371 } else if (r.IsDouble()) { 1371 } else if (r.IsDouble()) {
1372 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); 1372 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1373 __ xorps(xmm0, xmm0); 1373 __ xorps(xmm0, xmm0);
1374 __ ucomisd(reg, xmm0); 1374 __ ucomisd(reg, xmm0);
1375 EmitBranch(true_block, false_block, not_equal); 1375 EmitBranch(true_block, false_block, not_equal);
1376 } else { 1376 } else {
1377 ASSERT(r.IsTagged()); 1377 ASSERT(r.IsTagged());
1378 Register reg = ToRegister(instr->InputAt(0)); 1378 Register reg = ToRegister(instr->InputAt(0));
1379 HType type = instr->hydrogen()->type(); 1379 HType type = instr->hydrogen()->value()->type();
1380 if (type.IsBoolean()) { 1380 if (type.IsBoolean()) {
1381 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1381 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1382 EmitBranch(true_block, false_block, equal); 1382 EmitBranch(true_block, false_block, equal);
1383 } else if (type.IsSmi()) { 1383 } else if (type.IsSmi()) {
1384 __ SmiCompare(reg, Smi::FromInt(0)); 1384 __ SmiCompare(reg, Smi::FromInt(0));
1385 EmitBranch(true_block, false_block, not_equal); 1385 EmitBranch(true_block, false_block, not_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
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 __ cmpl(ToOperand(left), Immediate(value)); 1476 __ cmpl(ToOperand(left), Immediate(value));
1477 } 1477 }
1478 } else if (right->IsRegister()) { 1478 } else if (right->IsRegister()) {
1479 __ cmpl(ToRegister(left), ToRegister(right)); 1479 __ cmpl(ToRegister(left), ToRegister(right));
1480 } else { 1480 } else {
1481 __ cmpl(ToRegister(left), ToOperand(right)); 1481 __ cmpl(ToRegister(left), ToOperand(right));
1482 } 1482 }
1483 } 1483 }
1484 1484
1485 1485
1486 void LCodeGen::DoCmpID(LCmpID* instr) {
1487 LOperand* left = instr->InputAt(0);
1488 LOperand* right = instr->InputAt(1);
1489 LOperand* result = instr->result();
1490
1491 Label unordered;
1492 if (instr->is_double()) {
1493 // Don't base result on EFLAGS when a NaN is involved. Instead
1494 // jump to the unordered case, which produces a false value.
1495 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1496 __ j(parity_even, &unordered, Label::kNear);
1497 } else {
1498 EmitCmpI(left, right);
1499 }
1500
1501 Label done;
1502 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1503 __ LoadRoot(ToRegister(result), Heap::kTrueValueRootIndex);
1504 __ j(cc, &done, Label::kNear);
1505
1506 __ bind(&unordered);
1507 __ LoadRoot(ToRegister(result), Heap::kFalseValueRootIndex);
1508 __ bind(&done);
1509 }
1510
1511
1512 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1486 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1513 LOperand* left = instr->InputAt(0); 1487 LOperand* left = instr->InputAt(0);
1514 LOperand* right = instr->InputAt(1); 1488 LOperand* right = instr->InputAt(1);
1515 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1489 int false_block = chunk_->LookupDestination(instr->false_block_id());
1516 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1490 int true_block = chunk_->LookupDestination(instr->true_block_id());
1517 1491
1518 if (instr->is_double()) { 1492 if (instr->is_double()) {
1519 // Don't base result on EFLAGS when a NaN is involved. Instead 1493 // Don't base result on EFLAGS when a NaN is involved. Instead
1520 // jump to the false block. 1494 // jump to the false block.
1521 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1495 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1522 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 1496 __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
1523 } else { 1497 } else {
1524 EmitCmpI(left, right); 1498 EmitCmpI(left, right);
1525 } 1499 }
1526 1500
1527 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1501 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1528 EmitBranch(true_block, false_block, cc); 1502 EmitBranch(true_block, false_block, cc);
1529 } 1503 }
1530 1504
1531 1505
1532 void LCodeGen::DoCmpObjectEq(LCmpObjectEq* instr) {
1533 Register left = ToRegister(instr->InputAt(0));
1534 Register right = ToRegister(instr->InputAt(1));
1535 Register result = ToRegister(instr->result());
1536
1537 Label different, done;
1538 __ cmpq(left, right);
1539 __ j(not_equal, &different, Label::kNear);
1540 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1541 __ jmp(&done, Label::kNear);
1542 __ bind(&different);
1543 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1544 __ bind(&done);
1545 }
1546
1547
1548 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1506 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1549 Register left = ToRegister(instr->InputAt(0)); 1507 Register left = ToRegister(instr->InputAt(0));
1550 Register right = ToRegister(instr->InputAt(1)); 1508 Register right = ToRegister(instr->InputAt(1));
1551 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1509 int false_block = chunk_->LookupDestination(instr->false_block_id());
1552 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1510 int true_block = chunk_->LookupDestination(instr->true_block_id());
1553 1511
1554 __ cmpq(left, right); 1512 __ cmpq(left, right);
1555 EmitBranch(true_block, false_block, equal); 1513 EmitBranch(true_block, false_block, equal);
1556 } 1514 }
1557 1515
1558 1516
1559 void LCodeGen::DoCmpConstantEq(LCmpConstantEq* instr) {
1560 Register left = ToRegister(instr->InputAt(0));
1561 Register result = ToRegister(instr->result());
1562
1563 Label done;
1564 __ cmpq(left, Immediate(instr->hydrogen()->right()));
1565 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1566 __ j(equal, &done, Label::kNear);
1567 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1568 __ bind(&done);
1569 }
1570
1571
1572 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1517 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1573 Register left = ToRegister(instr->InputAt(0)); 1518 Register left = ToRegister(instr->InputAt(0));
1574 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1519 int true_block = chunk_->LookupDestination(instr->true_block_id());
1575 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1520 int false_block = chunk_->LookupDestination(instr->false_block_id());
1576 1521
1577 __ cmpq(left, Immediate(instr->hydrogen()->right())); 1522 __ cmpq(left, Immediate(instr->hydrogen()->right()));
1578 EmitBranch(true_block, false_block, equal); 1523 EmitBranch(true_block, false_block, equal);
1579 } 1524 }
1580 1525
1581 1526
1582 void LCodeGen::DoIsNull(LIsNull* instr) {
1583 Register reg = ToRegister(instr->InputAt(0));
1584 Register result = ToRegister(instr->result());
1585
1586 // If the expression is known to be a smi, then it's
1587 // definitely not null. Materialize false.
1588 // Consider adding other type and representation tests too.
1589 if (instr->hydrogen()->value()->type().IsSmi()) {
1590 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1591 return;
1592 }
1593
1594 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1595 if (instr->is_strict()) {
1596 ASSERT(Heap::kTrueValueRootIndex >= 0);
1597 __ movl(result, Immediate(Heap::kTrueValueRootIndex));
1598 Label load;
1599 __ j(equal, &load, Label::kNear);
1600 __ Set(result, Heap::kFalseValueRootIndex);
1601 __ bind(&load);
1602 __ LoadRootIndexed(result, result, 0);
1603 } else {
1604 Label false_value, true_value, done;
1605 __ j(equal, &true_value, Label::kNear);
1606 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1607 __ j(equal, &true_value, Label::kNear);
1608 __ JumpIfSmi(reg, &false_value, Label::kNear);
1609 // Check for undetectable objects by looking in the bit field in
1610 // the map. The object has already been smi checked.
1611 Register scratch = result;
1612 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1613 __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
1614 Immediate(1 << Map::kIsUndetectable));
1615 __ j(not_zero, &true_value, Label::kNear);
1616 __ bind(&false_value);
1617 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1618 __ jmp(&done, Label::kNear);
1619 __ bind(&true_value);
1620 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1621 __ bind(&done);
1622 }
1623 }
1624
1625
1626 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1527 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1627 Register reg = ToRegister(instr->InputAt(0)); 1528 Register reg = ToRegister(instr->InputAt(0));
1628 1529
1629 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1530 int false_block = chunk_->LookupDestination(instr->false_block_id());
1630 1531
1631 if (instr->hydrogen()->representation().IsSpecialization() || 1532 if (instr->hydrogen()->representation().IsSpecialization() ||
1632 instr->hydrogen()->type().IsSmi()) { 1533 instr->hydrogen()->type().IsSmi()) {
1633 // If the expression is known to untagged or smi, then it's definitely 1534 // If the expression is known to untagged or smi, then it's definitely
1634 // not null, and it can't be a an undetectable object. 1535 // not null, and it can't be a an undetectable object.
1635 // Jump directly to the false block. 1536 // Jump directly to the false block.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 1579
1679 __ movzxbl(kScratchRegister, 1580 __ movzxbl(kScratchRegister,
1680 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 1581 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
1681 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1582 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
1682 __ j(below, is_not_object); 1583 __ j(below, is_not_object);
1683 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1584 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
1684 return below_equal; 1585 return below_equal;
1685 } 1586 }
1686 1587
1687 1588
1688 void LCodeGen::DoIsObject(LIsObject* instr) {
1689 Register reg = ToRegister(instr->InputAt(0));
1690 Register result = ToRegister(instr->result());
1691 Label is_false, is_true, done;
1692
1693 Condition true_cond = EmitIsObject(reg, &is_false, &is_true);
1694 __ j(true_cond, &is_true);
1695
1696 __ bind(&is_false);
1697 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1698 __ jmp(&done);
1699
1700 __ bind(&is_true);
1701 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1702
1703 __ bind(&done);
1704 }
1705
1706
1707 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1589 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1708 Register reg = ToRegister(instr->InputAt(0)); 1590 Register reg = ToRegister(instr->InputAt(0));
1709 1591
1710 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1592 int true_block = chunk_->LookupDestination(instr->true_block_id());
1711 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1593 int false_block = chunk_->LookupDestination(instr->false_block_id());
1712 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1594 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1713 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1595 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1714 1596
1715 Condition true_cond = EmitIsObject(reg, false_label, true_label); 1597 Condition true_cond = EmitIsObject(reg, false_label, true_label);
1716 1598
1717 EmitBranch(true_block, false_block, true_cond); 1599 EmitBranch(true_block, false_block, true_cond);
1718 } 1600 }
1719 1601
1720 1602
1721 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1722 LOperand* input_operand = instr->InputAt(0);
1723 Register result = ToRegister(instr->result());
1724 if (input_operand->IsRegister()) {
1725 Register input = ToRegister(input_operand);
1726 __ CheckSmiToIndicator(result, input);
1727 } else {
1728 Operand input = ToOperand(instr->InputAt(0));
1729 __ CheckSmiToIndicator(result, input);
1730 }
1731 // result is zero if input is a smi, and one otherwise.
1732 ASSERT(Heap::kFalseValueRootIndex == Heap::kTrueValueRootIndex + 1);
1733 __ LoadRootIndexed(result, result, Heap::kTrueValueRootIndex);
1734 }
1735
1736
1737 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1603 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1738 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1604 int true_block = chunk_->LookupDestination(instr->true_block_id());
1739 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1605 int false_block = chunk_->LookupDestination(instr->false_block_id());
1740 1606
1741 Condition is_smi; 1607 Condition is_smi;
1742 if (instr->InputAt(0)->IsRegister()) { 1608 if (instr->InputAt(0)->IsRegister()) {
1743 Register input = ToRegister(instr->InputAt(0)); 1609 Register input = ToRegister(instr->InputAt(0));
1744 is_smi = masm()->CheckSmi(input); 1610 is_smi = masm()->CheckSmi(input);
1745 } else { 1611 } else {
1746 Operand input = ToOperand(instr->InputAt(0)); 1612 Operand input = ToOperand(instr->InputAt(0));
1747 is_smi = masm()->CheckSmi(input); 1613 is_smi = masm()->CheckSmi(input);
1748 } 1614 }
1749 EmitBranch(true_block, false_block, is_smi); 1615 EmitBranch(true_block, false_block, is_smi);
1750 } 1616 }
1751 1617
1752 1618
1753 void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) {
1754 Register input = ToRegister(instr->InputAt(0));
1755 Register result = ToRegister(instr->result());
1756
1757 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1758 Label false_label, done;
1759 __ JumpIfSmi(input, &false_label);
1760 __ movq(result, FieldOperand(input, HeapObject::kMapOffset));
1761 __ testb(FieldOperand(result, Map::kBitFieldOffset),
1762 Immediate(1 << Map::kIsUndetectable));
1763 __ j(zero, &false_label);
1764 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1765 __ jmp(&done);
1766 __ bind(&false_label);
1767 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1768 __ bind(&done);
1769 }
1770
1771
1772 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 1619 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
1773 Register input = ToRegister(instr->InputAt(0)); 1620 Register input = ToRegister(instr->InputAt(0));
1774 Register temp = ToRegister(instr->TempAt(0)); 1621 Register temp = ToRegister(instr->TempAt(0));
1775 1622
1776 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1623 int true_block = chunk_->LookupDestination(instr->true_block_id());
1777 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1624 int false_block = chunk_->LookupDestination(instr->false_block_id());
1778 1625
1779 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 1626 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
1780 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); 1627 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
1781 __ testb(FieldOperand(temp, Map::kBitFieldOffset), 1628 __ testb(FieldOperand(temp, Map::kBitFieldOffset),
1782 Immediate(1 << Map::kIsUndetectable)); 1629 Immediate(1 << Map::kIsUndetectable));
1783 EmitBranch(true_block, false_block, not_zero); 1630 EmitBranch(true_block, false_block, not_zero);
1784 } 1631 }
1785 1632
1786 1633
1787 static InstanceType TestType(HHasInstanceType* instr) { 1634 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
1788 InstanceType from = instr->from(); 1635 InstanceType from = instr->from();
1789 InstanceType to = instr->to(); 1636 InstanceType to = instr->to();
1790 if (from == FIRST_TYPE) return to; 1637 if (from == FIRST_TYPE) return to;
1791 ASSERT(from == to || to == LAST_TYPE); 1638 ASSERT(from == to || to == LAST_TYPE);
1792 return from; 1639 return from;
1793 } 1640 }
1794 1641
1795 1642
1796 static Condition BranchCondition(HHasInstanceType* instr) { 1643 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
1797 InstanceType from = instr->from(); 1644 InstanceType from = instr->from();
1798 InstanceType to = instr->to(); 1645 InstanceType to = instr->to();
1799 if (from == to) return equal; 1646 if (from == to) return equal;
1800 if (to == LAST_TYPE) return above_equal; 1647 if (to == LAST_TYPE) return above_equal;
1801 if (from == FIRST_TYPE) return below_equal; 1648 if (from == FIRST_TYPE) return below_equal;
1802 UNREACHABLE(); 1649 UNREACHABLE();
1803 return equal; 1650 return equal;
1804 } 1651 }
1805 1652
1806 1653
1807 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1808 Register input = ToRegister(instr->InputAt(0));
1809 Register result = ToRegister(instr->result());
1810
1811 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1812 __ testl(input, Immediate(kSmiTagMask));
1813 Label done, is_false;
1814 __ j(zero, &is_false);
1815 __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1816 __ j(NegateCondition(BranchCondition(instr->hydrogen())),
1817 &is_false, Label::kNear);
1818 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1819 __ jmp(&done, Label::kNear);
1820 __ bind(&is_false);
1821 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1822 __ bind(&done);
1823 }
1824
1825
1826 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1654 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1827 Register input = ToRegister(instr->InputAt(0)); 1655 Register input = ToRegister(instr->InputAt(0));
1828 1656
1829 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1657 int true_block = chunk_->LookupDestination(instr->true_block_id());
1830 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1658 int false_block = chunk_->LookupDestination(instr->false_block_id());
1831 1659
1832 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1660 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1833 1661
1834 __ JumpIfSmi(input, false_label); 1662 __ JumpIfSmi(input, false_label);
1835 1663
1836 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); 1664 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
1837 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 1665 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1838 } 1666 }
1839 1667
1840 1668
1841 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 1669 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
1842 Register input = ToRegister(instr->InputAt(0)); 1670 Register input = ToRegister(instr->InputAt(0));
1843 Register result = ToRegister(instr->result()); 1671 Register result = ToRegister(instr->result());
1844 1672
1845 if (FLAG_debug_code) { 1673 if (FLAG_debug_code) {
1846 __ AbortIfNotString(input); 1674 __ AbortIfNotString(input);
1847 } 1675 }
1848 1676
1849 __ movl(result, FieldOperand(input, String::kHashFieldOffset)); 1677 __ movl(result, FieldOperand(input, String::kHashFieldOffset));
1850 ASSERT(String::kHashShift >= kSmiTagSize); 1678 ASSERT(String::kHashShift >= kSmiTagSize);
1851 __ IndexFromHash(result, result); 1679 __ IndexFromHash(result, result);
1852 } 1680 }
1853 1681
1854 1682
1855 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1856 Register input = ToRegister(instr->InputAt(0));
1857 Register result = ToRegister(instr->result());
1858
1859 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1860 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1861 __ testl(FieldOperand(input, String::kHashFieldOffset),
1862 Immediate(String::kContainsCachedArrayIndexMask));
1863 Label done;
1864 __ j(zero, &done, Label::kNear);
1865 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1866 __ bind(&done);
1867 }
1868
1869
1870 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1683 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1871 LHasCachedArrayIndexAndBranch* instr) { 1684 LHasCachedArrayIndexAndBranch* instr) {
1872 Register input = ToRegister(instr->InputAt(0)); 1685 Register input = ToRegister(instr->InputAt(0));
1873 1686
1874 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1687 int true_block = chunk_->LookupDestination(instr->true_block_id());
1875 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1688 int false_block = chunk_->LookupDestination(instr->false_block_id());
1876 1689
1877 __ testl(FieldOperand(input, String::kHashFieldOffset), 1690 __ testl(FieldOperand(input, String::kHashFieldOffset),
1878 Immediate(String::kContainsCachedArrayIndexMask)); 1691 Immediate(String::kContainsCachedArrayIndexMask));
1879 EmitBranch(true_block, false_block, equal); 1692 EmitBranch(true_block, false_block, equal);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 // booted. This routine isn't expected to work for random API-created 1741 // booted. This routine isn't expected to work for random API-created
1929 // classes and it doesn't have to because you can't access it with natives 1742 // classes and it doesn't have to because you can't access it with natives
1930 // syntax. Since both sides are symbols it is sufficient to use an identity 1743 // syntax. Since both sides are symbols it is sufficient to use an identity
1931 // comparison. 1744 // comparison.
1932 ASSERT(class_name->IsSymbol()); 1745 ASSERT(class_name->IsSymbol());
1933 __ Cmp(temp, class_name); 1746 __ Cmp(temp, class_name);
1934 // End with the answer in the z flag. 1747 // End with the answer in the z flag.
1935 } 1748 }
1936 1749
1937 1750
1938 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1939 Register input = ToRegister(instr->InputAt(0));
1940 Register result = ToRegister(instr->result());
1941 ASSERT(input.is(result));
1942 Register temp = ToRegister(instr->TempAt(0));
1943 Handle<String> class_name = instr->hydrogen()->class_name();
1944 Label done;
1945 Label is_true, is_false;
1946
1947 EmitClassOfTest(&is_true, &is_false, class_name, input, temp);
1948
1949 __ j(not_equal, &is_false);
1950
1951 __ bind(&is_true);
1952 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1953 __ jmp(&done, Label::kNear);
1954
1955 __ bind(&is_false);
1956 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1957 __ bind(&done);
1958 }
1959
1960
1961 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1751 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1962 Register input = ToRegister(instr->InputAt(0)); 1752 Register input = ToRegister(instr->InputAt(0));
1963 Register temp = ToRegister(instr->TempAt(0)); 1753 Register temp = ToRegister(instr->TempAt(0));
1964 Handle<String> class_name = instr->hydrogen()->class_name(); 1754 Handle<String> class_name = instr->hydrogen()->class_name();
1965 1755
1966 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1756 int true_block = chunk_->LookupDestination(instr->true_block_id());
1967 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1757 int false_block = chunk_->LookupDestination(instr->false_block_id());
1968 1758
1969 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1759 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1970 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1760 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 2047 matching lines...) Expand 10 before | Expand all | Expand 10 after
4018 } 3808 }
4019 3809
4020 3810
4021 void LCodeGen::DoTypeof(LTypeof* instr) { 3811 void LCodeGen::DoTypeof(LTypeof* instr) {
4022 LOperand* input = instr->InputAt(0); 3812 LOperand* input = instr->InputAt(0);
4023 EmitPushTaggedOperand(input); 3813 EmitPushTaggedOperand(input);
4024 CallRuntime(Runtime::kTypeof, 1, instr); 3814 CallRuntime(Runtime::kTypeof, 1, instr);
4025 } 3815 }
4026 3816
4027 3817
4028 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
4029 Register input = ToRegister(instr->InputAt(0));
4030 Register result = ToRegister(instr->result());
4031 Label true_label;
4032 Label false_label;
4033 Label done;
4034
4035 Condition final_branch_condition = EmitTypeofIs(&true_label,
4036 &false_label,
4037 input,
4038 instr->type_literal());
4039 __ j(final_branch_condition, &true_label);
4040 __ bind(&false_label);
4041 __ LoadRoot(result, Heap::kFalseValueRootIndex);
4042 __ jmp(&done, Label::kNear);
4043
4044 __ bind(&true_label);
4045 __ LoadRoot(result, Heap::kTrueValueRootIndex);
4046
4047 __ bind(&done);
4048 }
4049
4050
4051 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 3818 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
4052 ASSERT(!operand->IsDoubleRegister()); 3819 ASSERT(!operand->IsDoubleRegister());
4053 if (operand->IsConstantOperand()) { 3820 if (operand->IsConstantOperand()) {
4054 __ Push(ToHandle(LConstantOperand::cast(operand))); 3821 __ Push(ToHandle(LConstantOperand::cast(operand)));
4055 } else if (operand->IsRegister()) { 3822 } else if (operand->IsRegister()) {
4056 __ push(ToRegister(operand)); 3823 __ push(ToRegister(operand));
4057 } else { 3824 } else {
4058 __ push(ToOperand(operand)); 3825 __ push(ToOperand(operand));
4059 } 3826 }
4060 } 3827 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 3899
4133 } else { 3900 } else {
4134 final_branch_condition = never; 3901 final_branch_condition = never;
4135 __ jmp(false_label); 3902 __ jmp(false_label);
4136 } 3903 }
4137 3904
4138 return final_branch_condition; 3905 return final_branch_condition;
4139 } 3906 }
4140 3907
4141 3908
4142 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
4143 Register result = ToRegister(instr->result());
4144 Label true_label;
4145 Label done;
4146
4147 EmitIsConstructCall(result);
4148 __ j(equal, &true_label, Label::kNear);
4149
4150 __ LoadRoot(result, Heap::kFalseValueRootIndex);
4151 __ jmp(&done, Label::kNear);
4152
4153 __ bind(&true_label);
4154 __ LoadRoot(result, Heap::kTrueValueRootIndex);
4155
4156
4157 __ bind(&done);
4158 }
4159
4160
4161 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 3909 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
4162 Register temp = ToRegister(instr->TempAt(0)); 3910 Register temp = ToRegister(instr->TempAt(0));
4163 int true_block = chunk_->LookupDestination(instr->true_block_id()); 3911 int true_block = chunk_->LookupDestination(instr->true_block_id());
4164 int false_block = chunk_->LookupDestination(instr->false_block_id()); 3912 int false_block = chunk_->LookupDestination(instr->false_block_id());
4165 3913
4166 EmitIsConstructCall(temp); 3914 EmitIsConstructCall(temp);
4167 EmitBranch(true_block, false_block, equal); 3915 EmitBranch(true_block, false_block, equal);
4168 } 3916 }
4169 3917
4170 3918
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4289 RegisterEnvironmentForDeoptimization(environment); 4037 RegisterEnvironmentForDeoptimization(environment);
4290 ASSERT(osr_pc_offset_ == -1); 4038 ASSERT(osr_pc_offset_ == -1);
4291 osr_pc_offset_ = masm()->pc_offset(); 4039 osr_pc_offset_ = masm()->pc_offset();
4292 } 4040 }
4293 4041
4294 #undef __ 4042 #undef __
4295 4043
4296 } } // namespace v8::internal 4044 } } // namespace v8::internal
4297 4045
4298 #endif // V8_TARGET_ARCH_X64 4046 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/hydrogen.cc ('K') | « src/ia32/lithium-ia32.cc ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698