| 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) \ |
| 513 V(mov) |
| 514 |
| 515 |
| 512 class Assembler : public AssemblerBase { | 516 class Assembler : public AssemblerBase { |
| 513 private: | 517 private: |
| 514 // We check before assembling an instruction that there is sufficient | 518 // We check before assembling an instruction that there is sufficient |
| 515 // space to write an instruction and its relocation information. | 519 // space to write an instruction and its relocation information. |
| 516 // The relocation writer's position must be kGap bytes above the end of | 520 // The relocation writer's position must be kGap bytes above the end of |
| 517 // the generated instructions. This leaves enough space for the | 521 // the generated instructions. This leaves enough space for the |
| 518 // longest possible x64 instruction, 15 bytes, and the longest possible | 522 // longest possible x64 instruction, 15 bytes, and the longest possible |
| 519 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. | 523 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. |
| 520 // (There is a 15 byte limit on x64 instruction length that rules out some | 524 // (There is a 15 byte limit on x64 instruction length that rules out some |
| 521 // otherwise valid instructions.) | 525 // otherwise valid instructions.) |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 // add, sub, and test. | 634 // add, sub, and test. |
| 631 // There are no versions of these instructions without the suffix. | 635 // There are no versions of these instructions without the suffix. |
| 632 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. | 636 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. |
| 633 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. | 637 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. |
| 634 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. | 638 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. |
| 635 // - Instructions on 64-bit (quadword) operands/registers use 'q'. | 639 // - Instructions on 64-bit (quadword) operands/registers use 'q'. |
| 636 // | 640 // |
| 637 // Some mnemonics, such as "and", are the same as C++ keywords. | 641 // Some mnemonics, such as "and", are the same as C++ keywords. |
| 638 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. | 642 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. |
| 639 | 643 |
| 644 #define DECLARE_INSTRUCTION(instruction) \ |
| 645 template<class P1, class P2> \ |
| 646 void instruction##p(P1 p1, P2 p2) { \ |
| 647 emit_##instruction(p1, p2, kPointerSize); \ |
| 648 } \ |
| 649 \ |
| 650 template<class P1, class P2> \ |
| 651 void instruction##l(P1 p1, P2 p2) { \ |
| 652 emit_##instruction(p1, p2, kInt32Size); \ |
| 653 } \ |
| 654 \ |
| 655 template<class P1, class P2> \ |
| 656 void instruction##q(P1 p1, P2 p2) { \ |
| 657 emit_##instruction(p1, p2, kInt64Size); \ |
| 658 } |
| 659 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) |
| 660 #undef DECLARE_INSTRUCTION |
| 661 |
| 640 // Insert the smallest number of nop instructions | 662 // Insert the smallest number of nop instructions |
| 641 // possible to align the pc offset to a multiple | 663 // possible to align the pc offset to a multiple |
| 642 // of m, where m must be a power of 2. | 664 // of m, where m must be a power of 2. |
| 643 void Align(int m); | 665 void Align(int m); |
| 644 void Nop(int bytes = 1); | 666 void Nop(int bytes = 1); |
| 645 // Aligns code to something that's optimal for a jump target for the platform. | 667 // Aligns code to something that's optimal for a jump target for the platform. |
| 646 void CodeTargetAlign(); | 668 void CodeTargetAlign(); |
| 647 | 669 |
| 648 // Stack | 670 // Stack |
| 649 void pushfq(); | 671 void pushfq(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 667 void movb(Register dst, Immediate imm); | 689 void movb(Register dst, Immediate imm); |
| 668 void movb(const Operand& dst, Register src); | 690 void movb(const Operand& dst, Register src); |
| 669 void movb(const Operand& dst, Immediate imm); | 691 void movb(const Operand& dst, Immediate imm); |
| 670 | 692 |
| 671 // Move the low 16 bits of a 64-bit register value to a 16-bit | 693 // Move the low 16 bits of a 64-bit register value to a 16-bit |
| 672 // memory location. | 694 // memory location. |
| 673 void movw(Register dst, const Operand& src); | 695 void movw(Register dst, const Operand& src); |
| 674 void movw(const Operand& dst, Register src); | 696 void movw(const Operand& dst, Register src); |
| 675 void movw(const Operand& dst, Immediate imm); | 697 void movw(const Operand& dst, Immediate imm); |
| 676 | 698 |
| 677 void movl(Register dst, Register src); | |
| 678 void movl(Register dst, const Operand& src); | |
| 679 void movl(const Operand& dst, Register src); | |
| 680 void movl(const Operand& dst, Immediate imm); | |
| 681 // Load a 32-bit immediate value, zero-extended to 64 bits. | |
| 682 void movl(Register dst, Immediate imm32); | |
| 683 | |
| 684 // Move 64 bit register value to 64-bit memory location. | |
| 685 void movq(const Operand& dst, Register src); | |
| 686 // Move 64 bit memory location to 64-bit register value. | |
| 687 void movq(Register dst, const Operand& src); | |
| 688 void movq(Register dst, Register src); | |
| 689 // Sign extends immediate 32-bit value to 64 bits. | |
| 690 void movq(Register dst, Immediate x); | |
| 691 // Move the offset of the label location relative to the current | 699 // Move the offset of the label location relative to the current |
| 692 // position (after the move) to the destination. | 700 // position (after the move) to the destination. |
| 693 void movl(const Operand& dst, Label* src); | 701 void movl(const Operand& dst, Label* src); |
| 694 | 702 |
| 695 // Move sign extended immediate to memory location. | |
| 696 void movq(const Operand& dst, Immediate value); | |
| 697 // Loads a pointer into a register with a relocation mode. | 703 // Loads a pointer into a register with a relocation mode. |
| 698 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); | 704 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); |
| 699 // Loads a 64-bit immediate into a register. | 705 // Loads a 64-bit immediate into a register. |
| 700 void movq(Register dst, int64_t value); | 706 void movq(Register dst, int64_t value); |
| 707 void movq(Register dst, uint64_t value); |
| 701 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); | 708 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); |
| 702 | 709 |
| 703 void movsxbq(Register dst, const Operand& src); | 710 void movsxbq(Register dst, const Operand& src); |
| 704 void movsxwq(Register dst, const Operand& src); | 711 void movsxwq(Register dst, const Operand& src); |
| 705 void movsxlq(Register dst, Register src); | 712 void movsxlq(Register dst, Register src); |
| 706 void movsxlq(Register dst, const Operand& src); | 713 void movsxlq(Register dst, const Operand& src); |
| 707 void movzxbq(Register dst, const Operand& src); | 714 void movzxbq(Register dst, const Operand& src); |
| 708 void movzxbl(Register dst, const Operand& src); | 715 void movzxbl(Register dst, const Operand& src); |
| 709 void movzxwq(Register dst, const Operand& src); | 716 void movzxwq(Register dst, const Operand& src); |
| 710 void movzxwl(Register dst, const Operand& src); | 717 void movzxwl(Register dst, const Operand& src); |
| (...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); | 1569 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); |
| 1563 | 1570 |
| 1564 // Optionally do as emit_rex_32(Register) if the register number has | 1571 // Optionally do as emit_rex_32(Register) if the register number has |
| 1565 // the high bit set. | 1572 // the high bit set. |
| 1566 inline void emit_optional_rex_32(Register rm_reg); | 1573 inline void emit_optional_rex_32(Register rm_reg); |
| 1567 | 1574 |
| 1568 // Optionally do as emit_rex_32(const Operand&) if the operand register | 1575 // Optionally do as emit_rex_32(const Operand&) if the operand register |
| 1569 // numbers have a high bit set. | 1576 // numbers have a high bit set. |
| 1570 inline void emit_optional_rex_32(const Operand& op); | 1577 inline void emit_optional_rex_32(const Operand& op); |
| 1571 | 1578 |
| 1579 template<class P1> |
| 1580 void emit_rex(P1 p1, int size) { |
| 1581 if (size == kInt64Size) { |
| 1582 emit_rex_64(p1); |
| 1583 } else { |
| 1584 ASSERT(size == kInt32Size); |
| 1585 emit_optional_rex_32(p1); |
| 1586 } |
| 1587 } |
| 1588 |
| 1589 template<class P1, class P2> |
| 1590 void emit_rex(P1 p1, P2 p2, int size) { |
| 1591 if (size == kInt64Size) { |
| 1592 emit_rex_64(p1, p2); |
| 1593 } else { |
| 1594 ASSERT(size == kInt32Size); |
| 1595 emit_optional_rex_32(p1, p2); |
| 1596 } |
| 1597 } |
| 1572 | 1598 |
| 1573 // Emit the ModR/M byte, and optionally the SIB byte and | 1599 // Emit the ModR/M byte, and optionally the SIB byte and |
| 1574 // 1- or 4-byte offset for a memory operand. Also encodes | 1600 // 1- or 4-byte offset for a memory operand. Also encodes |
| 1575 // the second operand of the operation, a register or operation | 1601 // the second operand of the operation, a register or operation |
| 1576 // subcode, into the reg field of the ModR/M byte. | 1602 // subcode, into the reg field of the ModR/M byte. |
| 1577 void emit_operand(Register reg, const Operand& adr) { | 1603 void emit_operand(Register reg, const Operand& adr) { |
| 1578 emit_operand(reg.low_bits(), adr); | 1604 emit_operand(reg.low_bits(), adr); |
| 1579 } | 1605 } |
| 1580 | 1606 |
| 1581 // Emit the ModR/M byte, and optionally the SIB byte and | 1607 // Emit the ModR/M byte, and optionally the SIB byte and |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 | 1673 |
| 1648 void emit_farith(int b1, int b2, int i); | 1674 void emit_farith(int b1, int b2, int i); |
| 1649 | 1675 |
| 1650 // labels | 1676 // labels |
| 1651 // void print(Label* L); | 1677 // void print(Label* L); |
| 1652 void bind_to(Label* L, int pos); | 1678 void bind_to(Label* L, int pos); |
| 1653 | 1679 |
| 1654 // record reloc info for current pc_ | 1680 // record reloc info for current pc_ |
| 1655 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1681 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
| 1656 | 1682 |
| 1683 void emit_mov(Register dst, const Operand& src, int size); |
| 1684 void emit_mov(Register dst, Register src, int size); |
| 1685 void emit_mov(const Operand& dst, Register src, int size); |
| 1686 void emit_mov(Register dst, Immediate value, int size); |
| 1687 void emit_mov(const Operand& dst, Immediate value, int size); |
| 1688 |
| 1657 friend class CodePatcher; | 1689 friend class CodePatcher; |
| 1658 friend class EnsureSpace; | 1690 friend class EnsureSpace; |
| 1659 friend class RegExpMacroAssemblerX64; | 1691 friend class RegExpMacroAssemblerX64; |
| 1660 | 1692 |
| 1661 // code generation | 1693 // code generation |
| 1662 RelocInfoWriter reloc_info_writer; | 1694 RelocInfoWriter reloc_info_writer; |
| 1663 | 1695 |
| 1664 List< Handle<Code> > code_targets_; | 1696 List< Handle<Code> > code_targets_; |
| 1665 | 1697 |
| 1666 PositionsRecorder positions_recorder_; | 1698 PositionsRecorder positions_recorder_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1691 private: | 1723 private: |
| 1692 Assembler* assembler_; | 1724 Assembler* assembler_; |
| 1693 #ifdef DEBUG | 1725 #ifdef DEBUG |
| 1694 int space_before_; | 1726 int space_before_; |
| 1695 #endif | 1727 #endif |
| 1696 }; | 1728 }; |
| 1697 | 1729 |
| 1698 } } // namespace v8::internal | 1730 } } // namespace v8::internal |
| 1699 | 1731 |
| 1700 #endif // V8_X64_ASSEMBLER_X64_H_ | 1732 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |