Changeset 69743 in webkit
- Timestamp:
- Oct 13, 2010 11:45:26 PM (14 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r69728 r69743 1 2010-10-13 David Goodwin <david_goodwin@apple.com> 2 3 Reviewed by Oliver Hunt. 4 5 ARMv7 JIT should generated conditional branches when possible 6 https://bugs.webkit.org/show_bug.cgi?id=47384 7 8 Use different jump padding sizes for conditional and unconditional 9 jumps (12 bytes and 10 bytes respectively). This allows the JIT to 10 include the IT instruction as part of the conditional jump sequence 11 which in turn allows it to optimize away the IT using an ARMv7 12 conditional branch instruction. Use 2-byte B(T1) and 4-byte B(T3) for 13 conditional branches when displacement is in range. Also use IT/B(T4) 14 for conditional branch when displacement does not fit in B(T3). 15 16 For unconditional jump, instruction selection options are: 17 B(T2), B(T4), MOVW/MOVT/BX. For conditional jump, instruction selection 18 options are: B(T1), B(T3), IT/B(T4), ITTT/MOVW/MOVT/BX. 19 20 * assembler/ARMv7Assembler.cpp: 21 * assembler/ARMv7Assembler.h: 22 (JSC::ARMv7Assembler::JmpSrc::JmpSrc): 23 (JSC::ARMv7Assembler::ifThenElse): 24 (JSC::ARMv7Assembler::jumpSizeDelta): 25 (JSC::ARMv7Assembler::canCompact): 26 (JSC::ARMv7Assembler::computeJumpType): 27 (JSC::ARMv7Assembler::link): 28 (JSC::ARMv7Assembler::canBeJumpT1): 29 (JSC::ARMv7Assembler::canBeJumpT3): 30 (JSC::ARMv7Assembler::canBeJumpT4): 31 (JSC::ARMv7Assembler::linkJumpT1): 32 (JSC::ARMv7Assembler::linkJumpT3): 33 (JSC::ARMv7Assembler::linkJumpT4): 34 (JSC::ARMv7Assembler::linkConditionalJumpT4): 35 (JSC::ARMv7Assembler::linkBX): 36 (JSC::ARMv7Assembler::linkConditionalBX): 37 (JSC::ARMv7Assembler::linkJumpAbsolute): 38 * assembler/LinkBuffer.h: 39 (JSC::LinkBuffer::linkCode): 40 * assembler/MacroAssemblerARMv7.h: 41 (JSC::MacroAssemblerARMv7::canCompact): 42 (JSC::MacroAssemblerARMv7::computeJumpType): 43 (JSC::MacroAssemblerARMv7::jumpSizeDelta): 44 (JSC::MacroAssemblerARMv7::jump): 45 (JSC::MacroAssemblerARMv7::nearCall): 46 (JSC::MacroAssemblerARMv7::call): 47 (JSC::MacroAssemblerARMv7::ret): 48 (JSC::MacroAssemblerARMv7::tailRecursiveCall): 49 (JSC::MacroAssemblerARMv7::makeJump): 50 (JSC::MacroAssemblerARMv7::makeBranch): 51 1 52 2010-10-13 Fridrich Strba <fridrich.strba@bluewin.ch> 2 53 -
trunk/JavaScriptCore/assembler/ARMv7Assembler.cpp
r69080 r69743 33 33 34 34 const int ARMv7Assembler::JumpSizes[] = { 0xffffffff, sizeof(uint16_t), sizeof(uint16_t), 35 2 * sizeof(uint16_t), 2 * sizeof(uint16_t), 5 * sizeof(uint16_t) }; 35 2 * sizeof(uint16_t), 2 * sizeof(uint16_t), 3 * sizeof(uint16_t), 5 * sizeof(uint16_t), 6 * sizeof(uint16_t) }; 36 const int ARMv7Assembler::JumpPaddingSizes[] = { 0, 5 * sizeof(uint16_t), 6 * sizeof(uint16_t), 37 5 * sizeof(uint16_t), 6 * sizeof(uint16_t) }; 36 38 37 39 } -
trunk/JavaScriptCore/assembler/ARMv7Assembler.h
r69372 r69743 479 479 } Condition; 480 480 481 enum JumpType { Jump NoCondition, JumpCondition, JumpFullSize};482 enum JumpLinkType { LinkInvalid, LinkJumpT 2, LinkConditionalJumpT2,483 LinkJumpT4, LinkConditionalJumpT4, LinkBX, JumpTypeCount };484 static const int JumpSizes[Jump TypeCount];485 enum { JumpPaddingSize = 5 * sizeof(uint16_t) };481 enum JumpType { JumpFixed, JumpNoCondition, JumpCondition, JumpNoConditionFixedSize, JumpConditionFixedSize, JumpTypeCount }; 482 enum JumpLinkType { LinkInvalid, LinkJumpT1, LinkJumpT2, LinkJumpT3, 483 LinkJumpT4, LinkConditionalJumpT4, LinkBX, LinkConditionalBX, JumpLinkTypeCount }; 484 static const int JumpSizes[JumpLinkTypeCount]; 485 static const int JumpPaddingSizes[JumpTypeCount]; 486 486 class LinkRecord { 487 487 public: … … 504 504 intptr_t m_from : 31; 505 505 intptr_t m_to : 31; 506 JumpType m_type : 2;507 JumpLinkType m_linkType : 3;506 JumpType m_type : 3; 507 JumpLinkType m_linkType : 4; 508 508 Condition m_condition : 16; 509 509 }; … … 525 525 , m_type(type) 526 526 { 527 ASSERT(m_type != JumpCondition);527 ASSERT(m_type == JumpFixed || m_type == JumpNoCondition || m_type == JumpNoConditionFixedSize); 528 528 } 529 529 … … 533 533 , m_type(type) 534 534 { 535 ASSERT(m_type == Jump Condition || m_type == JumpFullSize);535 ASSERT(m_type == JumpFixed || m_type == JumpCondition || m_type == JumpConditionFixedSize); 536 536 } 537 537 … … 630 630 631 631 typedef enum { 632 OP_B_T1 = 0xD000, 632 633 OP_B_T2 = 0xE000, 633 634 OP_AND_reg_T2 = 0xEA00, … … 658 659 OP_VMOV_IMM_T2 = 0xEEB0, 659 660 OP_VMRS = 0xEEB0, 661 OP_B_T3a = 0xF000, 660 662 OP_B_T4a = 0xF000, 661 663 OP_AND_imm_T1 = 0xF000, … … 710 712 OP_VSUB_T2b = 0x0A40, 711 713 OP_NOP_T2b = 0x8000, 714 OP_B_T3b = 0x8000, 712 715 OP_B_T4b = 0x9000, 713 716 } OpcodeID2; … … 746 749 | (ifThenElseConditionBit(condition, inst4if) << 1) 747 750 | 1; 748 ASSERT((condition != ConditionAL) || (mask & (mask - 1)));751 ASSERT((condition != ConditionAL) || !(mask & (mask - 1))); 749 752 return (condition << 4) | mask; 750 753 } … … 754 757 | (ifThenElseConditionBit(condition, inst3if) << 2) 755 758 | 2; 756 ASSERT((condition != ConditionAL) || (mask & (mask - 1)));759 ASSERT((condition != ConditionAL) || !(mask & (mask - 1))); 757 760 return (condition << 4) | mask; 758 761 } … … 761 764 int mask = (ifThenElseConditionBit(condition, inst2if) << 3) 762 765 | 4; 763 ASSERT((condition != ConditionAL) || (mask & (mask - 1)));766 ASSERT((condition != ConditionAL) || !(mask & (mask - 1))); 764 767 return (condition << 4) | mask; 765 768 } … … 768 771 { 769 772 int mask = 8; 770 ASSERT((condition != ConditionAL) || (mask & (mask - 1)));771 773 return (condition << 4) | mask; 772 774 } … … 1665 1667 } 1666 1668 1667 int jumpSizeDelta(Jump LinkType jumpLinkType) { return JumpPaddingSize- JumpSizes[jumpLinkType]; }1669 int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return JumpPaddingSizes[jumpType] - JumpSizes[jumpLinkType]; } 1668 1670 1669 1671 // Assembler admin methods: … … 1679 1681 } 1680 1682 1683 bool canCompact(JumpType jumpType) 1684 { 1685 // The following cannot be compacted: 1686 // JumpFixed: represents custom jump sequence 1687 // JumpNoConditionFixedSize: represents unconditional jump that must remain a fixed size 1688 // JumpConditionFixedSize: represents conditional jump that must remain a fixed size 1689 return (jumpType == JumpNoCondition) || (jumpType == JumpCondition); 1690 } 1691 1692 JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) 1693 { 1694 if (jumpType == JumpFixed) 1695 return LinkInvalid; 1696 1697 // for patchable jump we must leave space for the longest code sequence 1698 if (jumpType == JumpNoConditionFixedSize) 1699 return LinkBX; 1700 if (jumpType == JumpConditionFixedSize) 1701 return LinkConditionalBX; 1702 1703 const int paddingSize = JumpPaddingSizes[jumpType]; 1704 bool mayTriggerErrata = false; 1705 1706 if (jumpType == JumpCondition) { 1707 // 2-byte conditional T1 1708 const uint16_t* jumpT1Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT1])); 1709 if (canBeJumpT1(jumpT1Location, to)) 1710 return LinkJumpT1; 1711 // 4-byte conditional T3 1712 const uint16_t* jumpT3Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT3])); 1713 if (canBeJumpT3(jumpT3Location, to, mayTriggerErrata)) { 1714 if (!mayTriggerErrata) 1715 return LinkJumpT3; 1716 } 1717 // 4-byte conditional T4 with IT 1718 const uint16_t* conditionalJumpT4Location = 1719 reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkConditionalJumpT4])); 1720 if (canBeJumpT4(conditionalJumpT4Location, to, mayTriggerErrata)) { 1721 if (!mayTriggerErrata) 1722 return LinkConditionalJumpT4; 1723 } 1724 } else { 1725 // 2-byte unconditional T2 1726 const uint16_t* jumpT2Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT2])); 1727 if (canBeJumpT2(jumpT2Location, to)) 1728 return LinkJumpT2; 1729 // 4-byte unconditional T4 1730 const uint16_t* jumpT4Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT4])); 1731 if (canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) { 1732 if (!mayTriggerErrata) 1733 return LinkJumpT4; 1734 } 1735 // use long jump sequence 1736 return LinkBX; 1737 } 1738 1739 ASSERT(jumpType == JumpCondition); 1740 return LinkConditionalBX; 1741 } 1742 1681 1743 JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) 1682 1744 { 1683 if (record.type() >= JumpFullSize) { 1684 record.setLinkType(LinkBX); 1685 return LinkBX; 1686 } 1687 const uint16_t* jumpT2Location = reinterpret_cast<const uint16_t*>(from - (JumpPaddingSize - JumpSizes[LinkJumpT2])); 1688 if (canBeJumpT2(jumpT2Location, to)) { 1689 if (record.type() == JumpCondition) { 1690 record.setLinkType(LinkConditionalJumpT2); 1691 return LinkConditionalJumpT2; 1692 } 1693 record.setLinkType(LinkJumpT2); 1694 return LinkJumpT2; 1695 } 1696 bool mayTriggerErrata = false; 1697 const uint16_t* jumpT4Location = reinterpret_cast<const uint16_t*>(from - (JumpPaddingSize - JumpSizes[LinkJumpT4])); 1698 if (!canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) { 1699 record.setLinkType(LinkBX); 1700 return LinkBX; 1701 } 1702 if (mayTriggerErrata) { 1703 record.setLinkType(LinkBX); 1704 return LinkBX; 1705 } 1706 if (record.type() == JumpCondition) { 1707 record.setLinkType(LinkConditionalJumpT4); 1708 return LinkConditionalJumpT4; 1709 } 1710 record.setLinkType(LinkJumpT4); 1711 return LinkJumpT4; 1712 } 1713 1745 JumpLinkType linkType = computeJumpType(record.type(), from, to); 1746 record.setLinkType(linkType); 1747 return linkType; 1748 } 1749 1714 1750 void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) 1715 1751 { … … 1729 1765 void link(LinkRecord& record, uint8_t* from, uint8_t* to) 1730 1766 { 1731 JumpLinkType linkType = record.linkType(); 1732 ASSERT(linkType != LinkInvalid); 1733 if ((linkType == LinkConditionalJumpT2) || (linkType == LinkConditionalJumpT4)) { 1734 uint16_t* itttLocation = reinterpret_cast<uint16_t*>(from - JumpSizes[linkType] - 2); 1735 itttLocation[0] = ifThenElse(record.condition()) | OP_IT; 1736 } 1737 switch (linkType) { 1767 switch (record.linkType()) { 1768 case LinkJumpT1: 1769 linkJumpT1(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1770 break; 1738 1771 case LinkJumpT2: 1739 case LinkConditionalJumpT2:1740 1772 linkJumpT2(reinterpret_cast<uint16_t*>(from), to); 1741 1773 break; 1774 case LinkJumpT3: 1775 linkJumpT3(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1776 break; 1742 1777 case LinkJumpT4: 1778 linkJumpT4(reinterpret_cast<uint16_t*>(from), to); 1779 break; 1743 1780 case LinkConditionalJumpT4: 1744 linkJumpT4(reinterpret_cast<uint16_t*>(from), to); 1781 linkConditionalJumpT4(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1782 break; 1783 case LinkConditionalBX: 1784 linkConditionalBX(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1745 1785 break; 1746 1786 case LinkBX: … … 1970 2010 } 1971 2011 2012 static bool canBeJumpT1(const uint16_t* instruction, const void* target) 2013 { 2014 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2015 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2016 2017 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2018 // It does not appear to be documented in the ARM ARM (big surprise), but 2019 // for OP_B_T1 the branch displacement encoded in the instruction is 2 2020 // less than the actual displacement. 2021 relative -= 2; 2022 return ((relative << 23) >> 23) == relative; 2023 } 2024 1972 2025 static bool canBeJumpT2(const uint16_t* instruction, const void* target) 1973 2026 { … … 1981 2034 relative -= 2; 1982 2035 return ((relative << 20) >> 20) == relative; 2036 } 2037 2038 static bool canBeJumpT3(const uint16_t* instruction, const void* target, bool& mayTriggerErrata) 2039 { 2040 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2041 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2042 2043 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2044 // From Cortex-A8 errata: 2045 // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and 2046 // the target of the branch falls within the first region it is 2047 // possible for the processor to incorrectly determine the branch 2048 // instruction, and it is also possible in some cases for the processor 2049 // to enter a deadlock state. 2050 // The instruction is spanning two pages if it ends at an address ending 0x002 2051 bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002); 2052 mayTriggerErrata = spansTwo4K; 2053 // The target is in the first page if the jump branch back by [3..0x1002] bytes 2054 bool targetInFirstPage = (relative >= -0x1002) && (relative < -2); 2055 bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage; 2056 return ((relative << 11) >> 11) == relative && !wouldTriggerA8Errata; 1983 2057 } 1984 2058 … … 2003 2077 return ((relative << 7) >> 7) == relative && !wouldTriggerA8Errata; 2004 2078 } 2005 2006 static void linkBX(uint16_t* instruction, void* target) 2007 { 2008 linkJumpAbsolute(instruction, target); 2009 } 2010 2011 static void linkJumpT4(uint16_t* instruction, void* target) 2079 2080 void linkJumpT1(Condition cond, uint16_t* instruction, void* target) 2012 2081 { 2013 2082 // FIMXE: this should be up in the MacroAssembler layer. :-( 2014 2083 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2015 2084 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2085 ASSERT(canBeJumpT1(instruction, target)); 2016 2086 2017 2087 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2018 bool scratch; 2019 UNUSED_PARAM(scratch); 2020 ASSERT(canBeJumpT4(instruction, target, scratch)); 2021 // ARM encoding for the top two bits below the sign bit is 'peculiar'. 2022 if (relative >= 0) 2023 relative ^= 0xC00000; 2024 2088 // It does not appear to be documented in the ARM ARM (big surprise), but 2089 // for OP_B_T1 the branch displacement encoded in the instruction is 2 2090 // less than the actual displacement. 2091 relative -= 2; 2092 2025 2093 // All branch offsets should be an even distance. 2026 2094 ASSERT(!(relative & 1)); 2027 instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); 2028 instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); 2029 } 2030 2095 instruction[-1] = OP_B_T1 | ((cond & 0xf) << 8) | ((relative & 0x1fe) >> 1); 2096 } 2097 2031 2098 static void linkJumpT2(uint16_t* instruction, void* target) 2032 2099 { … … 2047 2114 } 2048 2115 2049 static void linkJumpAbsolute(uint16_t* instruction, void* target)2116 void linkJumpT3(Condition cond, uint16_t* instruction, void* target) 2050 2117 { 2051 2118 // FIMXE: this should be up in the MacroAssembler layer. :-( 2052 2119 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2053 2120 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2054 2121 bool scratch; 2122 UNUSED_PARAM(scratch); 2123 ASSERT(canBeJumpT3(instruction, target, scratch)); 2124 2125 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2126 2127 // All branch offsets should be an even distance. 2128 ASSERT(!(relative & 1)); 2129 instruction[-2] = OP_B_T3a | ((relative & 0x100000) >> 10) | ((cond & 0xf) << 6) | ((relative & 0x3f000) >> 12); 2130 instruction[-1] = OP_B_T3b | ((relative & 0x80000) >> 8) | ((relative & 0x40000) >> 5) | ((relative & 0xffe) >> 1); 2131 } 2132 2133 static void linkJumpT4(uint16_t* instruction, void* target) 2134 { 2135 // FIMXE: this should be up in the MacroAssembler layer. :-( 2136 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2137 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2138 bool scratch; 2139 UNUSED_PARAM(scratch); 2140 ASSERT(canBeJumpT4(instruction, target, scratch)); 2141 2142 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2143 // ARM encoding for the top two bits below the sign bit is 'peculiar'. 2144 if (relative >= 0) 2145 relative ^= 0xC00000; 2146 2147 // All branch offsets should be an even distance. 2148 ASSERT(!(relative & 1)); 2149 instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); 2150 instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); 2151 } 2152 2153 void linkConditionalJumpT4(Condition cond, uint16_t* instruction, void* target) 2154 { 2155 // FIMXE: this should be up in the MacroAssembler layer. :-( 2156 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2157 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2158 2159 instruction[-3] = ifThenElse(cond) | OP_IT; 2160 linkJumpT4(instruction, target); 2161 } 2162 2163 static void linkBX(uint16_t* instruction, void* target) 2164 { 2165 // FIMXE: this should be up in the MacroAssembler layer. :-( 2166 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2167 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2168 2169 const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; 2170 ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); 2171 ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); 2172 instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); 2173 instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16); 2174 instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); 2175 instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); 2176 instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); 2177 } 2178 2179 void linkConditionalBX(Condition cond, uint16_t* instruction, void* target) 2180 { 2181 // FIMXE: this should be up in the MacroAssembler layer. :-( 2182 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2183 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2184 2185 linkBX(instruction, target); 2186 instruction[-6] = ifThenElse(cond, true, true) | OP_IT; 2187 } 2188 2189 static void linkJumpAbsolute(uint16_t* instruction, void* target) 2190 { 2191 // FIMXE: this should be up in the MacroAssembler layer. :-( 2192 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2193 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2194 2055 2195 ASSERT((isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1)) 2056 || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2))); 2057 2058 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2196 || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2))); 2197 2059 2198 bool scratch; 2060 2199 if (canBeJumpT4(instruction, target, scratch)) { 2061 // ARM encoding for the top two bits below the sign bit is 'peculiar'.2062 if (relative >= 0)2063 relative ^= 0xC00000;2064 2065 // All branch offsets should be an even distance.2066 ASSERT(!(relative & 1));2067 2200 // There may be a better way to fix this, but right now put the NOPs first, since in the 2068 2201 // case of an conditional branch this will be coming after an ITTT predicating *three* … … 2073 2206 instruction[-4] = OP_NOP_T2a; 2074 2207 instruction[-3] = OP_NOP_T2b; 2075 instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); 2076 instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); 2208 linkJumpT4(instruction, target); 2077 2209 } else { 2078 2210 const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; … … 2086 2218 } 2087 2219 } 2088 2220 2089 2221 static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm) 2090 2222 { -
trunk/JavaScriptCore/assembler/LinkBuffer.h
r66150 r69743 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 236 236 237 237 JumpLinkType jumpLinkType = m_assembler->computeJumpType(jumpsToLink[i], linkBase + writePtr, target); 238 239 // Step back in the write stream 240 int32_t delta = m_assembler->jumpSizeDelta(jumpLinkType); 241 if (delta) { 242 writePtr -= delta; 243 m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr); 238 // Compact branch if we can... 239 if (m_assembler->canCompact(jumpsToLink[i].type())) { 240 // Step back in the write stream 241 int32_t delta = m_assembler->jumpSizeDelta(jumpsToLink[i].type(), jumpLinkType); 242 if (delta) { 243 writePtr -= delta; 244 m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr); 245 } 244 246 } 245 247 jumpsToLink[i].setFrom(writePtr); -
trunk/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r65042 r69743 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2010 University of Szeged 4 4 * … … 47 47 public: 48 48 typedef ARMv7Assembler::LinkRecord LinkRecord; 49 typedef ARMv7Assembler::JumpType JumpType; 49 50 typedef ARMv7Assembler::JumpLinkType JumpLinkType; 50 51 … … 58 59 Vector<LinkRecord>& jumpsToLink() { return m_assembler.jumpsToLink(); } 59 60 void* unlinkedCode() { return m_assembler.unlinkedCode(); } 61 bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); } 62 JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(jumpType, from, to); } 60 63 JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(record, from, to); } 61 64 void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) {return m_assembler.recordLinkOffsets(regionStart, regionEnd, offset); } 62 int jumpSizeDelta(Jump LinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpLinkType); }65 int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpType, jumpLinkType); } 63 66 void link(LinkRecord& record, uint8_t* from, uint8_t* to) { return m_assembler.link(record, from, to); } 64 67 … … 987 990 void jump(RegisterID target) 988 991 { 989 m_assembler.bx(target, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition);992 m_assembler.bx(target, ARMv7Assembler::JumpFixed); 990 993 } 991 994 … … 994 997 { 995 998 load32(address, dataTempRegister); 996 m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition);999 m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed); 997 1000 } 998 1001 … … 1083 1086 { 1084 1087 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1085 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpF ullSize), Call::LinkableNear);1088 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::LinkableNear); 1086 1089 } 1087 1090 … … 1089 1092 { 1090 1093 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1091 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpF ullSize), Call::Linkable);1094 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable); 1092 1095 } 1093 1096 1094 1097 Call call(RegisterID target) 1095 1098 { 1096 return Call(m_assembler.blx(target, ARMv7Assembler::JumpF ullSize), Call::None);1099 return Call(m_assembler.blx(target, ARMv7Assembler::JumpFixed), Call::None); 1097 1100 } 1098 1101 … … 1100 1103 { 1101 1104 load32(address, dataTempRegister); 1102 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpF ullSize), Call::None);1105 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::None); 1103 1106 } 1104 1107 1105 1108 void ret() 1106 1109 { 1107 m_assembler.bx(linkRegister, ARMv7Assembler::JumpF ullSize);1110 m_assembler.bx(linkRegister, ARMv7Assembler::JumpFixed); 1108 1111 } 1109 1112 … … 1205 1208 // Like a normal call, but don't link. 1206 1209 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1207 return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpF ullSize), Call::Linkable);1210 return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable); 1208 1211 } 1209 1212 … … 1229 1232 { 1230 1233 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1231 return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::Jump FullSize : ARMv7Assembler::JumpNoCondition);1234 return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition); 1232 1235 } 1233 1236 … … 1236 1239 m_assembler.it(cond, true, true); 1237 1240 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1238 return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::Jump FullSize : ARMv7Assembler::JumpCondition, cond);1241 return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond); 1239 1242 } 1240 1243 ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); }
Note: See TracChangeset
for help on using the changeset viewer.