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

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

Issue 6237002: Remove the remaining LOperand-members from concrete LIR instructions.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ia32/lithium-ia32.h » ('j') | src/ia32/lithium-ia32.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 __ test(edx, Operand(edx)); 825 __ test(edx, Operand(edx));
826 DeoptimizeIf(not_zero, instr->environment()); 826 DeoptimizeIf(not_zero, instr->environment());
827 } 827 }
828 828
829 829
830 void LCodeGen::DoMulI(LMulI* instr) { 830 void LCodeGen::DoMulI(LMulI* instr) {
831 Register left = ToRegister(instr->left()); 831 Register left = ToRegister(instr->left());
832 LOperand* right = instr->right(); 832 LOperand* right = instr->right();
833 833
834 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 834 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
835 __ mov(ToRegister(instr->temp()), left); 835 __ mov(ToRegister(instr->TempAt(0)), left);
836 } 836 }
837 837
838 if (right->IsConstantOperand()) { 838 if (right->IsConstantOperand()) {
839 __ imul(left, left, ToInteger32(LConstantOperand::cast(right))); 839 __ imul(left, left, ToInteger32(LConstantOperand::cast(right)));
840 } else { 840 } else {
841 __ imul(left, ToOperand(right)); 841 __ imul(left, ToOperand(right));
842 } 842 }
843 843
844 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 844 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
845 DeoptimizeIf(overflow, instr->environment()); 845 DeoptimizeIf(overflow, instr->environment());
846 } 846 }
847 847
848 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 848 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
849 // Bail out if the result is supposed to be negative zero. 849 // Bail out if the result is supposed to be negative zero.
850 NearLabel done; 850 NearLabel done;
851 __ test(left, Operand(left)); 851 __ test(left, Operand(left));
852 __ j(not_zero, &done); 852 __ j(not_zero, &done);
853 if (right->IsConstantOperand()) { 853 if (right->IsConstantOperand()) {
854 if (ToInteger32(LConstantOperand::cast(right)) < 0) { 854 if (ToInteger32(LConstantOperand::cast(right)) < 0) {
855 DeoptimizeIf(no_condition, instr->environment()); 855 DeoptimizeIf(no_condition, instr->environment());
856 } 856 }
857 } else { 857 } else {
858 // Test the non-zero operand for negative sign. 858 // Test the non-zero operand for negative sign.
859 __ or_(ToRegister(instr->temp()), ToOperand(right)); 859 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
860 DeoptimizeIf(sign, instr->environment()); 860 DeoptimizeIf(sign, instr->environment());
861 } 861 }
862 __ bind(&done); 862 __ bind(&done);
863 } 863 }
864 } 864 }
865 865
866 866
867 void LCodeGen::DoBitI(LBitI* instr) { 867 void LCodeGen::DoBitI(LBitI* instr) {
868 LOperand* left = instr->left(); 868 LOperand* left = instr->left();
869 LOperand* right = instr->right(); 869 LOperand* right = instr->right();
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 1026 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
1027 Register result = ToRegister(instr->result()); 1027 Register result = ToRegister(instr->result());
1028 Register array = ToRegister(instr->input()); 1028 Register array = ToRegister(instr->input());
1029 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); 1029 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
1030 } 1030 }
1031 1031
1032 1032
1033 void LCodeGen::DoValueOf(LValueOf* instr) { 1033 void LCodeGen::DoValueOf(LValueOf* instr) {
1034 Register input = ToRegister(instr->input()); 1034 Register input = ToRegister(instr->input());
1035 Register result = ToRegister(instr->result()); 1035 Register result = ToRegister(instr->result());
1036 Register map = ToRegister(instr->temporary()); 1036 Register map = ToRegister(instr->TempAt(0));
1037 ASSERT(input.is(result)); 1037 ASSERT(input.is(result));
1038 NearLabel done; 1038 NearLabel done;
1039 // If the object is a smi return the object. 1039 // If the object is a smi return the object.
1040 __ test(input, Immediate(kSmiTagMask)); 1040 __ test(input, Immediate(kSmiTagMask));
1041 __ j(zero, &done); 1041 __ j(zero, &done);
1042 1042
1043 // If the object is not a value type, return the object. 1043 // If the object is not a value type, return the object.
1044 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1044 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1045 __ j(not_equal, &done); 1045 __ j(not_equal, &done);
1046 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1046 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 } else { 1428 } else {
1429 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1429 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1430 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1430 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1431 __ j(equal, true_label); 1431 __ j(equal, true_label);
1432 __ cmp(reg, Factory::undefined_value()); 1432 __ cmp(reg, Factory::undefined_value());
1433 __ j(equal, true_label); 1433 __ j(equal, true_label);
1434 __ test(reg, Immediate(kSmiTagMask)); 1434 __ test(reg, Immediate(kSmiTagMask));
1435 __ j(zero, false_label); 1435 __ j(zero, false_label);
1436 // Check for undetectable objects by looking in the bit field in 1436 // Check for undetectable objects by looking in the bit field in
1437 // the map. The object has already been smi checked. 1437 // the map. The object has already been smi checked.
1438 Register scratch = ToRegister(instr->temp()); 1438 Register scratch = ToRegister(instr->TempAt(0));
1439 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1439 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1440 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1440 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1441 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1441 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1442 EmitBranch(true_block, false_block, not_zero); 1442 EmitBranch(true_block, false_block, not_zero);
1443 } 1443 }
1444 } 1444 }
1445 1445
1446 1446
1447 Condition LCodeGen::EmitIsObject(Register input, 1447 Condition LCodeGen::EmitIsObject(Register input,
1448 Register temp1, 1448 Register temp1,
(...skipping 20 matching lines...) Expand all
1469 __ cmp(temp2, FIRST_JS_OBJECT_TYPE); 1469 __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
1470 __ j(below, is_not_object); 1470 __ j(below, is_not_object);
1471 __ cmp(temp2, LAST_JS_OBJECT_TYPE); 1471 __ cmp(temp2, LAST_JS_OBJECT_TYPE);
1472 return below_equal; 1472 return below_equal;
1473 } 1473 }
1474 1474
1475 1475
1476 void LCodeGen::DoIsObject(LIsObject* instr) { 1476 void LCodeGen::DoIsObject(LIsObject* instr) {
1477 Register reg = ToRegister(instr->input()); 1477 Register reg = ToRegister(instr->input());
1478 Register result = ToRegister(instr->result()); 1478 Register result = ToRegister(instr->result());
1479 Register temp = ToRegister(instr->temp()); 1479 Register temp = ToRegister(instr->TempAt(0));
1480 Label is_false, is_true, done; 1480 Label is_false, is_true, done;
1481 1481
1482 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); 1482 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
1483 __ j(true_cond, &is_true); 1483 __ j(true_cond, &is_true);
1484 1484
1485 __ bind(&is_false); 1485 __ bind(&is_false);
1486 __ mov(result, Handle<Object>(Heap::false_value())); 1486 __ mov(result, Handle<Object>(Heap::false_value()));
1487 __ jmp(&done); 1487 __ jmp(&done);
1488 1488
1489 __ bind(&is_true); 1489 __ bind(&is_true);
1490 __ mov(result, Handle<Object>(Heap::true_value())); 1490 __ mov(result, Handle<Object>(Heap::true_value()));
1491 1491
1492 __ bind(&done); 1492 __ bind(&done);
1493 } 1493 }
1494 1494
1495 1495
1496 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1496 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1497 Register reg = ToRegister(instr->input()); 1497 Register reg = ToRegister(instr->input());
1498 Register temp = ToRegister(instr->temp()); 1498 Register temp = ToRegister(instr->TempAt(0));
1499 Register temp2 = ToRegister(instr->temp2()); 1499 Register temp2 = ToRegister(instr->TempAt(1));
1500 1500
1501 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1501 int true_block = chunk_->LookupDestination(instr->true_block_id());
1502 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1502 int false_block = chunk_->LookupDestination(instr->false_block_id());
1503 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1503 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1504 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1504 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1505 1505
1506 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); 1506 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label);
1507 1507
1508 EmitBranch(true_block, false_block, true_cond); 1508 EmitBranch(true_block, false_block, true_cond);
1509 } 1509 }
(...skipping 17 matching lines...) Expand all
1527 Operand input = ToOperand(instr->input()); 1527 Operand input = ToOperand(instr->input());
1528 1528
1529 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1529 int true_block = chunk_->LookupDestination(instr->true_block_id());
1530 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1530 int false_block = chunk_->LookupDestination(instr->false_block_id());
1531 1531
1532 __ test(input, Immediate(kSmiTagMask)); 1532 __ test(input, Immediate(kSmiTagMask));
1533 EmitBranch(true_block, false_block, zero); 1533 EmitBranch(true_block, false_block, zero);
1534 } 1534 }
1535 1535
1536 1536
1537 InstanceType LHasInstanceType::TestType() { 1537 static InstanceType TestType(HHasInstanceType* instr) {
1538 InstanceType from = hydrogen()->from(); 1538 InstanceType from = instr->from();
1539 InstanceType to = hydrogen()->to(); 1539 InstanceType to = instr->to();
1540 if (from == FIRST_TYPE) return to; 1540 if (from == FIRST_TYPE) return to;
1541 ASSERT(from == to || to == LAST_TYPE); 1541 ASSERT(from == to || to == LAST_TYPE);
1542 return from; 1542 return from;
1543 } 1543 }
1544 1544
1545 1545
1546 1546
1547 Condition LHasInstanceType::BranchCondition() { 1547 static Condition BranchCondition(HHasInstanceType* instr) {
1548 InstanceType from = hydrogen()->from(); 1548 InstanceType from = instr->from();
1549 InstanceType to = hydrogen()->to(); 1549 InstanceType to = instr->to();
1550 if (from == to) return equal; 1550 if (from == to) return equal;
1551 if (to == LAST_TYPE) return above_equal; 1551 if (to == LAST_TYPE) return above_equal;
1552 if (from == FIRST_TYPE) return below_equal; 1552 if (from == FIRST_TYPE) return below_equal;
1553 UNREACHABLE(); 1553 UNREACHABLE();
1554 return equal; 1554 return equal;
1555 } 1555 }
1556 1556
1557 1557
1558 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { 1558 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1559 Register input = ToRegister(instr->input()); 1559 Register input = ToRegister(instr->input());
1560 Register result = ToRegister(instr->result()); 1560 Register result = ToRegister(instr->result());
1561 1561
1562 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1562 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1563 __ test(input, Immediate(kSmiTagMask)); 1563 __ test(input, Immediate(kSmiTagMask));
1564 NearLabel done, is_false; 1564 NearLabel done, is_false;
1565 __ j(zero, &is_false); 1565 __ j(zero, &is_false);
1566 __ CmpObjectType(input, instr->TestType(), result); 1566 __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1567 __ j(NegateCondition(instr->BranchCondition()), &is_false); 1567 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
1568 __ mov(result, Handle<Object>(Heap::true_value())); 1568 __ mov(result, Handle<Object>(Heap::true_value()));
1569 __ jmp(&done); 1569 __ jmp(&done);
1570 __ bind(&is_false); 1570 __ bind(&is_false);
1571 __ mov(result, Handle<Object>(Heap::false_value())); 1571 __ mov(result, Handle<Object>(Heap::false_value()));
1572 __ bind(&done); 1572 __ bind(&done);
1573 } 1573 }
1574 1574
1575 1575
1576 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1576 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1577 Register input = ToRegister(instr->input()); 1577 Register input = ToRegister(instr->input());
1578 Register temp = ToRegister(instr->temp()); 1578 Register temp = ToRegister(instr->TempAt(0));
1579 1579
1580 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1580 int true_block = chunk_->LookupDestination(instr->true_block_id());
1581 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1581 int false_block = chunk_->LookupDestination(instr->false_block_id());
1582 1582
1583 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1583 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1584 1584
1585 __ test(input, Immediate(kSmiTagMask)); 1585 __ test(input, Immediate(kSmiTagMask));
1586 __ j(zero, false_label); 1586 __ j(zero, false_label);
1587 1587
1588 __ CmpObjectType(input, instr->TestType(), temp); 1588 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
1589 EmitBranch(true_block, false_block, instr->BranchCondition()); 1589 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1590 } 1590 }
1591 1591
1592 1592
1593 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { 1593 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1594 Register input = ToRegister(instr->input()); 1594 Register input = ToRegister(instr->input());
1595 Register result = ToRegister(instr->result()); 1595 Register result = ToRegister(instr->result());
1596 1596
1597 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1597 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1598 __ mov(result, Handle<Object>(Heap::true_value())); 1598 __ mov(result, Handle<Object>(Heap::true_value()));
1599 __ test(FieldOperand(input, String::kHashFieldOffset), 1599 __ test(FieldOperand(input, String::kHashFieldOffset),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 // comparison. 1672 // comparison.
1673 __ cmp(temp, class_name); 1673 __ cmp(temp, class_name);
1674 // End with the answer in the z flag. 1674 // End with the answer in the z flag.
1675 } 1675 }
1676 1676
1677 1677
1678 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1678 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1679 Register input = ToRegister(instr->input()); 1679 Register input = ToRegister(instr->input());
1680 Register result = ToRegister(instr->result()); 1680 Register result = ToRegister(instr->result());
1681 ASSERT(input.is(result)); 1681 ASSERT(input.is(result));
1682 Register temp = ToRegister(instr->temporary()); 1682 Register temp = ToRegister(instr->TempAt(0));
1683 Handle<String> class_name = instr->hydrogen()->class_name(); 1683 Handle<String> class_name = instr->hydrogen()->class_name();
1684 NearLabel done; 1684 NearLabel done;
1685 Label is_true, is_false; 1685 Label is_true, is_false;
1686 1686
1687 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); 1687 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
1688 1688
1689 __ j(not_equal, &is_false); 1689 __ j(not_equal, &is_false);
1690 1690
1691 __ bind(&is_true); 1691 __ bind(&is_true);
1692 __ mov(result, Handle<Object>(Heap::true_value())); 1692 __ mov(result, Handle<Object>(Heap::true_value()));
1693 __ jmp(&done); 1693 __ jmp(&done);
1694 1694
1695 __ bind(&is_false); 1695 __ bind(&is_false);
1696 __ mov(result, Handle<Object>(Heap::false_value())); 1696 __ mov(result, Handle<Object>(Heap::false_value()));
1697 __ bind(&done); 1697 __ bind(&done);
1698 } 1698 }
1699 1699
1700 1700
1701 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1701 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1702 Register input = ToRegister(instr->input()); 1702 Register input = ToRegister(instr->input());
1703 Register temp = ToRegister(instr->temporary()); 1703 Register temp = ToRegister(instr->TempAt(0));
1704 Register temp2 = ToRegister(instr->temporary2()); 1704 Register temp2 = ToRegister(instr->TempAt(1));
1705 if (input.is(temp)) { 1705 if (input.is(temp)) {
1706 // Swap. 1706 // Swap.
1707 Register swapper = temp; 1707 Register swapper = temp;
1708 temp = temp2; 1708 temp = temp2;
1709 temp2 = swapper; 1709 temp2 = swapper;
1710 } 1710 }
1711 Handle<String> class_name = instr->hydrogen()->class_name(); 1711 Handle<String> class_name = instr->hydrogen()->class_name();
1712 1712
1713 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1713 int true_block = chunk_->LookupDestination(instr->true_block_id());
1714 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1714 int false_block = chunk_->LookupDestination(instr->false_block_id());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 private: 1774 private:
1775 LInstanceOfKnownGlobal* instr_; 1775 LInstanceOfKnownGlobal* instr_;
1776 Label map_check_; 1776 Label map_check_;
1777 }; 1777 };
1778 1778
1779 DeferredInstanceOfKnownGlobal* deferred; 1779 DeferredInstanceOfKnownGlobal* deferred;
1780 deferred = new DeferredInstanceOfKnownGlobal(this, instr); 1780 deferred = new DeferredInstanceOfKnownGlobal(this, instr);
1781 1781
1782 Label done, false_result; 1782 Label done, false_result;
1783 Register object = ToRegister(instr->input()); 1783 Register object = ToRegister(instr->input());
1784 Register temp = ToRegister(instr->temp()); 1784 Register temp = ToRegister(instr->TempAt(0));
1785 1785
1786 // A Smi is not instance of anything. 1786 // A Smi is not instance of anything.
1787 __ test(object, Immediate(kSmiTagMask)); 1787 __ test(object, Immediate(kSmiTagMask));
1788 __ j(zero, &false_result, not_taken); 1788 __ j(zero, &false_result, not_taken);
1789 1789
1790 // This is the inlined call site instanceof cache. The two occourences of the 1790 // This is the inlined call site instanceof cache. The two occourences of the
1791 // hole value will be patched to the last map/result pair generated by the 1791 // hole value will be patched to the last map/result pair generated by the
1792 // instanceof stub. 1792 // instanceof stub.
1793 NearLabel cache_miss; 1793 NearLabel cache_miss;
1794 Register map = ToRegister(instr->temp()); 1794 Register map = ToRegister(instr->TempAt(0));
1795 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 1795 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
1796 __ bind(deferred->map_check()); // Label for calculating code patching. 1796 __ bind(deferred->map_check()); // Label for calculating code patching.
1797 __ cmp(map, Factory::the_hole_value()); // Patched to cached map. 1797 __ cmp(map, Factory::the_hole_value()); // Patched to cached map.
1798 __ j(not_equal, &cache_miss, not_taken); 1798 __ j(not_equal, &cache_miss, not_taken);
1799 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false. 1799 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false.
1800 __ jmp(&done); 1800 __ jmp(&done);
1801 1801
1802 // The inlined call site cache did not match. Check null and string before 1802 // The inlined call site cache did not match. Check null and string before
1803 // calling the deferred code. 1803 // calling the deferred code.
1804 __ bind(&cache_miss); 1804 __ bind(&cache_miss);
(...skipping 27 matching lines...) Expand all
1832 flags | InstanceofStub::kArgsInRegisters); 1832 flags | InstanceofStub::kArgsInRegisters);
1833 flags = static_cast<InstanceofStub::Flags>( 1833 flags = static_cast<InstanceofStub::Flags>(
1834 flags | InstanceofStub::kCallSiteInlineCheck); 1834 flags | InstanceofStub::kCallSiteInlineCheck);
1835 flags = static_cast<InstanceofStub::Flags>( 1835 flags = static_cast<InstanceofStub::Flags>(
1836 flags | InstanceofStub::kReturnTrueFalseObject); 1836 flags | InstanceofStub::kReturnTrueFalseObject);
1837 InstanceofStub stub(flags); 1837 InstanceofStub stub(flags);
1838 1838
1839 // Get the temp register reserved by the instruction. This needs to be edi as 1839 // Get the temp register reserved by the instruction. This needs to be edi as
1840 // its slot of the pushing of safepoint registers is used to communicate the 1840 // its slot of the pushing of safepoint registers is used to communicate the
1841 // offset to the location of the map check. 1841 // offset to the location of the map check.
1842 Register temp = ToRegister(instr->temp()); 1842 Register temp = ToRegister(instr->TempAt(0));
1843 ASSERT(temp.is(edi)); 1843 ASSERT(temp.is(edi));
1844 __ mov(InstanceofStub::right(), Immediate(instr->function())); 1844 __ mov(InstanceofStub::right(), Immediate(instr->function()));
1845 static const int kAdditionalDelta = 13; 1845 static const int kAdditionalDelta = 13;
1846 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 1846 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
1847 Label before_push_delta; 1847 Label before_push_delta;
1848 __ bind(&before_push_delta); 1848 __ bind(&before_push_delta);
1849 __ mov(temp, Immediate(delta)); 1849 __ mov(temp, Immediate(delta));
1850 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp); 1850 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp);
1851 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 1851 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
1852 ASSERT_EQ(kAdditionalDelta, 1852 ASSERT_EQ(kAdditionalDelta,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1966 ASSERT(ToRegister(instr->result()).is(eax)); 1966 ASSERT(ToRegister(instr->result()).is(eax));
1967 1967
1968 __ mov(ecx, instr->name()); 1968 __ mov(ecx, instr->name());
1969 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1969 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1970 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1970 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1971 } 1971 }
1972 1972
1973 1973
1974 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 1974 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
1975 Register function = ToRegister(instr->function()); 1975 Register function = ToRegister(instr->function());
1976 Register temp = ToRegister(instr->temporary()); 1976 Register temp = ToRegister(instr->TempAt(0));
1977 Register result = ToRegister(instr->result()); 1977 Register result = ToRegister(instr->result());
1978 1978
1979 // Check that the function really is a function. 1979 // Check that the function really is a function.
1980 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 1980 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
1981 DeoptimizeIf(not_equal, instr->environment()); 1981 DeoptimizeIf(not_equal, instr->environment());
1982 1982
1983 // Check whether the function has an instance prototype. 1983 // Check whether the function has an instance prototype.
1984 NearLabel non_instance; 1984 NearLabel non_instance;
1985 __ test_b(FieldOperand(result, Map::kBitFieldOffset), 1985 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
1986 1 << Map::kHasNonInstancePrototype); 1986 1 << Map::kHasNonInstancePrototype);
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
2603 int offset = instr->offset(); 2603 int offset = instr->offset();
2604 2604
2605 if (!instr->transition().is_null()) { 2605 if (!instr->transition().is_null()) {
2606 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 2606 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
2607 } 2607 }
2608 2608
2609 // Do the store. 2609 // Do the store.
2610 if (instr->is_in_object()) { 2610 if (instr->is_in_object()) {
2611 __ mov(FieldOperand(object, offset), value); 2611 __ mov(FieldOperand(object, offset), value);
2612 if (instr->needs_write_barrier()) { 2612 if (instr->needs_write_barrier()) {
2613 Register temp = ToRegister(instr->temp()); 2613 Register temp = ToRegister(instr->TempAt(0));
2614 // Update the write barrier for the object for in-object properties. 2614 // Update the write barrier for the object for in-object properties.
2615 __ RecordWrite(object, offset, value, temp); 2615 __ RecordWrite(object, offset, value, temp);
2616 } 2616 }
2617 } else { 2617 } else {
2618 Register temp = ToRegister(instr->temp()); 2618 Register temp = ToRegister(instr->TempAt(0));
2619 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 2619 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
2620 __ mov(FieldOperand(temp, offset), value); 2620 __ mov(FieldOperand(temp, offset), value);
2621 if (instr->needs_write_barrier()) { 2621 if (instr->needs_write_barrier()) {
2622 // Update the write barrier for the properties array. 2622 // Update the write barrier for the properties array.
2623 // object is used as a scratch register. 2623 // object is used as a scratch register.
2624 __ RecordWrite(temp, offset, value, object); 2624 __ RecordWrite(temp, offset, value, object);
2625 } 2625 }
2626 } 2626 }
2627 } 2627 }
2628 2628
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2755 public: 2755 public:
2756 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 2756 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
2757 : LDeferredCode(codegen), instr_(instr) { } 2757 : LDeferredCode(codegen), instr_(instr) { }
2758 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 2758 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
2759 private: 2759 private:
2760 LNumberTagD* instr_; 2760 LNumberTagD* instr_;
2761 }; 2761 };
2762 2762
2763 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2763 XMMRegister input_reg = ToDoubleRegister(instr->input());
2764 Register reg = ToRegister(instr->result()); 2764 Register reg = ToRegister(instr->result());
2765 Register tmp = ToRegister(instr->temp()); 2765 Register tmp = ToRegister(instr->TempAt(0));
2766 2766
2767 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 2767 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
2768 if (FLAG_inline_new) { 2768 if (FLAG_inline_new) {
2769 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 2769 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
2770 } else { 2770 } else {
2771 __ jmp(deferred->entry()); 2771 __ jmp(deferred->entry());
2772 } 2772 }
2773 __ bind(deferred->exit()); 2773 __ bind(deferred->exit());
2774 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 2774 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
2775 } 2775 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
2896 2896
2897 // Reserve space for 64 bit answer. 2897 // Reserve space for 64 bit answer.
2898 __ bind(&convert); 2898 __ bind(&convert);
2899 __ sub(Operand(esp), Immediate(kDoubleSize)); 2899 __ sub(Operand(esp), Immediate(kDoubleSize));
2900 // Do conversion, which cannot fail because we checked the exponent. 2900 // Do conversion, which cannot fail because we checked the exponent.
2901 __ fisttp_d(Operand(esp, 0)); 2901 __ fisttp_d(Operand(esp, 0));
2902 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 2902 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
2903 __ add(Operand(esp), Immediate(kDoubleSize)); 2903 __ add(Operand(esp), Immediate(kDoubleSize));
2904 } else { 2904 } else {
2905 NearLabel deopt; 2905 NearLabel deopt;
2906 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 2906 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
2907 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2907 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
2908 __ cvttsd2si(input_reg, Operand(xmm0)); 2908 __ cvttsd2si(input_reg, Operand(xmm0));
2909 __ cmp(input_reg, 0x80000000u); 2909 __ cmp(input_reg, 0x80000000u);
2910 __ j(not_equal, &done); 2910 __ j(not_equal, &done);
2911 // Check if the input was 0x8000000 (kMinInt). 2911 // Check if the input was 0x8000000 (kMinInt).
2912 // If no, then we got an overflow and we deoptimize. 2912 // If no, then we got an overflow and we deoptimize.
2913 ExternalReference min_int = ExternalReference::address_of_min_int(); 2913 ExternalReference min_int = ExternalReference::address_of_min_int();
2914 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 2914 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
2915 __ ucomisd(xmm_temp, xmm0); 2915 __ ucomisd(xmm_temp, xmm0);
2916 DeoptimizeIf(not_equal, instr->environment()); 2916 DeoptimizeIf(not_equal, instr->environment());
2917 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2917 DeoptimizeIf(parity_even, instr->environment()); // NaN.
2918 } 2918 }
2919 } else { 2919 } else {
2920 // Deoptimize if we don't have a heap number. 2920 // Deoptimize if we don't have a heap number.
2921 DeoptimizeIf(not_equal, instr->environment()); 2921 DeoptimizeIf(not_equal, instr->environment());
2922 2922
2923 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 2923 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
2924 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2924 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
2925 __ cvttsd2si(input_reg, Operand(xmm0)); 2925 __ cvttsd2si(input_reg, Operand(xmm0));
2926 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 2926 __ cvtsi2sd(xmm_temp, Operand(input_reg));
2927 __ ucomisd(xmm0, xmm_temp); 2927 __ ucomisd(xmm0, xmm_temp);
2928 DeoptimizeIf(not_equal, instr->environment()); 2928 DeoptimizeIf(not_equal, instr->environment());
2929 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2929 DeoptimizeIf(parity_even, instr->environment()); // NaN.
2930 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2930 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2931 __ test(input_reg, Operand(input_reg)); 2931 __ test(input_reg, Operand(input_reg));
2932 __ j(not_zero, &done); 2932 __ j(not_zero, &done);
2933 __ movmskpd(input_reg, xmm0); 2933 __ movmskpd(input_reg, xmm0);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 DeoptimizeIf(no_condition, instr->environment()); 3004 DeoptimizeIf(no_condition, instr->environment());
3005 __ bind(&convert); 3005 __ bind(&convert);
3006 // Do conversion, which cannot fail because we checked the exponent. 3006 // Do conversion, which cannot fail because we checked the exponent.
3007 __ fld_d(Operand(esp, 0)); 3007 __ fld_d(Operand(esp, 0));
3008 __ fisttp_d(Operand(esp, 0)); 3008 __ fisttp_d(Operand(esp, 0));
3009 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 3009 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
3010 __ add(Operand(esp), Immediate(kDoubleSize)); 3010 __ add(Operand(esp), Immediate(kDoubleSize));
3011 __ bind(&done); 3011 __ bind(&done);
3012 } else { 3012 } else {
3013 NearLabel done; 3013 NearLabel done;
3014 Register temp_reg = ToRegister(instr->temporary()); 3014 Register temp_reg = ToRegister(instr->TempAt(0));
3015 XMMRegister xmm_scratch = xmm0; 3015 XMMRegister xmm_scratch = xmm0;
3016 3016
3017 // If cvttsd2si succeeded, we're done. Otherwise, we attempt 3017 // If cvttsd2si succeeded, we're done. Otherwise, we attempt
3018 // manual conversion. 3018 // manual conversion.
3019 __ j(not_equal, &done); 3019 __ j(not_equal, &done);
3020 3020
3021 // Get high 32 bits of the input in result_reg and temp_reg. 3021 // Get high 32 bits of the input in result_reg and temp_reg.
3022 __ pshufd(xmm_scratch, input_reg, 1); 3022 __ pshufd(xmm_scratch, input_reg, 1);
3023 __ movd(Operand(temp_reg), xmm_scratch); 3023 __ movd(Operand(temp_reg), xmm_scratch);
3024 __ mov(result_reg, temp_reg); 3024 __ mov(result_reg, temp_reg);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 3092 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
3093 LOperand* input = instr->input(); 3093 LOperand* input = instr->input();
3094 ASSERT(input->IsRegister()); 3094 ASSERT(input->IsRegister());
3095 __ test(ToRegister(input), Immediate(kSmiTagMask)); 3095 __ test(ToRegister(input), Immediate(kSmiTagMask));
3096 DeoptimizeIf(instr->condition(), instr->environment()); 3096 DeoptimizeIf(instr->condition(), instr->environment());
3097 } 3097 }
3098 3098
3099 3099
3100 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3100 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3101 Register input = ToRegister(instr->input()); 3101 Register input = ToRegister(instr->input());
3102 Register temp = ToRegister(instr->temp()); 3102 Register temp = ToRegister(instr->TempAt(0));
3103 InstanceType first = instr->hydrogen()->first(); 3103 InstanceType first = instr->hydrogen()->first();
3104 InstanceType last = instr->hydrogen()->last(); 3104 InstanceType last = instr->hydrogen()->last();
3105 3105
3106 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 3106 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
3107 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3107 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3108 static_cast<int8_t>(first)); 3108 static_cast<int8_t>(first));
3109 3109
3110 // If there is only one type in the interval check for equality. 3110 // If there is only one type in the interval check for equality.
3111 if (first == last) { 3111 if (first == last) {
3112 DeoptimizeIf(not_equal, instr->environment()); 3112 DeoptimizeIf(not_equal, instr->environment());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3145 Handle<JSGlobalPropertyCell> cell = 3145 Handle<JSGlobalPropertyCell> cell =
3146 Factory::NewJSGlobalPropertyCell(prototype); 3146 Factory::NewJSGlobalPropertyCell(prototype);
3147 __ mov(result, Operand::Cell(cell)); 3147 __ mov(result, Operand::Cell(cell));
3148 } else { 3148 } else {
3149 __ mov(result, prototype); 3149 __ mov(result, prototype);
3150 } 3150 }
3151 } 3151 }
3152 3152
3153 3153
3154 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 3154 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
3155 Register reg = ToRegister(instr->temp()); 3155 Register reg = ToRegister(instr->TempAt(0));
3156 3156
3157 Handle<JSObject> holder = instr->holder(); 3157 Handle<JSObject> holder = instr->holder();
3158 Handle<Map> receiver_map = instr->receiver_map(); 3158 Handle<Map> receiver_map = instr->receiver_map();
3159 Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype())); 3159 Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
3160 3160
3161 // Load prototype object. 3161 // Load prototype object.
3162 LoadPrototype(reg, current_prototype); 3162 LoadPrototype(reg, current_prototype);
3163 3163
3164 // Check prototype maps up to the holder. 3164 // Check prototype maps up to the holder.
3165 while (!current_prototype.is_identical_to(holder)) { 3165 while (!current_prototype.is_identical_to(holder)) {
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
3476 ASSERT(!environment->HasBeenRegistered()); 3476 ASSERT(!environment->HasBeenRegistered());
3477 RegisterEnvironmentForDeoptimization(environment); 3477 RegisterEnvironmentForDeoptimization(environment);
3478 ASSERT(osr_pc_offset_ == -1); 3478 ASSERT(osr_pc_offset_ == -1);
3479 osr_pc_offset_ = masm()->pc_offset(); 3479 osr_pc_offset_ = masm()->pc_offset();
3480 } 3480 }
3481 3481
3482 3482
3483 #undef __ 3483 #undef __
3484 3484
3485 } } // namespace v8::internal 3485 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/ia32/lithium-ia32.h » ('j') | src/ia32/lithium-ia32.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698