| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1582 break; | 1582 break; |
| 1583 } | 1583 } |
| 1584 | 1584 |
| 1585 default: | 1585 default: |
| 1586 UNREACHABLE(); | 1586 UNREACHABLE(); |
| 1587 break; | 1587 break; |
| 1588 } | 1588 } |
| 1589 } | 1589 } |
| 1590 | 1590 |
| 1591 | 1591 |
| 1592 void CodeGenerator::Comparison(Condition cc, | 1592 void CodeGenerator::Comparison(Condition cond, |
| 1593 Expression* left, | 1593 Expression* left, |
| 1594 Expression* right, | 1594 Expression* right, |
| 1595 bool strict) { | 1595 bool strict) { |
| 1596 VirtualFrame::RegisterAllocationScope scope(this); | 1596 VirtualFrame::RegisterAllocationScope scope(this); |
| 1597 | 1597 |
| 1598 if (left != NULL) Load(left); | 1598 if (left != NULL) Load(left); |
| 1599 if (right != NULL) Load(right); | 1599 if (right != NULL) Load(right); |
| 1600 | 1600 |
| 1601 // sp[0] : y | 1601 // sp[0] : y |
| 1602 // sp[1] : x | 1602 // sp[1] : x |
| 1603 // result : cc register | 1603 // result : cc register |
| 1604 | 1604 |
| 1605 // Strict only makes sense for equality comparisons. | 1605 // Strict only makes sense for equality comparisons. |
| 1606 ASSERT(!strict || cc == eq); | 1606 ASSERT(!strict || cond == eq); |
| 1607 | 1607 |
| 1608 Register lhs; | 1608 Register lhs; |
| 1609 Register rhs; | 1609 Register rhs; |
| 1610 | 1610 |
| 1611 bool lhs_is_smi; | 1611 bool lhs_is_smi; |
| 1612 bool rhs_is_smi; | 1612 bool rhs_is_smi; |
| 1613 | 1613 |
| 1614 // We load the top two stack positions into registers chosen by the virtual | 1614 // We load the top two stack positions into registers chosen by the virtual |
| 1615 // frame. This should keep the register shuffling to a minimum. | 1615 // frame. This should keep the register shuffling to a minimum. |
| 1616 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. | 1616 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. |
| 1617 if (cc == gt || cc == le) { | 1617 if (cond == gt || cond == le) { |
| 1618 cc = ReverseCondition(cc); | 1618 cond = ReverseCondition(cond); |
| 1619 lhs_is_smi = frame_->KnownSmiAt(0); | 1619 lhs_is_smi = frame_->KnownSmiAt(0); |
| 1620 rhs_is_smi = frame_->KnownSmiAt(1); | 1620 rhs_is_smi = frame_->KnownSmiAt(1); |
| 1621 lhs = frame_->PopToRegister(); | 1621 lhs = frame_->PopToRegister(); |
| 1622 rhs = frame_->PopToRegister(lhs); // Don't pop to the same register again! | 1622 rhs = frame_->PopToRegister(lhs); // Don't pop to the same register again! |
| 1623 } else { | 1623 } else { |
| 1624 rhs_is_smi = frame_->KnownSmiAt(0); | 1624 rhs_is_smi = frame_->KnownSmiAt(0); |
| 1625 lhs_is_smi = frame_->KnownSmiAt(1); | 1625 lhs_is_smi = frame_->KnownSmiAt(1); |
| 1626 rhs = frame_->PopToRegister(); | 1626 rhs = frame_->PopToRegister(); |
| 1627 lhs = frame_->PopToRegister(rhs); // Don't pop to the same register again! | 1627 lhs = frame_->PopToRegister(rhs); // Don't pop to the same register again! |
| 1628 } | 1628 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1648 __ orr(scratch, lhs, Operand(rhs)); | 1648 __ orr(scratch, lhs, Operand(rhs)); |
| 1649 smi_test_reg = scratch; | 1649 smi_test_reg = scratch; |
| 1650 } | 1650 } |
| 1651 __ tst(smi_test_reg, Operand(kSmiTagMask)); | 1651 __ tst(smi_test_reg, Operand(kSmiTagMask)); |
| 1652 JumpTarget smi; | 1652 JumpTarget smi; |
| 1653 smi.Branch(eq); | 1653 smi.Branch(eq); |
| 1654 | 1654 |
| 1655 // Perform non-smi comparison by stub. | 1655 // Perform non-smi comparison by stub. |
| 1656 // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0. | 1656 // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0. |
| 1657 // We call with 0 args because there are 0 on the stack. | 1657 // We call with 0 args because there are 0 on the stack. |
| 1658 CompareStub stub(cc, strict, NO_SMI_COMPARE_IN_STUB, lhs, rhs); | 1658 CompareStub stub(cond, strict, NO_SMI_COMPARE_IN_STUB, lhs, rhs); |
| 1659 frame_->CallStub(&stub, 0); | 1659 frame_->CallStub(&stub, 0); |
| 1660 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 1660 __ cmp(r0, Operand(0, RelocInfo::NONE)); |
| 1661 exit.Jump(); | 1661 exit.Jump(); |
| 1662 | 1662 |
| 1663 smi.Bind(); | 1663 smi.Bind(); |
| 1664 } | 1664 } |
| 1665 | 1665 |
| 1666 // Do smi comparisons by pointer comparison. | 1666 // Do smi comparisons by pointer comparison. |
| 1667 __ cmp(lhs, Operand(rhs)); | 1667 __ cmp(lhs, Operand(rhs)); |
| 1668 | 1668 |
| 1669 exit.Bind(); | 1669 exit.Bind(); |
| 1670 cc_reg_ = cc; | 1670 cc_reg_ = cond; |
| 1671 } | 1671 } |
| 1672 | 1672 |
| 1673 | 1673 |
| 1674 // Call the function on the stack with the given arguments. | 1674 // Call the function on the stack with the given arguments. |
| 1675 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, | 1675 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
| 1676 CallFunctionFlags flags, | 1676 CallFunctionFlags flags, |
| 1677 int position) { | 1677 int position) { |
| 1678 // Push the arguments ("left-to-right") on the stack. | 1678 // Push the arguments ("left-to-right") on the stack. |
| 1679 int arg_count = args->length(); | 1679 int arg_count = args->length(); |
| 1680 for (int i = 0; i < arg_count; i++) { | 1680 for (int i = 0; i < arg_count; i++) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1878 // sp[0]: result | 1878 // sp[0]: result |
| 1879 __ bind(&done); | 1879 __ bind(&done); |
| 1880 | 1880 |
| 1881 // Restore the context register after a call. | 1881 // Restore the context register after a call. |
| 1882 __ ldr(cp, frame_->Context()); | 1882 __ ldr(cp, frame_->Context()); |
| 1883 } | 1883 } |
| 1884 | 1884 |
| 1885 | 1885 |
| 1886 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { | 1886 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { |
| 1887 ASSERT(has_cc()); | 1887 ASSERT(has_cc()); |
| 1888 Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_); | 1888 Condition cond = if_true ? cc_reg_ : NegateCondition(cc_reg_); |
| 1889 target->Branch(cc); | 1889 target->Branch(cond); |
| 1890 cc_reg_ = al; | 1890 cc_reg_ = al; |
| 1891 } | 1891 } |
| 1892 | 1892 |
| 1893 | 1893 |
| 1894 void CodeGenerator::CheckStack() { | 1894 void CodeGenerator::CheckStack() { |
| 1895 frame_->SpillAll(); | 1895 frame_->SpillAll(); |
| 1896 Comment cmnt(masm_, "[ check stack"); | 1896 Comment cmnt(masm_, "[ check stack"); |
| 1897 __ LoadRoot(ip, Heap::kStackLimitRootIndex); | 1897 __ LoadRoot(ip, Heap::kStackLimitRootIndex); |
| 1898 masm_->cmp(sp, Operand(ip)); | 1898 masm_->cmp(sp, Operand(ip)); |
| 1899 StackCheckStub stub; | 1899 StackCheckStub stub; |
| (...skipping 3665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5565 DeferredSwapElements* deferred = | 5565 DeferredSwapElements* deferred = |
| 5566 new DeferredSwapElements(object, index1, index2); | 5566 new DeferredSwapElements(object, index1, index2); |
| 5567 | 5567 |
| 5568 // Fetch the map and check if array is in fast case. | 5568 // Fetch the map and check if array is in fast case. |
| 5569 // Check that object doesn't require security checks and | 5569 // Check that object doesn't require security checks and |
| 5570 // has no indexed interceptor. | 5570 // has no indexed interceptor. |
| 5571 __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE); | 5571 __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE); |
| 5572 deferred->Branch(lt); | 5572 deferred->Branch(lt); |
| 5573 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset)); | 5573 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset)); |
| 5574 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); | 5574 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); |
| 5575 deferred->Branch(nz); | 5575 deferred->Branch(ne); |
| 5576 | 5576 |
| 5577 // Check the object's elements are in fast case and writable. | 5577 // Check the object's elements are in fast case and writable. |
| 5578 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset)); | 5578 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset)); |
| 5579 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset)); | 5579 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset)); |
| 5580 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 5580 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| 5581 __ cmp(tmp2, ip); | 5581 __ cmp(tmp2, ip); |
| 5582 deferred->Branch(ne); | 5582 deferred->Branch(ne); |
| 5583 | 5583 |
| 5584 // Smi-tagging is equivalent to multiplying by 2. | 5584 // Smi-tagging is equivalent to multiplying by 2. |
| 5585 STATIC_ASSERT(kSmiTag == 0); | 5585 STATIC_ASSERT(kSmiTag == 0); |
| 5586 STATIC_ASSERT(kSmiTagSize == 1); | 5586 STATIC_ASSERT(kSmiTagSize == 1); |
| 5587 | 5587 |
| 5588 // Check that both indices are smis. | 5588 // Check that both indices are smis. |
| 5589 __ mov(tmp2, index1); | 5589 __ mov(tmp2, index1); |
| 5590 __ orr(tmp2, tmp2, index2); | 5590 __ orr(tmp2, tmp2, index2); |
| 5591 __ tst(tmp2, Operand(kSmiTagMask)); | 5591 __ tst(tmp2, Operand(kSmiTagMask)); |
| 5592 deferred->Branch(nz); | 5592 deferred->Branch(ne); |
| 5593 | 5593 |
| 5594 // Check that both indices are valid. | 5594 // Check that both indices are valid. |
| 5595 __ ldr(tmp2, FieldMemOperand(object, JSArray::kLengthOffset)); | 5595 __ ldr(tmp2, FieldMemOperand(object, JSArray::kLengthOffset)); |
| 5596 __ cmp(tmp2, index1); | 5596 __ cmp(tmp2, index1); |
| 5597 __ cmp(tmp2, index2, hi); | 5597 __ cmp(tmp2, index2, hi); |
| 5598 deferred->Branch(ls); | 5598 deferred->Branch(ls); |
| 5599 | 5599 |
| 5600 // Bring the offsets into the fixed array in tmp1 into index1 and | 5600 // Bring the offsets into the fixed array in tmp1 into index1 and |
| 5601 // index2. | 5601 // index2. |
| 5602 __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 5602 __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| (...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7363 BinaryOpIC::GetName(runtime_operands_type_)); | 7363 BinaryOpIC::GetName(runtime_operands_type_)); |
| 7364 return name_; | 7364 return name_; |
| 7365 } | 7365 } |
| 7366 | 7366 |
| 7367 | 7367 |
| 7368 #undef __ | 7368 #undef __ |
| 7369 | 7369 |
| 7370 } } // namespace v8::internal | 7370 } } // namespace v8::internal |
| 7371 | 7371 |
| 7372 #endif // V8_TARGET_ARCH_ARM | 7372 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |