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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 int32_t value_; | 218 int32_t value_; |
| 219 | 219 |
| 220 friend class Assembler; | 220 friend class Assembler; |
| 221 }; | 221 }; |
| 222 | 222 |
| 223 | 223 |
| 224 // ----------------------------------------------------------------------------- | 224 // ----------------------------------------------------------------------------- |
| 225 // Machine instruction Operands | 225 // Machine instruction Operands |
| 226 | 226 |
| 227 enum ScaleFactor { | 227 enum ScaleFactor { |
| 228 times_1 = 0, | 228 kTimes1 = 0, |
| 229 times_2 = 1, | 229 kTimes2 = 1, |
| 230 times_4 = 2, | 230 kTimes4 = 2, |
| 231 times_8 = 3 | 231 kTimes8 = 3, |
| 232 kTimesIntSize = kTimes4, | |
| 233 kTimesPointerSize = kTimes8 | |
| 232 }; | 234 }; |
| 233 | 235 |
| 234 | 236 |
| 235 class Operand BASE_EMBEDDED { | 237 class Operand BASE_EMBEDDED { |
| 236 public: | 238 public: |
| 237 // [base + disp/r] | 239 // [base + disp/r] |
| 238 INLINE(Operand(Register base, int32_t disp)); | 240 INLINE(Operand(Register base, int32_t disp)); |
| 239 | 241 |
| 240 // [base + index*scale + disp/r] | 242 // [base + index*scale + disp/r] |
| 241 Operand(Register base, | 243 Operand(Register base, |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 | 621 |
| 620 | 622 |
| 621 // Bit operations. | 623 // Bit operations. |
| 622 void bt(const Operand& dst, Register src); | 624 void bt(const Operand& dst, Register src); |
| 623 void bts(const Operand& dst, Register src); | 625 void bts(const Operand& dst, Register src); |
| 624 | 626 |
| 625 // Miscellaneous | 627 // Miscellaneous |
| 626 void hlt(); | 628 void hlt(); |
| 627 void int3(); | 629 void int3(); |
| 628 void nop(); | 630 void nop(); |
| 631 void nop(int n); | |
| 629 void rdtsc(); | 632 void rdtsc(); |
| 630 void ret(int imm16); | 633 void ret(int imm16); |
| 631 | 634 |
| 632 // Label operations & relative jumps (PPUM Appendix D) | 635 // Label operations & relative jumps (PPUM Appendix D) |
| 633 // | 636 // |
| 634 // Takes a branch opcode (cc) and a label (L) and generates | 637 // Takes a branch opcode (cc) and a label (L) and generates |
| 635 // either a backward branch or a forward branch and links it | 638 // either a backward branch or a forward branch and links it |
| 636 // to the label fixup chain. Usage: | 639 // to the label fixup chain. Usage: |
| 637 // | 640 // |
| 638 // Label L; // unbound label | 641 // Label L; // unbound label |
| 639 // j(cc, &L); // forward branch to unbound label | 642 // j(cc, &L); // forward branch to unbound label |
| 640 // bind(&L); // bind label to the current pc | 643 // bind(&L); // bind label to the current pc |
| 641 // j(cc, &L); // backward branch to bound label | 644 // j(cc, &L); // backward branch to bound label |
| 642 // bind(&L); // illegal: a label may be bound only once | 645 // bind(&L); // illegal: a label may be bound only once |
| 643 // | 646 // |
| 644 // Note: The same Label can be used for forward and backward branches | 647 // Note: The same Label can be used for forward and backward branches |
| 645 // but it may be bound only once. | 648 // but it may be bound only once. |
| 646 | 649 |
| 647 void bind(Label* L); // binds an unbound label L to the current code position | 650 void bind(Label* L); // binds an unbound label L to the current code position |
| 648 | 651 |
| 649 // Calls | 652 // Calls |
| 653 // Call near relative 32-bit displacement, relative to next instruction. | |
| 650 void call(Label* L); | 654 void call(Label* L); |
| 651 void call(byte* entry, RelocInfo::Mode rmode); | 655 |
| 652 void call(const Operand& adr); | 656 // Call near absolute indirect, address in register |
| 653 void call(Handle<Code> code, RelocInfo::Mode rmode); | 657 void call(Register adr); |
| 654 | 658 |
| 655 // Jumps | 659 // Jumps |
| 660 // Jump short or near relative. | |
| 656 void jmp(Label* L); // unconditional jump to L | 661 void jmp(Label* L); // unconditional jump to L |
| 657 void jmp(byte* entry, RelocInfo::Mode rmode); | 662 |
| 658 void jmp(const Operand& adr); | 663 // Jump near absolute indirect (r64) |
| 659 void jmp(Handle<Code> code, RelocInfo::Mode rmode); | 664 void jmp(Register adr); |
| 660 | 665 |
| 661 // Conditional jumps | 666 // Conditional jumps |
| 662 void j(Condition cc, Label* L); | 667 void j(Condition cc, Label* L); |
| 663 void j(Condition cc, byte* entry, RelocInfo::Mode rmode); | 668 void j(Condition cc, byte* entry, RelocInfo::Mode rmode); |
| 664 void j(Condition cc, Handle<Code> code); | 669 void j(Condition cc, Handle<Code> code); |
| 665 | 670 |
| 666 // Floating-point operations | 671 // Floating-point operations |
| 667 void fld(int i); | 672 void fld(int i); |
| 668 | 673 |
| 669 void fld1(); | 674 void fld1(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 inline void emitl(uint32_t x); | 813 inline void emitl(uint32_t x); |
| 809 inline void emit(Handle<Object> handle); | 814 inline void emit(Handle<Object> handle); |
| 810 inline void emitq(uint64_t x, RelocInfo::Mode rmode); | 815 inline void emitq(uint64_t x, RelocInfo::Mode rmode); |
| 811 void emit(Immediate x) { emitl(x.value_); } | 816 void emit(Immediate x) { emitl(x.value_); } |
| 812 | 817 |
| 813 // Emits a REX prefix that encodes a 64-bit operand size and | 818 // Emits a REX prefix that encodes a 64-bit operand size and |
| 814 // the top bit of both register codes. | 819 // the top bit of both register codes. |
| 815 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 820 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
| 816 // REX.W is set. | 821 // REX.W is set. |
| 817 inline void emit_rex_64(Register reg, Register rm_reg); | 822 inline void emit_rex_64(Register reg, Register rm_reg); |
| 818 void emit_rex_64(Register rm_reg) { emit_rex_64(rax, rm_reg); } | |
| 819 | 823 |
| 820 // Emits a REX prefix that encodes a 64-bit operand size and | 824 // Emits a REX prefix that encodes a 64-bit operand size and |
| 821 // the top bit of the destination, index, and base register codes. | 825 // the top bit of the destination, index, and base register codes. |
| 822 // The high bit of reg is used for REX.R, the high bit of op's base | 826 // The high bit of reg is used for REX.R, the high bit of op's base |
| 823 // register is used for REX.B, and the high bit of op's index register | 827 // register is used for REX.B, and the high bit of op's index register |
| 824 // is used for REX.X. REX.W is set. | 828 // is used for REX.X. REX.W is set. |
| 825 inline void emit_rex_64(Register reg, const Operand& op); | 829 inline void emit_rex_64(Register reg, const Operand& op); |
| 826 void emit_rex_64(const Operand& op) { emit_rex_64(rax, op); } | 830 |
| 831 // Emits a REX prefix that encodes a 64-bit operand size and | |
| 832 // the top bit of the register code. | |
| 833 // The high bit of register is used for REX.B. | |
| 834 // REX.W is set and REX.R and REX.X are clear. | |
| 835 inline void emit_rex_64(Register rm_reg); | |
| 836 | |
| 837 // Emits a REX prefix that encodes a 64-bit operand size and | |
| 838 // the top bit of the index and base register codes. | |
| 839 // The high bit of op's base register is used for REX.B, and the high | |
| 840 // bit of op's index register is used for REX.X. | |
| 841 // REX.W is set and REX.R clear. | |
| 842 inline void emit_rex_64(const Operand& op); | |
| 827 | 843 |
| 828 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 844 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
| 829 // REX.W is set. | 845 // REX.W is clear. |
| 830 inline void emit_rex_32(Register reg, Register rm_reg); | 846 inline void emit_rex_32(Register reg, Register rm_reg); |
| 831 | 847 |
| 832 // The high bit of reg is used for REX.R, the high bit of op's base | 848 // The high bit of reg is used for REX.R, the high bit of op's base |
| 833 // register is used for REX.B, and the high bit of op's index register | 849 // register is used for REX.B, and the high bit of op's index register |
| 834 // is used for REX.X. REX.W is cleared. | 850 // is used for REX.X. REX.W is cleared. |
| 835 inline void emit_rex_32(Register reg, const Operand& op); | 851 inline void emit_rex_32(Register reg, const Operand& op); |
| 836 | 852 |
| 837 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 853 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
| 838 // REX.W is cleared. If no REX bits are set, no byte is emitted. | 854 // REX.W is cleared. If no REX bits are set, no byte is emitted. |
| 839 inline void emit_optional_rex_32(Register reg, Register rm_reg); | 855 inline void emit_optional_rex_32(Register reg, Register rm_reg); |
| 840 | 856 |
| 841 // The high bit of reg is used for REX.R, the high bit of op's base | 857 // The high bit of reg is used for REX.R, the high bit of op's base |
| 842 // register is used for REX.B, and the high bit of op's index register | 858 // register is used for REX.B, and the high bit of op's index register |
| 843 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing | 859 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing |
| 844 // is emitted. | 860 // is emitted. |
| 845 inline void emit_optional_rex_32(Register reg, const Operand& op); | 861 inline void emit_optional_rex_32(Register reg, const Operand& op); |
| 846 | 862 |
| 847 // Emit the Mod/RM byte, and optionally the SIB byte and | 863 // Emit the Mod/RM byte, and optionally the SIB byte and |
| 848 // 1- or 4-byte offset for a memory operand. Also encodes | 864 // 1- or 4-byte offset for a memory operand. Also encodes |
| 849 // the second operand of the operation, a register or operation | 865 // the second operand of the operation, a register or operation |
| 850 // subcode, into the Mod/RM byte. | 866 // subcode, into the Mod/RM byte. |
| 851 void emit_operand(Register reg, const Operand& adr); | 867 void emit_operand(Register reg, const Operand& adr) { |
| 852 void emit_operand(int op_subcode, const Operand& adr) { | 868 emit_operand(reg.code() & 0x07, adr); |
|
William Hesse
2009/05/29 13:08:00
I would really like to put the & 0x7 into the base
Lasse Reichstein
2009/05/29 13:13:29
There is no need for a register code argument when
| |
| 853 emit_operand(Register::toRegister(op_subcode), adr); | |
| 854 } | 869 } |
| 855 | 870 |
| 871 // Emit the Mod/RM byte, and optionally the SIB byte and | |
| 872 // 1- or 4-byte offset for a memory operand. Also used to encode | |
| 873 // a three-byte opcode extension into the Mod/RM byte. | |
| 874 void emit_operand(int rm, const Operand& adr); | |
| 875 | |
| 856 // Emit the code-object-relative offset of the label's position | 876 // Emit the code-object-relative offset of the label's position |
| 857 inline void emit_code_relative_offset(Label* label); | 877 inline void emit_code_relative_offset(Label* label); |
| 858 | 878 |
| 859 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, | 879 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, |
| 860 // AND, OR, XOR, or CMP. The encodings of these operations are all | 880 // AND, OR, XOR, or CMP. The encodings of these operations are all |
| 861 // similar, differing just in the opcode or in the reg field of the | 881 // similar, differing just in the opcode or in the reg field of the |
| 862 // Mod/RM byte. | 882 // Mod/RM byte. |
| 863 void arithmetic_op(byte opcode, Register dst, Register src); | 883 void arithmetic_op(byte opcode, Register dst, Register src); |
| 864 void arithmetic_op(byte opcode, Register reg, const Operand& op); | 884 void arithmetic_op(byte opcode, Register reg, const Operand& op); |
| 865 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); | 885 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 private: | 945 private: |
| 926 Assembler* assembler_; | 946 Assembler* assembler_; |
| 927 #ifdef DEBUG | 947 #ifdef DEBUG |
| 928 int space_before_; | 948 int space_before_; |
| 929 #endif | 949 #endif |
| 930 }; | 950 }; |
| 931 | 951 |
| 932 } } // namespace v8::internal | 952 } } // namespace v8::internal |
| 933 | 953 |
| 934 #endif // V8_X64_ASSEMBLER_X64_H_ | 954 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |