From 52ff9897fbbdf70203feee81900124cc3f3fef7c Mon Sep 17 00:00:00 2001 From: "haitao.feng@intel.com" Date: Tue, 3 Dec 2013 03:49:41 +0000 Subject: [PATCH] Refactor X64 movq assembler instruction R=verwaest@chromium.org Review URL: https://codereview.chromium.org/91333002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18216 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/assembler-x64.cc | 87 ++++++++++++---------------------------- src/x64/assembler-x64.h | 64 +++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 78 deletions(-) diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index 49bd78d1ff..bc875d67e8 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -1395,92 +1395,59 @@ void Assembler::movw(const Operand& dst, Immediate imm) { } -void Assembler::movl(Register dst, const Operand& src) { +void Assembler::emit_mov(Register dst, const Operand& src, int size) { EnsureSpace ensure_space(this); - emit_optional_rex_32(dst, src); + emit_rex(dst, src, size); emit(0x8B); emit_operand(dst, src); } -void Assembler::movl(Register dst, Register src) { +void Assembler::emit_mov(Register dst, Register src, int size) { EnsureSpace ensure_space(this); if (src.low_bits() == 4) { - emit_optional_rex_32(src, dst); + emit_rex(src, dst, size); emit(0x89); emit_modrm(src, dst); } else { - emit_optional_rex_32(dst, src); + emit_rex(dst, src, size); emit(0x8B); emit_modrm(dst, src); } } -void Assembler::movl(const Operand& dst, Register src) { +void Assembler::emit_mov(const Operand& dst, Register src, int size) { EnsureSpace ensure_space(this); - emit_optional_rex_32(src, dst); + emit_rex(src, dst, size); emit(0x89); emit_operand(src, dst); } -void Assembler::movl(const Operand& dst, Immediate value) { +void Assembler::emit_mov(Register dst, Immediate value, int size) { EnsureSpace ensure_space(this); - emit_optional_rex_32(dst); + emit_rex(dst, size); + if (size == kInt64Size) { + emit(0xC7); + emit_modrm(0x0, dst); + } else { + ASSERT(size == kInt32Size); + emit(0xB8 + dst.low_bits()); + } + emit(value); +} + + +void Assembler::emit_mov(const Operand& dst, Immediate value, int size) { + EnsureSpace ensure_space(this); + emit_rex(dst, size); emit(0xC7); emit_operand(0x0, dst); emit(value); } -void Assembler::movl(Register dst, Immediate value) { - EnsureSpace ensure_space(this); - emit_optional_rex_32(dst); - emit(0xB8 + dst.low_bits()); - emit(value); -} - - -void Assembler::movq(Register dst, const Operand& src) { - EnsureSpace ensure_space(this); - emit_rex_64(dst, src); - emit(0x8B); - emit_operand(dst, src); -} - - -void Assembler::movq(Register dst, Register src) { - EnsureSpace ensure_space(this); - if (src.low_bits() == 4) { - emit_rex_64(src, dst); - emit(0x89); - emit_modrm(src, dst); - } else { - emit_rex_64(dst, src); - emit(0x8B); - emit_modrm(dst, src); - } -} - - -void Assembler::movq(Register dst, Immediate value) { - EnsureSpace ensure_space(this); - emit_rex_64(dst); - emit(0xC7); - emit_modrm(0x0, dst); - emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. -} - - -void Assembler::movq(const Operand& dst, Register src) { - EnsureSpace ensure_space(this); - emit_rex_64(src, dst); - emit(0x89); - emit_operand(src, dst); -} - - void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { // This method must not be used with heap object references. The stored // address is not GC safe. Use the handle version instead. @@ -1504,12 +1471,8 @@ void Assembler::movq(Register dst, int64_t value) { } -void Assembler::movq(const Operand& dst, Immediate value) { - EnsureSpace ensure_space(this); - emit_rex_64(dst); - emit(0xC7); - emit_operand(0, dst); - emit(value); +void Assembler::movq(Register dst, uint64_t value) { + movq(dst, static_cast(value)); } diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index 709b61b52e..1f1316fa82 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -530,6 +530,10 @@ class CpuFeatures : public AllStatic { }; +#define ASSEMBLER_INSTRUCTION_LIST(V) \ + V(mov) + + class Assembler : public AssemblerBase { private: // We check before assembling an instruction that there is sufficient @@ -658,6 +662,24 @@ class Assembler : public AssemblerBase { // Some mnemonics, such as "and", are the same as C++ keywords. // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. +#define DECLARE_INSTRUCTION(instruction) \ + template \ + void instruction##p(P1 p1, P2 p2) { \ + emit_##instruction(p1, p2, kPointerSize); \ + } \ + \ + template \ + void instruction##l(P1 p1, P2 p2) { \ + emit_##instruction(p1, p2, kInt32Size); \ + } \ + \ + template \ + void instruction##q(P1 p1, P2 p2) { \ + emit_##instruction(p1, p2, kInt64Size); \ + } + ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) +#undef DECLARE_INSTRUCTION + // Insert the smallest number of nop instructions // possible to align the pc offset to a multiple // of m, where m must be a power of 2. @@ -695,30 +717,15 @@ class Assembler : public AssemblerBase { void movw(const Operand& dst, Register src); void movw(const Operand& dst, Immediate imm); - void movl(Register dst, Register src); - void movl(Register dst, const Operand& src); - void movl(const Operand& dst, Register src); - void movl(const Operand& dst, Immediate imm); - // Load a 32-bit immediate value, zero-extended to 64 bits. - void movl(Register dst, Immediate imm32); - - // Move 64 bit register value to 64-bit memory location. - void movq(const Operand& dst, Register src); - // Move 64 bit memory location to 64-bit register value. - void movq(Register dst, const Operand& src); - void movq(Register dst, Register src); - // Sign extends immediate 32-bit value to 64 bits. - void movq(Register dst, Immediate x); // Move the offset of the label location relative to the current // position (after the move) to the destination. void movl(const Operand& dst, Label* src); - // Move sign extended immediate to memory location. - void movq(const Operand& dst, Immediate value); // Loads a pointer into a register with a relocation mode. void movq(Register dst, void* ptr, RelocInfo::Mode rmode); // Loads a 64-bit immediate into a register. void movq(Register dst, int64_t value); + void movq(Register dst, uint64_t value); void movq(Register dst, Handle handle, RelocInfo::Mode rmode); void movsxbq(Register dst, const Operand& src); @@ -1590,6 +1597,25 @@ class Assembler : public AssemblerBase { // numbers have a high bit set. inline void emit_optional_rex_32(const Operand& op); + template + void emit_rex(P1 p1, int size) { + if (size == kInt64Size) { + emit_rex_64(p1); + } else { + ASSERT(size == kInt32Size); + emit_optional_rex_32(p1); + } + } + + template + void emit_rex(P1 p1, P2 p2, int size) { + if (size == kInt64Size) { + emit_rex_64(p1, p2); + } else { + ASSERT(size == kInt32Size); + emit_optional_rex_32(p1, p2); + } + } // Emit the ModR/M byte, and optionally the SIB byte and // 1- or 4-byte offset for a memory operand. Also encodes @@ -1675,6 +1701,12 @@ class Assembler : public AssemblerBase { // record reloc info for current pc_ void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); + void emit_mov(Register dst, const Operand& src, int size); + void emit_mov(Register dst, Register src, int size); + void emit_mov(const Operand& dst, Register src, int size); + void emit_mov(Register dst, Immediate value, int size); + void emit_mov(const Operand& dst, Immediate value, int size); + friend class CodePatcher; friend class EnsureSpace; friend class RegExpMacroAssemblerX64;