OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
9 | 9 |
10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
(...skipping 1579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1590 ASSERT(kSmiTagShift == 1); | 1590 ASSERT(kSmiTagShift == 1); |
1591 __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag); | 1591 __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag); |
1592 __ ldrh(R0, Address(R0, R1)); | 1592 __ ldrh(R0, Address(R0, R1)); |
1593 __ SmiTag(R0); | 1593 __ SmiTag(R0); |
1594 __ Ret(); | 1594 __ Ret(); |
1595 | 1595 |
1596 __ Bind(&fall_through); | 1596 __ Bind(&fall_through); |
1597 } | 1597 } |
1598 | 1598 |
1599 | 1599 |
1600 void GenerateSubstringMatchesSpecialization(Assembler* assembler, | |
1601 intptr_t receiver_cid, | |
1602 intptr_t other_cid, | |
1603 Label* return_true, | |
1604 Label* return_false) { | |
1605 __ SmiUntag(R1); | |
1606 __ ldr(R8, FieldAddress(R0, String::length_offset())); // this.length | |
1607 __ SmiUntag(R8); | |
1608 __ ldr(R9, FieldAddress(R2, String::length_offset())); // other.length | |
1609 __ SmiUntag(R9); | |
1610 | |
1611 // if (other.length == 0) return true; | |
1612 __ cmp(R9, Operand(0)); | |
1613 __ b(return_true, EQ); | |
1614 | |
1615 // if (start < 0) return false; | |
1616 __ cmp(R1, Operand(0)); | |
1617 __ b(return_false, LT); | |
1618 | |
1619 // if (start + other.length > this.length) return false; | |
1620 __ add(R3, R1, Operand(R9)); | |
1621 __ cmp(R3, Operand(R8)); | |
1622 __ b(return_false, GT); | |
1623 | |
1624 if (receiver_cid == kOneByteStringCid) { | |
1625 __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag); | |
1626 __ add(R0, R0, Operand(R1)); | |
1627 } else { | |
1628 ASSERT(receiver_cid == kTwoByteStringCid); | |
1629 __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag); | |
1630 __ add(R0, R0, Operand(R1)); | |
1631 __ add(R0, R0, Operand(R1)); | |
1632 } | |
1633 if (other_cid == kOneByteStringCid) { | |
1634 __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag); | |
1635 } else { | |
1636 ASSERT(other_cid == kTwoByteStringCid); | |
1637 __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag); | |
1638 } | |
1639 | |
1640 // i = 0 | |
1641 __ LoadImmediate(R3, 0); | |
1642 | |
1643 // while (i < len) | |
1644 Label loop; | |
1645 __ Bind(&loop); | |
1646 __ cmp(R3, Operand(R9/*otherlength*/)); | |
Florian Schneider
2015/11/18 10:26:03
s/otherlength/other.length/
| |
1647 __ b(return_true, GE); | |
1648 | |
1649 if (receiver_cid == kOneByteStringCid) { | |
1650 __ ldrb(R4, Address(R0, 0)); // this.codeUnitAt(i + start) | |
1651 } else { | |
1652 __ ldrh(R4, Address(R0, 0)); // this.codeUnitAt(i + start) | |
1653 } | |
1654 if (other_cid == kOneByteStringCid) { | |
1655 __ ldrb(NOTFP, Address(R2, 0)); // other.codeUnitAt(i) | |
1656 } else { | |
1657 __ ldrh(NOTFP, Address(R2, 0)); // other.codeUnitAt(i) | |
1658 } | |
1659 __ cmp(R4, Operand(NOTFP)); | |
1660 __ b(return_false, NE); | |
1661 | |
1662 // i++ | |
1663 __ AddImmediate(R3, R3, 1); | |
1664 __ AddImmediate(R0, R0, receiver_cid == kOneByteStringCid ? 1 : 2); | |
1665 __ AddImmediate(R2, R2, other_cid == kOneByteStringCid ? 1 : 2); | |
1666 __ b(&loop); | |
1667 } | |
1668 | |
1669 | |
1670 // bool _substringMatches(int start, String other) | |
1671 // Clobbers ARGS_DESCRIPTOR_REG. Safe because this method has no optional | |
srdjan
2015/11/18 17:52:54
s/ARGS_DESCRIPTOR_REG/ARGS_DESC_REG/
| |
1672 // parameters. | |
1673 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) { | |
srdjan
2015/11/18 17:52:54
You could push R4 (arg_desc) and restore it when r
rmacnak
2015/11/18 22:33:32
Done.
| |
1674 Label fall_through, return_true, return_false, try_two_byte; | |
1675 __ ldr(R0, Address(SP, 2 * kWordSize)); // this | |
1676 __ ldr(R1, Address(SP, 1 * kWordSize)); // start | |
1677 __ ldr(R2, Address(SP, 0 * kWordSize)); // other | |
1678 | |
1679 __ tst(R1, Operand(kSmiTagMask)); | |
1680 __ b(&fall_through, NE); // Index is not a Smi. | |
srdjan
2015/11/18 17:52:54
'start' is not a smi
rmacnak
2015/11/18 22:33:32
Done.
| |
1681 | |
1682 __ CompareClassId(R2, kOneByteStringCid, R3); | |
srdjan
2015/11/18 17:52:54
Add somewhere (top of function?):
Supports one-
rmacnak
2015/11/18 22:33:32
Done.
| |
1683 __ b(&fall_through, NE); | |
1684 | |
1685 __ CompareClassId(R0, kOneByteStringCid, R3); | |
1686 __ b(&try_two_byte, NE); | |
1687 | |
1688 GenerateSubstringMatchesSpecialization(assembler, | |
1689 kOneByteStringCid, | |
1690 kOneByteStringCid, | |
1691 &return_true, | |
1692 &return_false); | |
1693 | |
1694 __ Bind(&try_two_byte); | |
srdjan
2015/11/18 17:52:54
s/try_two_byte/try_two_byte_this/
| |
1695 __ CompareClassId(R0, kTwoByteStringCid, R3); | |
1696 __ b(&fall_through, NE); | |
1697 | |
1698 GenerateSubstringMatchesSpecialization(assembler, | |
1699 kTwoByteStringCid, | |
1700 kOneByteStringCid, | |
1701 &return_true, | |
1702 &return_false); | |
1703 | |
1704 __ Bind(&return_true); | |
1705 __ LoadObject(R0, Bool::True()); | |
1706 __ Ret(); | |
1707 | |
1708 __ Bind(&return_false); | |
1709 __ LoadObject(R0, Bool::False()); | |
1710 __ Ret(); | |
1711 | |
1712 __ Bind(&fall_through); | |
1713 } | |
1714 | |
1715 | |
1600 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { | 1716 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { |
1601 Label fall_through, try_two_byte_string; | 1717 Label fall_through, try_two_byte_string; |
1602 | 1718 |
1603 __ ldr(R1, Address(SP, 0 * kWordSize)); // Index. | 1719 __ ldr(R1, Address(SP, 0 * kWordSize)); // Index. |
1604 __ ldr(R0, Address(SP, 1 * kWordSize)); // String. | 1720 __ ldr(R0, Address(SP, 1 * kWordSize)); // String. |
1605 __ tst(R1, Operand(kSmiTagMask)); | 1721 __ tst(R1, Operand(kSmiTagMask)); |
1606 __ b(&fall_through, NE); // Index is not a Smi. | 1722 __ b(&fall_through, NE); // Index is not a Smi. |
1607 // Range check. | 1723 // Range check. |
1608 __ ldr(R2, FieldAddress(R0, String::length_offset())); | 1724 __ ldr(R2, FieldAddress(R0, String::length_offset())); |
1609 __ cmp(R1, Operand(R2)); | 1725 __ cmp(R1, Operand(R2)); |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2003 | 2119 |
2004 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { | 2120 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { |
2005 __ LoadIsolate(R0); | 2121 __ LoadIsolate(R0); |
2006 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); | 2122 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); |
2007 __ Ret(); | 2123 __ Ret(); |
2008 } | 2124 } |
2009 | 2125 |
2010 } // namespace dart | 2126 } // namespace dart |
2011 | 2127 |
2012 #endif // defined TARGET_ARCH_ARM | 2128 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |