Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 static uint64_t found_by_runtime_probing_only_; | 502 static uint64_t found_by_runtime_probing_only_; |
| 503 | 503 |
| 504 static uint64_t cross_compile_; | 504 static uint64_t cross_compile_; |
| 505 | 505 |
| 506 friend class ExternalReference; | 506 friend class ExternalReference; |
| 507 friend class PlatformFeatureScope; | 507 friend class PlatformFeatureScope; |
| 508 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); | 508 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); |
| 509 }; | 509 }; |
| 510 | 510 |
| 511 | 511 |
| 512 #define ASSEMBLER_INSTRUCTION_LIST(V) \ | 512 #define ASSEMBLER_INSTRUCTION_LIST(V) \ |
| 513 V(mov) | 513 V(add) \ |
| 514 V(idiv) \ | |
| 515 V(imul) \ | |
| 516 V(mov) \ | |
| 517 V(sub) | |
| 514 | 518 |
| 515 | 519 |
| 516 class Assembler : public AssemblerBase { | 520 class Assembler : public AssemblerBase { |
| 517 private: | 521 private: |
| 518 // We check before assembling an instruction that there is sufficient | 522 // We check before assembling an instruction that there is sufficient |
| 519 // space to write an instruction and its relocation information. | 523 // space to write an instruction and its relocation information. |
| 520 // The relocation writer's position must be kGap bytes above the end of | 524 // The relocation writer's position must be kGap bytes above the end of |
| 521 // the generated instructions. This leaves enough space for the | 525 // the generated instructions. This leaves enough space for the |
| 522 // longest possible x64 instruction, 15 bytes, and the longest possible | 526 // longest possible x64 instruction, 15 bytes, and the longest possible |
| 523 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. | 527 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 // There are no versions of these instructions without the suffix. | 661 // There are no versions of these instructions without the suffix. |
| 658 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. | 662 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. |
| 659 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. | 663 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. |
| 660 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. | 664 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. |
| 661 // - Instructions on 64-bit (quadword) operands/registers use 'q'. | 665 // - Instructions on 64-bit (quadword) operands/registers use 'q'. |
| 662 // | 666 // |
| 663 // Some mnemonics, such as "and", are the same as C++ keywords. | 667 // Some mnemonics, such as "and", are the same as C++ keywords. |
| 664 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. | 668 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. |
| 665 | 669 |
| 666 #define DECLARE_INSTRUCTION(instruction) \ | 670 #define DECLARE_INSTRUCTION(instruction) \ |
| 671 template<class P1> \ | |
| 672 void instruction##p(P1 p1) { \ | |
| 673 emit_##instruction(p1, kPointerSize); \ | |
| 674 } \ | |
| 675 \ | |
| 676 template<class P1> \ | |
| 677 void instruction##l(P1 p1) { \ | |
| 678 emit_##instruction(p1, kInt32Size); \ | |
| 679 } \ | |
| 680 \ | |
| 681 template<class P1> \ | |
| 682 void instruction##q(P1 p1) { \ | |
| 683 emit_##instruction(p1, kInt64Size); \ | |
| 684 } \ | |
| 685 \ | |
| 667 template<class P1, class P2> \ | 686 template<class P1, class P2> \ |
| 668 void instruction##p(P1 p1, P2 p2) { \ | 687 void instruction##p(P1 p1, P2 p2) { \ |
| 669 emit_##instruction(p1, p2, kPointerSize); \ | 688 emit_##instruction(p1, p2, kPointerSize); \ |
| 670 } \ | 689 } \ |
| 671 \ | 690 \ |
| 672 template<class P1, class P2> \ | 691 template<class P1, class P2> \ |
| 673 void instruction##l(P1 p1, P2 p2) { \ | 692 void instruction##l(P1 p1, P2 p2) { \ |
| 674 emit_##instruction(p1, p2, kInt32Size); \ | 693 emit_##instruction(p1, p2, kInt32Size); \ |
| 675 } \ | 694 } \ |
| 676 \ | 695 \ |
| 677 template<class P1, class P2> \ | 696 template<class P1, class P2> \ |
| 678 void instruction##q(P1 p1, P2 p2) { \ | 697 void instruction##q(P1 p1, P2 p2) { \ |
| 679 emit_##instruction(p1, p2, kInt64Size); \ | 698 emit_##instruction(p1, p2, kInt64Size); \ |
| 699 } \ | |
| 700 \ | |
| 701 template<class P1, class P2, class P3> \ | |
| 702 void instruction##p(P1 p1, P2 p2, P3 p3) { \ | |
| 703 emit_##instruction(p1, p2, p3, kPointerSize); \ | |
| 704 } \ | |
| 705 \ | |
| 706 template<class P1, class P2, class P3> \ | |
| 707 void instruction##l(P1 p1, P2 p2, P3 p3) { \ | |
| 708 emit_##instruction(p1, p2, p3, kInt32Size); \ | |
| 709 } \ | |
| 710 \ | |
| 711 template<class P1, class P2, class P3> \ | |
| 712 void instruction##q(P1 p1, P2 p2, P3 p3) { \ | |
| 713 emit_##instruction(p1, p2, p3, kInt64Size); \ | |
| 680 } | 714 } |
| 681 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) | 715 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) |
| 682 #undef DECLARE_INSTRUCTION | 716 #undef DECLARE_INSTRUCTION |
| 683 | 717 |
| 684 // Insert the smallest number of nop instructions | 718 // Insert the smallest number of nop instructions |
| 685 // possible to align the pc offset to a multiple | 719 // possible to align the pc offset to a multiple |
| 686 // of m, where m must be a power of 2. | 720 // of m, where m must be a power of 2. |
| 687 void Align(int m); | 721 void Align(int m); |
| 688 void Nop(int bytes = 1); | 722 void Nop(int bytes = 1); |
| 689 // Aligns code to something that's optimal for a jump target for the platform. | 723 // Aligns code to something that's optimal for a jump target for the platform. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 753 // Conditional moves. | 787 // Conditional moves. |
| 754 void cmovq(Condition cc, Register dst, Register src); | 788 void cmovq(Condition cc, Register dst, Register src); |
| 755 void cmovq(Condition cc, Register dst, const Operand& src); | 789 void cmovq(Condition cc, Register dst, const Operand& src); |
| 756 void cmovl(Condition cc, Register dst, Register src); | 790 void cmovl(Condition cc, Register dst, Register src); |
| 757 void cmovl(Condition cc, Register dst, const Operand& src); | 791 void cmovl(Condition cc, Register dst, const Operand& src); |
| 758 | 792 |
| 759 // Exchange two registers | 793 // Exchange two registers |
| 760 void xchgq(Register dst, Register src); | 794 void xchgq(Register dst, Register src); |
| 761 void xchgl(Register dst, Register src); | 795 void xchgl(Register dst, Register src); |
| 762 | 796 |
| 763 // Arithmetics | |
| 764 void addl(Register dst, Register src) { | |
| 765 arithmetic_op_32(0x03, dst, src); | |
| 766 } | |
| 767 | |
| 768 void addl(Register dst, Immediate src) { | |
| 769 immediate_arithmetic_op_32(0x0, dst, src); | |
| 770 } | |
| 771 | |
| 772 void addl(Register dst, const Operand& src) { | |
| 773 arithmetic_op_32(0x03, dst, src); | |
| 774 } | |
| 775 | |
| 776 void addl(const Operand& dst, Immediate src) { | |
| 777 immediate_arithmetic_op_32(0x0, dst, src); | |
| 778 } | |
| 779 | |
| 780 void addl(const Operand& dst, Register src) { | |
| 781 arithmetic_op_32(0x01, src, dst); | |
| 782 } | |
| 783 | |
| 784 void addq(Register dst, Register src) { | |
| 785 arithmetic_op(0x03, dst, src); | |
| 786 } | |
| 787 | |
| 788 void addq(Register dst, const Operand& src) { | |
| 789 arithmetic_op(0x03, dst, src); | |
| 790 } | |
| 791 | |
| 792 void addq(const Operand& dst, Register src) { | |
| 793 arithmetic_op(0x01, src, dst); | |
| 794 } | |
| 795 | |
| 796 void addq(Register dst, Immediate src) { | |
| 797 immediate_arithmetic_op(0x0, dst, src); | |
| 798 } | |
| 799 | |
| 800 void addq(const Operand& dst, Immediate src) { | |
| 801 immediate_arithmetic_op(0x0, dst, src); | |
| 802 } | |
| 803 | |
| 804 void sbbl(Register dst, Register src) { | 797 void sbbl(Register dst, Register src) { |
| 805 arithmetic_op_32(0x1b, dst, src); | 798 arithmetic_op_32(0x1b, dst, src); |
| 806 } | 799 } |
| 807 | 800 |
| 808 void sbbq(Register dst, Register src) { | 801 void sbbq(Register dst, Register src) { |
| 809 arithmetic_op(0x1b, dst, src); | 802 arithmetic_op(0x1b, dst, src); |
| 810 } | 803 } |
| 811 | 804 |
| 812 void cmpb(Register dst, Immediate src) { | 805 void cmpb(Register dst, Immediate src) { |
| 813 immediate_arithmetic_op_8(0x7, dst, src); | 806 immediate_arithmetic_op_8(0x7, dst, src); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 932 void decl(Register dst); | 925 void decl(Register dst); |
| 933 void decl(const Operand& dst); | 926 void decl(const Operand& dst); |
| 934 void decb(Register dst); | 927 void decb(Register dst); |
| 935 void decb(const Operand& dst); | 928 void decb(const Operand& dst); |
| 936 | 929 |
| 937 // Sign-extends rax into rdx:rax. | 930 // Sign-extends rax into rdx:rax. |
| 938 void cqo(); | 931 void cqo(); |
| 939 // Sign-extends eax into edx:eax. | 932 // Sign-extends eax into edx:eax. |
| 940 void cdq(); | 933 void cdq(); |
| 941 | 934 |
| 942 // Divide rdx:rax by src. Quotient in rax, remainder in rdx. | |
| 943 void idivq(Register src); | |
| 944 // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx. | |
| 945 void idivl(Register src); | |
| 946 | |
| 947 // Signed multiply instructions. | |
| 948 void imul(Register src); // rdx:rax = rax * src. | |
| 949 void imul(Register dst, Register src); // dst = dst * src. | |
| 950 void imul(Register dst, const Operand& src); // dst = dst * src. | |
| 951 void imul(Register dst, Register src, Immediate imm); // dst = src * imm. | |
| 952 // Signed 32-bit multiply instructions. | |
| 953 void imull(Register src); // edx:eax = eax * src. | |
| 954 void imull(Register dst, Register src); // dst = dst * src. | |
| 955 void imull(Register dst, const Operand& src); // dst = dst * src. | |
| 956 void imull(Register dst, Register src, Immediate imm); // dst = src * imm. | |
| 957 | |
| 958 void incq(Register dst); | 935 void incq(Register dst); |
| 959 void incq(const Operand& dst); | 936 void incq(const Operand& dst); |
| 960 void incl(Register dst); | 937 void incl(Register dst); |
| 961 void incl(const Operand& dst); | 938 void incl(const Operand& dst); |
| 962 | 939 |
| 963 void lea(Register dst, const Operand& src); | 940 void lea(Register dst, const Operand& src); |
| 964 void leal(Register dst, const Operand& src); | 941 void leal(Register dst, const Operand& src); |
| 965 | 942 |
| 966 // Multiply rax by src, put the result in rdx:rax. | 943 // Multiply rax by src, put the result in rdx:rax. |
| 967 void mul(Register src); | 944 void mul(Register src); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1098 shift_32(dst, 0x5); | 1075 shift_32(dst, 0x5); |
| 1099 } | 1076 } |
| 1100 | 1077 |
| 1101 void shrl(Register dst, Immediate shift_amount) { | 1078 void shrl(Register dst, Immediate shift_amount) { |
| 1102 shift_32(dst, shift_amount, 0x5); | 1079 shift_32(dst, shift_amount, 0x5); |
| 1103 } | 1080 } |
| 1104 | 1081 |
| 1105 void store_rax(void* dst, RelocInfo::Mode mode); | 1082 void store_rax(void* dst, RelocInfo::Mode mode); |
| 1106 void store_rax(ExternalReference ref); | 1083 void store_rax(ExternalReference ref); |
| 1107 | 1084 |
| 1108 void subq(Register dst, Register src) { | |
| 1109 arithmetic_op(0x2B, dst, src); | |
| 1110 } | |
| 1111 | |
| 1112 void subq(Register dst, const Operand& src) { | |
| 1113 arithmetic_op(0x2B, dst, src); | |
| 1114 } | |
| 1115 | |
| 1116 void subq(const Operand& dst, Register src) { | |
| 1117 arithmetic_op(0x29, src, dst); | |
| 1118 } | |
| 1119 | |
| 1120 void subq(Register dst, Immediate src) { | |
| 1121 immediate_arithmetic_op(0x5, dst, src); | |
| 1122 } | |
| 1123 | |
| 1124 void subq(const Operand& dst, Immediate src) { | |
| 1125 immediate_arithmetic_op(0x5, dst, src); | |
| 1126 } | |
| 1127 | |
| 1128 void subl(Register dst, Register src) { | |
| 1129 arithmetic_op_32(0x2B, dst, src); | |
| 1130 } | |
| 1131 | |
| 1132 void subl(Register dst, const Operand& src) { | |
| 1133 arithmetic_op_32(0x2B, dst, src); | |
| 1134 } | |
| 1135 | |
| 1136 void subl(const Operand& dst, Register src) { | |
| 1137 arithmetic_op_32(0x29, src, dst); | |
| 1138 } | |
| 1139 | |
| 1140 void subl(const Operand& dst, Immediate src) { | |
| 1141 immediate_arithmetic_op_32(0x5, dst, src); | |
| 1142 } | |
| 1143 | |
| 1144 void subl(Register dst, Immediate src) { | |
| 1145 immediate_arithmetic_op_32(0x5, dst, src); | |
| 1146 } | |
| 1147 | |
| 1148 void subb(Register dst, Immediate src) { | 1085 void subb(Register dst, Immediate src) { |
| 1149 immediate_arithmetic_op_8(0x5, dst, src); | 1086 immediate_arithmetic_op_8(0x5, dst, src); |
| 1150 } | 1087 } |
| 1151 | 1088 |
| 1152 void testb(Register dst, Register src); | 1089 void testb(Register dst, Register src); |
| 1153 void testb(Register reg, Immediate mask); | 1090 void testb(Register reg, Immediate mask); |
| 1154 void testb(const Operand& op, Immediate mask); | 1091 void testb(const Operand& op, Immediate mask); |
| 1155 void testb(const Operand& op, Register reg); | 1092 void testb(const Operand& op, Register reg); |
| 1156 void testl(Register dst, Register src); | 1093 void testl(Register dst, Register src); |
| 1157 void testl(Register reg, Immediate mask); | 1094 void testl(Register reg, Immediate mask); |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1705 | 1642 |
| 1706 void emit_farith(int b1, int b2, int i); | 1643 void emit_farith(int b1, int b2, int i); |
| 1707 | 1644 |
| 1708 // labels | 1645 // labels |
| 1709 // void print(Label* L); | 1646 // void print(Label* L); |
| 1710 void bind_to(Label* L, int pos); | 1647 void bind_to(Label* L, int pos); |
| 1711 | 1648 |
| 1712 // record reloc info for current pc_ | 1649 // record reloc info for current pc_ |
| 1713 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1650 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
| 1714 | 1651 |
| 1652 // Arithmetics | |
| 1653 void emit_add(Register dst, Register src, int size) { | |
| 1654 if (size == kInt64Size) { | |
| 1655 arithmetic_op(0x03, dst, src); | |
| 1656 } else { | |
| 1657 ASSERT(size == kInt32Size); | |
| 1658 arithmetic_op_32(0x03, dst, src); | |
|
haitao.feng
2014/03/19 15:21:25
The arithmetic_op and arithmetic_op_32 could be un
Toon Verwaest
2014/03/20 10:43:50
Sounds good.
On 2014/03/19 15:21:25, haitao.feng
| |
| 1659 } | |
| 1660 } | |
| 1661 | |
| 1662 void emit_add(Register dst, Immediate src, int size) { | |
| 1663 if (size == kInt64Size) { | |
| 1664 immediate_arithmetic_op(0x0, dst, src); | |
| 1665 } else { | |
| 1666 ASSERT(size == kInt32Size); | |
| 1667 immediate_arithmetic_op_32(0x0, dst, src); | |
| 1668 } | |
| 1669 } | |
| 1670 | |
| 1671 void emit_add(Register dst, const Operand& src, int size) { | |
| 1672 if (size == kInt64Size) { | |
| 1673 arithmetic_op(0x03, dst, src); | |
| 1674 } else { | |
| 1675 ASSERT(size == kInt32Size); | |
| 1676 arithmetic_op_32(0x03, dst, src); | |
| 1677 } | |
| 1678 } | |
| 1679 | |
| 1680 void emit_add(const Operand& dst, Register src, int size) { | |
| 1681 if (size == kInt64Size) { | |
| 1682 arithmetic_op(0x1, src, dst); | |
| 1683 } else { | |
| 1684 ASSERT(size == kInt32Size); | |
| 1685 arithmetic_op_32(0x1, src, dst); | |
| 1686 } | |
| 1687 } | |
| 1688 | |
| 1689 void emit_add(const Operand& dst, Immediate src, int size) { | |
| 1690 if (size == kInt64Size) { | |
| 1691 immediate_arithmetic_op(0x0, dst, src); | |
| 1692 } else { | |
| 1693 ASSERT(size == kInt32Size); | |
| 1694 immediate_arithmetic_op_32(0x0, dst, src); | |
| 1695 } | |
| 1696 } | |
| 1697 | |
| 1698 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. | |
| 1699 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx | |
| 1700 // when size is 32. | |
| 1701 void emit_idiv(Register src, int size); | |
| 1702 | |
| 1703 // Signed multiply instructions. | |
| 1704 // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32. | |
| 1705 void emit_imul(Register src, int size); | |
| 1706 void emit_imul(Register dst, Register src, int size); | |
| 1707 void emit_imul(Register dst, const Operand& src, int size); | |
| 1708 void emit_imul(Register dst, Register src, Immediate imm, int size); | |
| 1709 | |
| 1710 void emit_sub(Register dst, Register src, int size) { | |
| 1711 if (size == kInt64Size) { | |
| 1712 arithmetic_op(0x2B, dst, src); | |
| 1713 } else { | |
| 1714 ASSERT(size == kInt32Size); | |
| 1715 arithmetic_op_32(0x2B, dst, src); | |
| 1716 } | |
| 1717 } | |
| 1718 | |
| 1719 void emit_sub(Register dst, Immediate src, int size) { | |
| 1720 if (size == kInt64Size) { | |
| 1721 immediate_arithmetic_op(0x5, dst, src); | |
| 1722 } else { | |
| 1723 ASSERT(size == kInt32Size); | |
| 1724 immediate_arithmetic_op_32(0x5, dst, src); | |
| 1725 } | |
| 1726 } | |
| 1727 | |
| 1728 void emit_sub(Register dst, const Operand& src, int size) { | |
| 1729 if (size == kInt64Size) { | |
| 1730 arithmetic_op(0x2B, dst, src); | |
| 1731 } else { | |
| 1732 ASSERT(size == kInt32Size); | |
| 1733 arithmetic_op_32(0x2B, dst, src); | |
| 1734 } | |
| 1735 } | |
| 1736 | |
| 1737 void emit_sub(const Operand& dst, Register src, int size) { | |
| 1738 if (size == kInt64Size) { | |
| 1739 arithmetic_op(0x29, src, dst); | |
| 1740 } else { | |
| 1741 ASSERT(size == kInt32Size); | |
| 1742 arithmetic_op_32(0x29, src, dst); | |
| 1743 } | |
| 1744 } | |
| 1745 | |
| 1746 void emit_sub(const Operand& dst, Immediate src, int size) { | |
| 1747 if (size == kInt64Size) { | |
| 1748 immediate_arithmetic_op(0x5, dst, src); | |
| 1749 } else { | |
| 1750 ASSERT(size == kInt32Size); | |
| 1751 immediate_arithmetic_op_32(0x5, dst, src); | |
| 1752 } | |
| 1753 } | |
| 1754 | |
| 1715 void emit_mov(Register dst, const Operand& src, int size); | 1755 void emit_mov(Register dst, const Operand& src, int size); |
| 1716 void emit_mov(Register dst, Register src, int size); | 1756 void emit_mov(Register dst, Register src, int size); |
| 1717 void emit_mov(const Operand& dst, Register src, int size); | 1757 void emit_mov(const Operand& dst, Register src, int size); |
| 1718 void emit_mov(Register dst, Immediate value, int size); | 1758 void emit_mov(Register dst, Immediate value, int size); |
| 1719 void emit_mov(const Operand& dst, Immediate value, int size); | 1759 void emit_mov(const Operand& dst, Immediate value, int size); |
| 1720 | 1760 |
| 1721 friend class CodePatcher; | 1761 friend class CodePatcher; |
| 1722 friend class EnsureSpace; | 1762 friend class EnsureSpace; |
| 1723 friend class RegExpMacroAssemblerX64; | 1763 friend class RegExpMacroAssemblerX64; |
| 1724 | 1764 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1755 private: | 1795 private: |
| 1756 Assembler* assembler_; | 1796 Assembler* assembler_; |
| 1757 #ifdef DEBUG | 1797 #ifdef DEBUG |
| 1758 int space_before_; | 1798 int space_before_; |
| 1759 #endif | 1799 #endif |
| 1760 }; | 1800 }; |
| 1761 | 1801 |
| 1762 } } // namespace v8::internal | 1802 } } // namespace v8::internal |
| 1763 | 1803 |
| 1764 #endif // V8_X64_ASSEMBLER_X64_H_ | 1804 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |