diff options
author | Ryan <ry@tinyclouds.org> | 2009-06-29 10:55:05 +0200 |
---|---|---|
committer | Ryan <ry@tinyclouds.org> | 2009-06-29 10:55:05 +0200 |
commit | e763efdadf4bbd9c0155a4c7f782d271a2fd5814 (patch) | |
tree | 094824e55548cdeb2ce9b796cbf29aaa591bb69f /deps/v8/src/x64/assembler-x64.h | |
parent | e876d6629e8682f5d818141bc0710f6d82311373 (diff) | |
download | node-new-e763efdadf4bbd9c0155a4c7f782d271a2fd5814.tar.gz |
Upgrade v8 to 1.2.10 and libev to 3.6
Diffstat (limited to 'deps/v8/src/x64/assembler-x64.h')
-rw-r--r-- | deps/v8/src/x64/assembler-x64.h | 192 |
1 files changed, 155 insertions, 37 deletions
diff --git a/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h index 650c218f11..0d98e5fe4a 100644 --- a/deps/v8/src/x64/assembler-x64.h +++ b/deps/v8/src/x64/assembler-x64.h @@ -45,7 +45,7 @@ namespace internal { // Test whether a 64-bit value is in a specific range. static inline bool is_uint32(int64_t x) { const int64_t kUInt32Mask = V8_INT64_C(0xffffffff); - return x == x & kUInt32Mask; + return x == (x & kUInt32Mask); } static inline bool is_int32(int64_t x) { @@ -82,8 +82,6 @@ struct Register { } bool is_valid() const { return 0 <= code_ && code_ < 16; } bool is(Register reg) const { return code_ == reg.code_; } - // The byte-register distinction of ai32 has dissapeared. - bool is_byte_register() const { return false; } int code() const { ASSERT(is_valid()); return code_; @@ -92,6 +90,17 @@ struct Register { return 1 << code_; } + // Return the high bit of the register code as a 0 or 1. Used often + // when constructing the REX prefix byte. + int high_bit() const { + return code_ >> 3; + } + // Return the 3 low bits of the register code. Used when encoding registers + // in modR/M, SIB, and opcode bytes. + int low_bits() const { + return code_ & 0x7; + } + // (unfortunately we can't make this private in a struct when initializing // by assignment.) int code_; @@ -115,7 +124,8 @@ extern Register r14; extern Register r15; extern Register no_reg; -struct XMMRegister { + +struct MMXRegister { bool is_valid() const { return 0 <= code_ && code_ < 2; } int code() const { ASSERT(is_valid()); @@ -125,6 +135,34 @@ struct XMMRegister { int code_; }; +extern MMXRegister mm0; +extern MMXRegister mm1; +extern MMXRegister mm2; +extern MMXRegister mm3; +extern MMXRegister mm4; +extern MMXRegister mm5; +extern MMXRegister mm6; +extern MMXRegister mm7; +extern MMXRegister mm8; +extern MMXRegister mm9; +extern MMXRegister mm10; +extern MMXRegister mm11; +extern MMXRegister mm12; +extern MMXRegister mm13; +extern MMXRegister mm14; +extern MMXRegister mm15; + + +struct XMMRegister { + bool is_valid() const { return 0 <= code_ && code_ < 16; } + int code() const { + ASSERT(is_valid()); + return code_; + } + + int code_; +}; + extern XMMRegister xmm0; extern XMMRegister xmm1; extern XMMRegister xmm2; @@ -238,12 +276,12 @@ class Immediate BASE_EMBEDDED { // Machine instruction Operands enum ScaleFactor { - kTimes1 = 0, - kTimes2 = 1, - kTimes4 = 2, - kTimes8 = 3, - kTimesIntSize = kTimes4, - kTimesPointerSize = kTimes8 + times_1 = 0, + times_2 = 1, + times_4 = 2, + times_8 = 3, + times_int_size = times_4, + times_pointer_size = times_8 }; @@ -290,11 +328,11 @@ class Operand BASE_EMBEDDED { // CpuFeatures keeps track of which features are supported by the target CPU. // Supported features must be enabled by a Scope before use. // Example: -// if (CpuFeatures::IsSupported(SSE2)) { -// CpuFeatures::Scope fscope(SSE2); -// // Generate SSE2 floating point code. +// if (CpuFeatures::IsSupported(SSE3)) { +// CpuFeatures::Scope fscope(SSE3); +// // Generate SSE3 floating point code. // } else { -// // Generate standard x87 floating point code. +// // Generate standard x87 or SSE2 floating point code. // } class CpuFeatures : public AllStatic { public: @@ -331,6 +369,10 @@ class CpuFeatures : public AllStatic { #endif }; private: + // Safe defaults include SSE2 and CMOV for X64. It is always available, if + // anyone checks, but they shouldn't need to check. + static const uint64_t kDefaultCpuFeatures = + (1 << CpuFeatures::SSE2 | 1 << CpuFeatures::CMOV); static uint64_t supported_; static uint64_t enabled_; }; @@ -338,11 +380,15 @@ class CpuFeatures : public AllStatic { class Assembler : public Malloced { private: - // The relocation writer's position is kGap bytes below the end of + // We check before assembling an instruction that there is sufficient + // space to write an instruction and its relocation information. + // The relocation writer's position must be kGap bytes above the end of // the generated instructions. This leaves enough space for the - // longest possible x64 instruction (There is a 15 byte limit on - // instruction length, ruling out some otherwise valid instructions) and - // allows for a single, fast space check per instruction. + // longest possible x64 instruction, 15 bytes, and the longest possible + // relocation information encoding, RelocInfoWriter::kMaxLength == 16. + // (There is a 15 byte limit on x64 instruction length that rules out some + // otherwise valid instructions.) + // This allows for a single, fast space check per instruction. static const int kGap = 32; public: @@ -373,8 +419,8 @@ class Assembler : public Malloced { static inline void set_target_address_at(Address pc, Address target); // Distance between the address of the code target in the call instruction - // and the return address - static const int kTargetAddrToReturnAddrDist = kPointerSize; + // and the return address. Checked in the debug build. + static const int kTargetAddrToReturnAddrDist = 3 + kPointerSize; // --------------------------------------------------------------------------- @@ -446,12 +492,19 @@ class Assembler : public Malloced { void movq(Register dst, ExternalReference ext); void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); + void movsxlq(Register dst, Register src); + void movsxlq(Register dst, const Operand& src); + void movzxbq(Register dst, const Operand& src); + // New x64 instruction to load from an immediate 64-bit pointer into RAX. void load_rax(void* ptr, RelocInfo::Mode rmode); void load_rax(ExternalReference ext); - // Conditional moves - // Implement conditional moves here. + // Conditional moves. + void cmovq(Condition cc, Register dst, Register src); + void cmovq(Condition cc, Register dst, const Operand& src); + void cmovl(Condition cc, Register dst, Register src); + void cmovl(Condition cc, Register dst, const Operand& src); // Exchange two registers void xchg(Register dst, Register src); @@ -461,6 +514,14 @@ class Assembler : public Malloced { arithmetic_op(0x03, dst, src); } + void addl(Register dst, Register src) { + arithmetic_op_32(0x03, dst, src); + } + + void addl(Register dst, Immediate src) { + immediate_arithmetic_op_32(0x0, dst, src); + } + void addq(Register dst, const Operand& src) { arithmetic_op(0x03, dst, src); } @@ -482,6 +543,10 @@ class Assembler : public Malloced { immediate_arithmetic_op_32(0x0, dst, src); } + void cmpb(Register dst, Immediate src) { + immediate_arithmetic_op_8(0x7, dst, src); + } + void cmpb(const Operand& dst, Immediate src) { immediate_arithmetic_op_8(0x7, dst, src); } @@ -502,6 +567,10 @@ class Assembler : public Malloced { immediate_arithmetic_op(0x7, dst, src); } + void cmpl(Register dst, Immediate src) { + immediate_arithmetic_op_32(0x7, dst, src); + } + void cmpq(const Operand& dst, Immediate src) { immediate_arithmetic_op(0x7, dst, src); } @@ -540,6 +609,8 @@ class Assembler : public Malloced { void imul(Register dst, const Operand& src); // Performs the operation dst = src * imm. void imul(Register dst, Register src, Immediate imm); + // Multiply 32 bit registers + void imull(Register dst, Register src); void incq(Register dst); void incq(const Operand& dst); @@ -604,6 +675,10 @@ class Assembler : public Malloced { shift(dst, 0x4); } + void shll(Register dst) { + shift_32(dst, 0x4); + } + void shr(Register dst, Immediate shift_amount) { shift(dst, shift_amount, 0x5); } @@ -612,6 +687,10 @@ class Assembler : public Malloced { shift(dst, 0x5); } + void shrl(Register dst) { + shift_32(dst, 0x5); + } + void store_rax(void* dst, RelocInfo::Mode mode); void store_rax(ExternalReference ref); @@ -635,6 +714,10 @@ class Assembler : public Malloced { immediate_arithmetic_op(0x5, dst, src); } + void subl(Register dst, Register src) { + arithmetic_op_32(0x2B, dst, src); + } + void subl(const Operand& dst, Immediate src) { immediate_arithmetic_op_32(0x5, dst, src); } @@ -770,19 +853,37 @@ class Assembler : public Malloced { void fwait(); void fnclex(); + void fsin(); + void fcos(); + void frndint(); + void sahf(); + // SSE2 instructions + void movsd(const Operand& dst, XMMRegister src); + void movsd(Register src, XMMRegister dst); + void movsd(XMMRegister dst, Register src); + void movsd(XMMRegister src, const Operand& dst); + void cvttss2si(Register dst, const Operand& src); void cvttsd2si(Register dst, const Operand& src); - void cvtsi2sd(XMMRegister dst, const Operand& src); + void cvtlsi2sd(XMMRegister dst, const Operand& src); + void cvtlsi2sd(XMMRegister dst, Register src); + void cvtqsi2sd(XMMRegister dst, const Operand& src); + void cvtqsi2sd(XMMRegister dst, Register src); void addsd(XMMRegister dst, XMMRegister src); void subsd(XMMRegister dst, XMMRegister src); void mulsd(XMMRegister dst, XMMRegister src); void divsd(XMMRegister dst, XMMRegister src); + + void emit_sse_operand(XMMRegister dst, XMMRegister src); + void emit_sse_operand(XMMRegister reg, const Operand& adr); + void emit_sse_operand(XMMRegister dst, Register src); + // Use either movsd or movlpd. // void movdbl(XMMRegister dst, const Operand& src); // void movdbl(const Operand& dst, XMMRegister src); @@ -812,11 +913,6 @@ class Assembler : public Malloced { // Used for inline tables, e.g., jump-tables. // void dd(uint64_t data, RelocInfo::Mode reloc_info); - // Writes the absolute address of a bound label at the given position in - // the generated code. That positions should have the relocation mode - // internal_reference! - void WriteInternalReference(int position, const Label& bound_label); - int pc_offset() const { return pc_ - buffer_; } int current_statement_position() const { return current_statement_position_; } int current_position() const { return current_position_; } @@ -866,6 +962,7 @@ class Assembler : public Malloced { // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. // REX.W is set. inline void emit_rex_64(Register reg, Register rm_reg); + inline void emit_rex_64(XMMRegister reg, Register rm_reg); // Emits a REX prefix that encodes a 64-bit operand size and // the top bit of the destination, index, and base register codes. @@ -873,6 +970,7 @@ class Assembler : public Malloced { // register is used for REX.B, and the high bit of op's index register // is used for REX.X. REX.W is set. inline void emit_rex_64(Register reg, const Operand& op); + inline void emit_rex_64(XMMRegister reg, const Operand& op); // Emits a REX prefix that encodes a 64-bit operand size and // the top bit of the register code. @@ -917,6 +1015,18 @@ class Assembler : public Malloced { // is emitted. inline void emit_optional_rex_32(Register reg, const Operand& op); + // As for emit_optional_rex_32(Register, Register), except that + // the registers are XMM registers. + inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); + + // As for emit_optional_rex_32(Register, Register), except that + // the registers are XMM registers. + inline void emit_optional_rex_32(XMMRegister reg, Register base); + + // As for emit_optional_rex_32(Register, const Operand&), except that + // the register is an XMM register. + inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); + // Optionally do as emit_rex_32(Register) if the register number has // the high bit set. inline void emit_optional_rex_32(Register rm_reg); @@ -931,7 +1041,7 @@ class Assembler : public Malloced { // the second operand of the operation, a register or operation // subcode, into the reg field of the ModR/M byte. void emit_operand(Register reg, const Operand& adr) { - emit_operand(reg.code() & 0x07, adr); + emit_operand(reg.low_bits(), adr); } // Emit the ModR/M byte, and optionally the SIB byte and @@ -941,14 +1051,14 @@ class Assembler : public Malloced { // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. void emit_modrm(Register reg, Register rm_reg) { - emit(0xC0 | (reg.code() & 0x7) << 3 | (rm_reg.code() & 0x7)); + emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); } // Emit a ModR/M byte with an operation subcode in the reg field and // a register in the rm_reg field. void emit_modrm(int code, Register rm_reg) { - ASSERT((code & ~0x7) == 0); - emit(0xC0 | (code & 0x7) << 3 | (rm_reg.code() & 0x7)); + ASSERT(is_uint3(code)); + emit(0xC0 | code << 3 | rm_reg.low_bits()); } // Emit the code-object-relative offset of the label's position @@ -959,23 +1069,31 @@ class Assembler : public Malloced { // similar, differing just in the opcode or in the reg field of the // ModR/M byte. void arithmetic_op(byte opcode, Register dst, Register src); + void arithmetic_op_32(byte opcode, Register dst, Register src); void arithmetic_op(byte opcode, Register reg, const Operand& op); void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); - // Operate on a 32-bit word in memory. + // Operate on a 32-bit word in memory or register. void immediate_arithmetic_op_32(byte subcode, const Operand& dst, Immediate src); - // Operate on a byte in memory. - void immediate_arithmetic_op_8(byte subcode, - const Operand& dst, + void immediate_arithmetic_op_32(byte subcode, + Register dst, Immediate src); + // Operate on a byte in memory or register. + void immediate_arithmetic_op_8(byte subcode, + const Operand& dst, + Immediate src); + void immediate_arithmetic_op_8(byte subcode, + Register dst, + Immediate src); // Emit machine code for a shift operation. void shift(Register dst, Immediate shift_amount, int subcode); // Shift dst by cl % 64 bits. void shift(Register dst, int subcode); + void shift_32(Register dst, int subcode); - // void emit_farith(int b1, int b2, int i); + void emit_farith(int b1, int b2, int i); // labels // void print(Label* L); |