| 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 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 static uint64_t found_by_runtime_probing_only_; | 523 static uint64_t found_by_runtime_probing_only_; |
| 524 | 524 |
| 525 static uint64_t cross_compile_; | 525 static uint64_t cross_compile_; |
| 526 | 526 |
| 527 friend class ExternalReference; | 527 friend class ExternalReference; |
| 528 friend class PlatformFeatureScope; | 528 friend class PlatformFeatureScope; |
| 529 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); | 529 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); |
| 530 }; | 530 }; |
| 531 | 531 |
| 532 | 532 |
| 533 #define ASSEMBLER_INSTRUCTION_LIST(V) \ |
| 534 V(mov) |
| 535 |
| 536 |
| 533 class Assembler : public AssemblerBase { | 537 class Assembler : public AssemblerBase { |
| 534 private: | 538 private: |
| 535 // We check before assembling an instruction that there is sufficient | 539 // We check before assembling an instruction that there is sufficient |
| 536 // space to write an instruction and its relocation information. | 540 // space to write an instruction and its relocation information. |
| 537 // The relocation writer's position must be kGap bytes above the end of | 541 // The relocation writer's position must be kGap bytes above the end of |
| 538 // the generated instructions. This leaves enough space for the | 542 // the generated instructions. This leaves enough space for the |
| 539 // longest possible x64 instruction, 15 bytes, and the longest possible | 543 // longest possible x64 instruction, 15 bytes, and the longest possible |
| 540 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. | 544 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. |
| 541 // (There is a 15 byte limit on x64 instruction length that rules out some | 545 // (There is a 15 byte limit on x64 instruction length that rules out some |
| 542 // otherwise valid instructions.) | 546 // otherwise valid instructions.) |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 // add, sub, and test. | 655 // add, sub, and test. |
| 652 // There are no versions of these instructions without the suffix. | 656 // There are no versions of these instructions without the suffix. |
| 653 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. | 657 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. |
| 654 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. | 658 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. |
| 655 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. | 659 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. |
| 656 // - Instructions on 64-bit (quadword) operands/registers use 'q'. | 660 // - Instructions on 64-bit (quadword) operands/registers use 'q'. |
| 657 // | 661 // |
| 658 // Some mnemonics, such as "and", are the same as C++ keywords. | 662 // Some mnemonics, such as "and", are the same as C++ keywords. |
| 659 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. | 663 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. |
| 660 | 664 |
| 665 #define DECLARE_INSTRUCTION(instruction) \ |
| 666 template<class P1, class P2> \ |
| 667 void instruction##p(P1 p1, P2 p2) { \ |
| 668 emit_##instruction(p1, p2, kPointerSize); \ |
| 669 } \ |
| 670 \ |
| 671 template<class P1, class P2> \ |
| 672 void instruction##l(P1 p1, P2 p2) { \ |
| 673 emit_##instruction(p1, p2, kInt32Size); \ |
| 674 } \ |
| 675 \ |
| 676 template<class P1, class P2> \ |
| 677 void instruction##q(P1 p1, P2 p2) { \ |
| 678 emit_##instruction(p1, p2, kInt64Size); \ |
| 679 } |
| 680 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) |
| 681 #undef DECLARE_INSTRUCTION |
| 682 |
| 661 // Insert the smallest number of nop instructions | 683 // Insert the smallest number of nop instructions |
| 662 // possible to align the pc offset to a multiple | 684 // possible to align the pc offset to a multiple |
| 663 // of m, where m must be a power of 2. | 685 // of m, where m must be a power of 2. |
| 664 void Align(int m); | 686 void Align(int m); |
| 665 void Nop(int bytes = 1); | 687 void Nop(int bytes = 1); |
| 666 // Aligns code to something that's optimal for a jump target for the platform. | 688 // Aligns code to something that's optimal for a jump target for the platform. |
| 667 void CodeTargetAlign(); | 689 void CodeTargetAlign(); |
| 668 | 690 |
| 669 // Stack | 691 // Stack |
| 670 void pushfq(); | 692 void pushfq(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 688 void movb(Register dst, Immediate imm); | 710 void movb(Register dst, Immediate imm); |
| 689 void movb(const Operand& dst, Register src); | 711 void movb(const Operand& dst, Register src); |
| 690 void movb(const Operand& dst, Immediate imm); | 712 void movb(const Operand& dst, Immediate imm); |
| 691 | 713 |
| 692 // Move the low 16 bits of a 64-bit register value to a 16-bit | 714 // Move the low 16 bits of a 64-bit register value to a 16-bit |
| 693 // memory location. | 715 // memory location. |
| 694 void movw(Register dst, const Operand& src); | 716 void movw(Register dst, const Operand& src); |
| 695 void movw(const Operand& dst, Register src); | 717 void movw(const Operand& dst, Register src); |
| 696 void movw(const Operand& dst, Immediate imm); | 718 void movw(const Operand& dst, Immediate imm); |
| 697 | 719 |
| 698 void movl(Register dst, Register src); | |
| 699 void movl(Register dst, const Operand& src); | |
| 700 void movl(const Operand& dst, Register src); | |
| 701 void movl(const Operand& dst, Immediate imm); | |
| 702 // Load a 32-bit immediate value, zero-extended to 64 bits. | |
| 703 void movl(Register dst, Immediate imm32); | |
| 704 | |
| 705 // Move 64 bit register value to 64-bit memory location. | |
| 706 void movq(const Operand& dst, Register src); | |
| 707 // Move 64 bit memory location to 64-bit register value. | |
| 708 void movq(Register dst, const Operand& src); | |
| 709 void movq(Register dst, Register src); | |
| 710 // Sign extends immediate 32-bit value to 64 bits. | |
| 711 void movq(Register dst, Immediate x); | |
| 712 // Move the offset of the label location relative to the current | 720 // Move the offset of the label location relative to the current |
| 713 // position (after the move) to the destination. | 721 // position (after the move) to the destination. |
| 714 void movl(const Operand& dst, Label* src); | 722 void movl(const Operand& dst, Label* src); |
| 715 | 723 |
| 716 // Move sign extended immediate to memory location. | |
| 717 void movq(const Operand& dst, Immediate value); | |
| 718 // Loads a pointer into a register with a relocation mode. | 724 // Loads a pointer into a register with a relocation mode. |
| 719 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); | 725 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); |
| 720 // Loads a 64-bit immediate into a register. | 726 // Loads a 64-bit immediate into a register. |
| 721 void movq(Register dst, int64_t value); | 727 void movq(Register dst, int64_t value); |
| 728 void movq(Register dst, uint64_t value); |
| 722 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); | 729 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); |
| 723 | 730 |
| 724 void movsxbq(Register dst, const Operand& src); | 731 void movsxbq(Register dst, const Operand& src); |
| 725 void movsxwq(Register dst, const Operand& src); | 732 void movsxwq(Register dst, const Operand& src); |
| 726 void movsxlq(Register dst, Register src); | 733 void movsxlq(Register dst, Register src); |
| 727 void movsxlq(Register dst, const Operand& src); | 734 void movsxlq(Register dst, const Operand& src); |
| 728 void movzxbq(Register dst, const Operand& src); | 735 void movzxbq(Register dst, const Operand& src); |
| 729 void movzxbl(Register dst, const Operand& src); | 736 void movzxbl(Register dst, const Operand& src); |
| 730 void movzxwq(Register dst, const Operand& src); | 737 void movzxwq(Register dst, const Operand& src); |
| 731 void movzxwl(Register dst, const Operand& src); | 738 void movzxwl(Register dst, const Operand& src); |
| (...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1583 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); | 1590 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); |
| 1584 | 1591 |
| 1585 // Optionally do as emit_rex_32(Register) if the register number has | 1592 // Optionally do as emit_rex_32(Register) if the register number has |
| 1586 // the high bit set. | 1593 // the high bit set. |
| 1587 inline void emit_optional_rex_32(Register rm_reg); | 1594 inline void emit_optional_rex_32(Register rm_reg); |
| 1588 | 1595 |
| 1589 // Optionally do as emit_rex_32(const Operand&) if the operand register | 1596 // Optionally do as emit_rex_32(const Operand&) if the operand register |
| 1590 // numbers have a high bit set. | 1597 // numbers have a high bit set. |
| 1591 inline void emit_optional_rex_32(const Operand& op); | 1598 inline void emit_optional_rex_32(const Operand& op); |
| 1592 | 1599 |
| 1600 template<class P1> |
| 1601 void emit_rex(P1 p1, int size) { |
| 1602 if (size == kInt64Size) { |
| 1603 emit_rex_64(p1); |
| 1604 } else { |
| 1605 ASSERT(size == kInt32Size); |
| 1606 emit_optional_rex_32(p1); |
| 1607 } |
| 1608 } |
| 1609 |
| 1610 template<class P1, class P2> |
| 1611 void emit_rex(P1 p1, P2 p2, int size) { |
| 1612 if (size == kInt64Size) { |
| 1613 emit_rex_64(p1, p2); |
| 1614 } else { |
| 1615 ASSERT(size == kInt32Size); |
| 1616 emit_optional_rex_32(p1, p2); |
| 1617 } |
| 1618 } |
| 1593 | 1619 |
| 1594 // Emit the ModR/M byte, and optionally the SIB byte and | 1620 // Emit the ModR/M byte, and optionally the SIB byte and |
| 1595 // 1- or 4-byte offset for a memory operand. Also encodes | 1621 // 1- or 4-byte offset for a memory operand. Also encodes |
| 1596 // the second operand of the operation, a register or operation | 1622 // the second operand of the operation, a register or operation |
| 1597 // subcode, into the reg field of the ModR/M byte. | 1623 // subcode, into the reg field of the ModR/M byte. |
| 1598 void emit_operand(Register reg, const Operand& adr) { | 1624 void emit_operand(Register reg, const Operand& adr) { |
| 1599 emit_operand(reg.low_bits(), adr); | 1625 emit_operand(reg.low_bits(), adr); |
| 1600 } | 1626 } |
| 1601 | 1627 |
| 1602 // Emit the ModR/M byte, and optionally the SIB byte and | 1628 // Emit the ModR/M byte, and optionally the SIB byte and |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 | 1694 |
| 1669 void emit_farith(int b1, int b2, int i); | 1695 void emit_farith(int b1, int b2, int i); |
| 1670 | 1696 |
| 1671 // labels | 1697 // labels |
| 1672 // void print(Label* L); | 1698 // void print(Label* L); |
| 1673 void bind_to(Label* L, int pos); | 1699 void bind_to(Label* L, int pos); |
| 1674 | 1700 |
| 1675 // record reloc info for current pc_ | 1701 // record reloc info for current pc_ |
| 1676 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1702 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
| 1677 | 1703 |
| 1704 void emit_mov(Register dst, const Operand& src, int size); |
| 1705 void emit_mov(Register dst, Register src, int size); |
| 1706 void emit_mov(const Operand& dst, Register src, int size); |
| 1707 void emit_mov(Register dst, Immediate value, int size); |
| 1708 void emit_mov(const Operand& dst, Immediate value, int size); |
| 1709 |
| 1678 friend class CodePatcher; | 1710 friend class CodePatcher; |
| 1679 friend class EnsureSpace; | 1711 friend class EnsureSpace; |
| 1680 friend class RegExpMacroAssemblerX64; | 1712 friend class RegExpMacroAssemblerX64; |
| 1681 | 1713 |
| 1682 // code generation | 1714 // code generation |
| 1683 RelocInfoWriter reloc_info_writer; | 1715 RelocInfoWriter reloc_info_writer; |
| 1684 | 1716 |
| 1685 List< Handle<Code> > code_targets_; | 1717 List< Handle<Code> > code_targets_; |
| 1686 | 1718 |
| 1687 PositionsRecorder positions_recorder_; | 1719 PositionsRecorder positions_recorder_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1712 private: | 1744 private: |
| 1713 Assembler* assembler_; | 1745 Assembler* assembler_; |
| 1714 #ifdef DEBUG | 1746 #ifdef DEBUG |
| 1715 int space_before_; | 1747 int space_before_; |
| 1716 #endif | 1748 #endif |
| 1717 }; | 1749 }; |
| 1718 | 1750 |
| 1719 } } // namespace v8::internal | 1751 } } // namespace v8::internal |
| 1720 | 1752 |
| 1721 #endif // V8_X64_ASSEMBLER_X64_H_ | 1753 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |