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 |