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 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 |