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 22 matching lines...) Expand all Loading... | |
33 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 33 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
34 | 34 |
35 // A lightweight X64 Assembler. | 35 // A lightweight X64 Assembler. |
36 | 36 |
37 #ifndef V8_X64_ASSEMBLER_X64_H_ | 37 #ifndef V8_X64_ASSEMBLER_X64_H_ |
38 #define V8_X64_ASSEMBLER_X64_H_ | 38 #define V8_X64_ASSEMBLER_X64_H_ |
39 | 39 |
40 namespace v8 { | 40 namespace v8 { |
41 namespace internal { | 41 namespace internal { |
42 | 42 |
43 // Utility functions | |
44 | |
45 // Test whether a 64-bit value is in a specific range. | |
46 static inline bool is_uint32(int64_t x) { | |
47 static const unsigned int kUInt32Mask = 0xffffffff; | |
William Hesse
2009/06/02 13:21:58
Please use the V8_UINT64_C() macro to define a 64-
| |
48 return x == x & kUInt32Mask; | |
49 } | |
50 | |
51 static inline bool is_int32(int64_t x) { | |
52 static const int kMinIntValue = -0x80000000; | |
53 return is_uint32(x - kMinIntValue); | |
54 } | |
55 | |
43 // CPU Registers. | 56 // CPU Registers. |
44 // | 57 // |
45 // 1) We would prefer to use an enum, but enum values are assignment- | 58 // 1) We would prefer to use an enum, but enum values are assignment- |
46 // compatible with int, which has caused code-generation bugs. | 59 // compatible with int, which has caused code-generation bugs. |
47 // | 60 // |
48 // 2) We would prefer to use a class instead of a struct but we don't like | 61 // 2) We would prefer to use a class instead of a struct but we don't like |
49 // the register initialization to depend on the particular initialization | 62 // the register initialization to depend on the particular initialization |
50 // order (which appears to be different on OS X, Linux, and Windows for the | 63 // order (which appears to be different on OS X, Linux, and Windows for the |
51 // installed versions of C++ we tried). Using a struct permits C-style | 64 // installed versions of C++ we tried). Using a struct permits C-style |
52 // "initialization". Also, the Register objects cannot be const as this | 65 // "initialization". Also, the Register objects cannot be const as this |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 void pop(const Operand& dst); | 415 void pop(const Operand& dst); |
403 | 416 |
404 void enter(const Immediate& size); | 417 void enter(const Immediate& size); |
405 void leave(); | 418 void leave(); |
406 | 419 |
407 // Moves | 420 // Moves |
408 void movb(Register dst, const Operand& src); | 421 void movb(Register dst, const Operand& src); |
409 void movb(const Operand& dst, int8_t imm8); | 422 void movb(const Operand& dst, int8_t imm8); |
410 void movb(const Operand& dst, Register src); | 423 void movb(const Operand& dst, Register src); |
411 | 424 |
412 void movq(Register dst, int32_t imm32); | 425 // Load a 32-bit immediate value, zero-extended to 64 bits. |
426 void movl(Register dst, Immediate imm32); | |
427 | |
428 void movq(Register dst, const Operand& src); | |
429 // Sign extends immediate 32-bit value to 64 bits. | |
413 void movq(Register dst, Immediate x); | 430 void movq(Register dst, Immediate x); |
414 void movq(Register dst, const Operand& src); | |
415 void movq(Register dst, Register src); | 431 void movq(Register dst, Register src); |
416 void movq(const Operand& dst, const Immediate& x); | 432 |
433 // Move 64 bit register value to 64-bit memory location. | |
417 void movq(const Operand& dst, Register src); | 434 void movq(const Operand& dst, Register src); |
418 | 435 |
419 // New x64 instructions to load a 64-bit immediate into a register. | 436 // New x64 instructions to load a 64-bit immediate into a register. |
420 // All 64-bit immediates must have a relocation mode. | 437 // All 64-bit immediates must have a relocation mode. |
421 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); | 438 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); |
422 void movq(Register dst, int64_t value, RelocInfo::Mode rmode); | 439 void movq(Register dst, int64_t value, RelocInfo::Mode rmode); |
423 void movq(Register dst, const char* s, RelocInfo::Mode rmode); | 440 void movq(Register dst, const char* s, RelocInfo::Mode rmode); |
424 void movq(Register dst, const ExternalReference& ext, RelocInfo::Mode rmode); | 441 void movq(Register dst, const ExternalReference& ext, RelocInfo::Mode rmode); |
425 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); | 442 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); |
426 | 443 |
444 | |
427 // New x64 instruction to load from an immediate 64-bit pointer into RAX. | 445 // New x64 instruction to load from an immediate 64-bit pointer into RAX. |
428 void load_rax(void* ptr, RelocInfo::Mode rmode); | 446 void load_rax(void* ptr, RelocInfo::Mode rmode); |
429 | 447 |
430 void movsx_b(Register dst, const Operand& src); | 448 void movsx_b(Register dst, const Operand& src); |
431 | 449 |
432 void movsx_w(Register dst, const Operand& src); | 450 void movsx_w(Register dst, const Operand& src); |
433 | 451 |
434 void movzx_b(Register dst, const Operand& src); | 452 void movzx_b(Register dst, const Operand& src); |
435 | 453 |
436 void movzx_w(Register dst, const Operand& src); | 454 void movzx_w(Register dst, const Operand& src); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
843 | 861 |
844 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 862 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
845 // REX.W is clear. | 863 // REX.W is clear. |
846 inline void emit_rex_32(Register reg, Register rm_reg); | 864 inline void emit_rex_32(Register reg, Register rm_reg); |
847 | 865 |
848 // The high bit of reg is used for REX.R, the high bit of op's base | 866 // The high bit of reg is used for REX.R, the high bit of op's base |
849 // register is used for REX.B, and the high bit of op's index register | 867 // register is used for REX.B, and the high bit of op's index register |
850 // is used for REX.X. REX.W is cleared. | 868 // is used for REX.X. REX.W is cleared. |
851 inline void emit_rex_32(Register reg, const Operand& op); | 869 inline void emit_rex_32(Register reg, const Operand& op); |
852 | 870 |
871 // High bit of rm_reg goes to REX.B. | |
872 // REX.W, REX.R and REX.X are clear. | |
873 inline void emit_rex_32(Register rm_reg); | |
874 | |
875 // High bit of base goes to REX.B and high bit of index to REX.X. | |
876 // REX.W and REX.R are clear. | |
877 inline void emit_rex_32(const Operand &); | |
William Hesse
2009/06/03 10:36:09
Operand&, not Operand &
| |
878 | |
853 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 879 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
854 // REX.W is cleared. If no REX bits are set, no byte is emitted. | 880 // REX.W is cleared. If no REX bits are set, no byte is emitted. |
855 inline void emit_optional_rex_32(Register reg, Register rm_reg); | 881 inline void emit_optional_rex_32(Register reg, Register rm_reg); |
856 | 882 |
857 // The high bit of reg is used for REX.R, the high bit of op's base | 883 // The high bit of reg is used for REX.R, the high bit of op's base |
858 // register is used for REX.B, and the high bit of op's index register | 884 // register is used for REX.B, and the high bit of op's index register |
859 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing | 885 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing |
860 // is emitted. | 886 // is emitted. |
861 inline void emit_optional_rex_32(Register reg, const Operand& op); | 887 inline void emit_optional_rex_32(Register reg, const Operand& op); |
862 | 888 |
889 // Optionally do as emit_rex_32(Register) if the register number has | |
890 // the high bit set. | |
891 inline void emit_optional_rex_32(Register rm_reg); | |
892 | |
893 // Optionally do as emit_rex_32(const Operand&) if the operand register | |
894 // numbers have a high bit set. | |
895 inline void emit_optional_rex_32(const Operand& op); | |
896 | |
897 | |
863 // Emit the Mod/RM byte, and optionally the SIB byte and | 898 // Emit the Mod/RM byte, and optionally the SIB byte and |
864 // 1- or 4-byte offset for a memory operand. Also encodes | 899 // 1- or 4-byte offset for a memory operand. Also encodes |
865 // the second operand of the operation, a register or operation | 900 // the second operand of the operation, a register or operation |
866 // subcode, into the Mod/RM byte. | 901 // subcode, into the Mod/RM byte. |
867 void emit_operand(Register reg, const Operand& adr) { | 902 void emit_operand(Register reg, const Operand& adr) { |
868 emit_operand(reg.code() & 0x07, adr); | 903 emit_operand(reg.code() & 0x07, adr); |
869 } | 904 } |
870 | 905 |
871 // Emit the Mod/RM byte, and optionally the SIB byte and | 906 // 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 | 907 // 1- or 4-byte offset for a memory operand. Also used to encode |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
945 private: | 980 private: |
946 Assembler* assembler_; | 981 Assembler* assembler_; |
947 #ifdef DEBUG | 982 #ifdef DEBUG |
948 int space_before_; | 983 int space_before_; |
949 #endif | 984 #endif |
950 }; | 985 }; |
951 | 986 |
952 } } // namespace v8::internal | 987 } } // namespace v8::internal |
953 | 988 |
954 #endif // V8_X64_ASSEMBLER_X64_H_ | 989 #endif // V8_X64_ASSEMBLER_X64_H_ |
OLD | NEW |