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 |