OLD | NEW |
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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system. | 419 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system. |
420 desc->reloc_size = | 420 desc->reloc_size = |
421 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos()); | 421 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos()); |
422 desc->origin = this; | 422 desc->origin = this; |
423 } | 423 } |
424 | 424 |
425 | 425 |
426 void Assembler::Align(int m) { | 426 void Assembler::Align(int m) { |
427 ASSERT(IsPowerOf2(m)); | 427 ASSERT(IsPowerOf2(m)); |
428 int delta = (m - (pc_offset() & (m - 1))) & (m - 1); | 428 int delta = (m - (pc_offset() & (m - 1))) & (m - 1); |
429 while (delta >= 9) { | 429 Nop(delta); |
430 nop(9); | |
431 delta -= 9; | |
432 } | |
433 if (delta > 0) { | |
434 nop(delta); | |
435 } | |
436 } | 430 } |
437 | 431 |
438 | 432 |
439 void Assembler::CodeTargetAlign() { | 433 void Assembler::CodeTargetAlign() { |
440 Align(16); // Preferred alignment of jump targets on x64. | 434 Align(16); // Preferred alignment of jump targets on x64. |
441 } | 435 } |
442 | 436 |
443 | 437 |
| 438 bool Assembler::IsNop(Address addr) { |
| 439 Address a = addr; |
| 440 while (*a == 0x66) a++; |
| 441 if (*a == 0x90) return true; |
| 442 if (a[0] == 0xf && a[1] == 0x1f) return true; |
| 443 return false; |
| 444 } |
| 445 |
| 446 |
444 void Assembler::bind_to(Label* L, int pos) { | 447 void Assembler::bind_to(Label* L, int pos) { |
445 ASSERT(!L->is_bound()); // Label may only be bound once. | 448 ASSERT(!L->is_bound()); // Label may only be bound once. |
446 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. | 449 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. |
447 if (L->is_linked()) { | 450 if (L->is_linked()) { |
448 int current = L->pos(); | 451 int current = L->pos(); |
449 int next = long_at(current); | 452 int next = long_at(current); |
450 while (next != current) { | 453 while (next != current) { |
451 // Relative address, relative to point after address. | 454 // Relative address, relative to point after address. |
452 int imm32 = pos - (current + sizeof(int32_t)); | 455 int imm32 = pos - (current + sizeof(int32_t)); |
453 long_at_put(current, imm32); | 456 long_at_put(current, imm32); |
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 | 1759 |
1757 | 1760 |
1758 void Assembler::notl(Register dst) { | 1761 void Assembler::notl(Register dst) { |
1759 EnsureSpace ensure_space(this); | 1762 EnsureSpace ensure_space(this); |
1760 emit_optional_rex_32(dst); | 1763 emit_optional_rex_32(dst); |
1761 emit(0xF7); | 1764 emit(0xF7); |
1762 emit_modrm(0x2, dst); | 1765 emit_modrm(0x2, dst); |
1763 } | 1766 } |
1764 | 1767 |
1765 | 1768 |
1766 void Assembler::nop(int n) { | 1769 void Assembler::Nop(int n) { |
1767 // The recommended muti-byte sequences of NOP instructions from the Intel 64 | 1770 // The recommended muti-byte sequences of NOP instructions from the Intel 64 |
1768 // and IA-32 Architectures Software Developer's Manual. | 1771 // and IA-32 Architectures Software Developer's Manual. |
1769 // | 1772 // |
1770 // Length Assembly Byte Sequence | 1773 // Length Assembly Byte Sequence |
1771 // 2 bytes 66 NOP 66 90H | 1774 // 2 bytes 66 NOP 66 90H |
1772 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H | 1775 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H |
1773 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H | 1776 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H |
1774 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H | 1777 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H |
1775 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H | 1778 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H |
1776 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H | 1779 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H |
1777 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H | 1780 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H |
1778 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 | 1781 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 |
1779 // 00000000H] 00H | 1782 // 00000000H] 00H |
1780 | 1783 |
1781 ASSERT(1 <= n); | |
1782 ASSERT(n <= 9); | |
1783 EnsureSpace ensure_space(this); | 1784 EnsureSpace ensure_space(this); |
1784 switch (n) { | 1785 while (n > 0) { |
1785 case 1: | 1786 switch (n) { |
1786 emit(0x90); | 1787 case 2: |
1787 return; | 1788 emit(0x66); |
1788 case 2: | 1789 case 1: |
1789 emit(0x66); | 1790 emit(0x90); |
1790 emit(0x90); | 1791 return; |
1791 return; | 1792 case 3: |
1792 case 3: | 1793 emit(0x0f); |
1793 emit(0x0f); | 1794 emit(0x1f); |
1794 emit(0x1f); | 1795 emit(0x00); |
1795 emit(0x00); | 1796 return; |
1796 return; | 1797 case 4: |
1797 case 4: | 1798 emit(0x0f); |
1798 emit(0x0f); | 1799 emit(0x1f); |
1799 emit(0x1f); | 1800 emit(0x40); |
1800 emit(0x40); | 1801 emit(0x00); |
1801 emit(0x00); | 1802 return; |
1802 return; | 1803 case 6: |
1803 case 5: | 1804 emit(0x66); |
1804 emit(0x0f); | 1805 case 5: |
1805 emit(0x1f); | 1806 emit(0x0f); |
1806 emit(0x44); | 1807 emit(0x1f); |
1807 emit(0x00); | 1808 emit(0x44); |
1808 emit(0x00); | 1809 emit(0x00); |
1809 return; | 1810 emit(0x00); |
1810 case 6: | 1811 return; |
1811 emit(0x66); | 1812 case 7: |
1812 emit(0x0f); | 1813 emit(0x0f); |
1813 emit(0x1f); | 1814 emit(0x1f); |
1814 emit(0x44); | 1815 emit(0x80); |
1815 emit(0x00); | 1816 emit(0x00); |
1816 emit(0x00); | 1817 emit(0x00); |
1817 return; | 1818 emit(0x00); |
1818 case 7: | 1819 emit(0x00); |
1819 emit(0x0f); | 1820 return; |
1820 emit(0x1f); | 1821 default: |
1821 emit(0x80); | 1822 case 11: |
1822 emit(0x00); | 1823 emit(0x66); |
1823 emit(0x00); | 1824 n--; |
1824 emit(0x00); | 1825 case 10: |
1825 emit(0x00); | 1826 emit(0x66); |
1826 return; | 1827 n--; |
1827 case 8: | 1828 case 9: |
1828 emit(0x0f); | 1829 emit(0x66); |
1829 emit(0x1f); | 1830 n--; |
1830 emit(0x84); | 1831 case 8: |
1831 emit(0x00); | 1832 emit(0x0f); |
1832 emit(0x00); | 1833 emit(0x1f); |
1833 emit(0x00); | 1834 emit(0x84); |
1834 emit(0x00); | 1835 emit(0x00); |
1835 emit(0x00); | 1836 emit(0x00); |
1836 return; | 1837 emit(0x00); |
1837 case 9: | 1838 emit(0x00); |
1838 emit(0x66); | 1839 emit(0x00); |
1839 emit(0x0f); | 1840 n -= 8; |
1840 emit(0x1f); | 1841 } |
1841 emit(0x84); | |
1842 emit(0x00); | |
1843 emit(0x00); | |
1844 emit(0x00); | |
1845 emit(0x00); | |
1846 emit(0x00); | |
1847 return; | |
1848 } | 1842 } |
1849 } | 1843 } |
1850 | 1844 |
1851 | 1845 |
1852 void Assembler::pop(Register dst) { | 1846 void Assembler::pop(Register dst) { |
1853 EnsureSpace ensure_space(this); | 1847 EnsureSpace ensure_space(this); |
1854 emit_optional_rex_32(dst); | 1848 emit_optional_rex_32(dst); |
1855 emit(0x58 | dst.low_bits()); | 1849 emit(0x58 | dst.low_bits()); |
1856 } | 1850 } |
1857 | 1851 |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3026 // specially coded on x64 means that it is a relative 32 bit address, as used | 3020 // specially coded on x64 means that it is a relative 32 bit address, as used |
3027 // by branch instructions. | 3021 // by branch instructions. |
3028 return (1 << rmode_) & kApplyMask; | 3022 return (1 << rmode_) & kApplyMask; |
3029 } | 3023 } |
3030 | 3024 |
3031 | 3025 |
3032 | 3026 |
3033 } } // namespace v8::internal | 3027 } } // namespace v8::internal |
3034 | 3028 |
3035 #endif // V8_TARGET_ARCH_X64 | 3029 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |