Author: [email protected]
Date: Mon May 25 07:00:30 2009
New Revision: 2043

Modified:
    branches/bleeding_edge/src/x64/assembler-x64.cc
    branches/bleeding_edge/src/x64/assembler-x64.h

Log:
Implementation of a few more assembly instructions on x64
Review URL: http://codereview.chromium.org/113767

Modified: branches/bleeding_edge/src/x64/assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.cc     (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.cc     Mon May 25 07:00:30 2009
@@ -33,6 +33,9 @@
  namespace internal {

  Register no_reg = { -1 };
+Register rax = { 0 };
+Register rcx = { 1 };
+Register rsi = { 7 };


  // Safe default is no features.
@@ -239,10 +242,39 @@
  }


-void Assembler::int3() {
+void Assembler::add(Register dst, const Operand& src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  EMIT(0xCC);
+  emit_rex_64(dst, src);
+  EMIT(0x03);
+  emit_operand(dst, src);
+}
+
+
+void Assembler::add(Register dst, Register src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(dst, src);
+  EMIT(0x03);
+  EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7));
+}
+
+
+void Assembler::dec(Register dst) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(rcx, dst);
+  EMIT(0xFF);
+  EMIT(0xC8 | (dst.code() & 0x7));
+}
+
+
+void Assembler::dec(const Operand& dst) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(rax, dst);
+  EMIT(0xFF);
+  emit_operand(rcx, dst);
  }


@@ -253,24 +285,28 @@
  }


-void Assembler::nop() {
+void Assembler::inc(Register dst) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  EMIT(0x90);
+  emit_rex_64(rax, dst);
+  EMIT(0xFF);
+  EMIT(0xC0 | (dst.code() & 0x7));
  }


-void Assembler::ret(int imm16) {
+void Assembler::inc(const Operand& dst) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  ASSERT(is_uint16(imm16));
-  if (imm16 == 0) {
-    EMIT(0xC3);
-  } else {
-    EMIT(0xC2);
-    EMIT(imm16 & 0xFF);
-    EMIT((imm16 >> 8) & 0xFF);
-  }
+  emit_rex_64(rax, dst);
+  EMIT(0xFF);
+  emit_operand(rax, dst);
+}
+
+
+void Assembler::int3() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xCC);
  }


@@ -289,6 +325,64 @@
    emit_rex_64(dst, src);
    EMIT(0x89);
    EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7));
+}
+
+
+void Assembler::nop() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0x90);
+}
+
+void Assembler::pop(Register dst) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  if (dst.code() & 0x8) {
+    emit_rex_64(rax, dst);
+  }
+  EMIT(0x58 | (dst.code() & 0x7));
+}
+
+
+void Assembler::pop(const Operand& dst) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(rax, dst);  // Could be omitted in some cases.
+  EMIT(0x8F);
+  emit_operand(rax, dst);
+}
+
+
+void Assembler::push(Register src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  if (src.code() & 0x8) {
+    emit_rex_64(rax, src);
+  }
+  EMIT(0x50 | (src.code() & 0x7));
+}
+
+
+void Assembler::push(const Operand& src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(rsi, src);  // Could be omitted in some cases.
+  EMIT(0xFF);
+  emit_operand(rsi, src);
+}
+
+
+void Assembler::ret(int imm16) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  ASSERT(is_uint16(imm16));
+  if (imm16 == 0) {
+    EMIT(0xC3);
+  } else {
+    EMIT(0xC2);
+    EMIT(imm16 & 0xFF);
+    EMIT((imm16 >> 8) & 0xFF);
+  }
  }

  } }  // namespace v8::internal

Modified: branches/bleeding_edge/src/x64/assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.h      (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.h      Mon May 25 07:00:30 2009
@@ -437,7 +437,8 @@
   private:
    // The relocation writer's position is kGap bytes below the end of
    // the generated instructions. This leaves enough space for the
-  // longest possible ia32 instruction (17 bytes as of 9/26/06) and
+  // 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.
    static const int kGap = 32;

@@ -475,22 +476,20 @@
    //  
---------------------------------------------------------------------------
    // Code generation
    //
-  // - function names correspond one-to-one to ia32 instruction mnemonics
-  // - unless specified otherwise, instructions operate on 32bit operands
-  // - instructions on 8bit (byte) operands/registers have a trailing '_b'
-  // - instructions on 16bit (word) operands/registers have a trailing '_w'
-  // - naming conflicts with C++ keywords are resolved via a trailing '_'
-
-  // NOTE ON INTERFACE: Currently, the interface is not very consistent
-  // in the sense that some operations (e.g. mov()) can be called in more
-  // the one way to generate the same instruction: The Register argument
-  // can in some cases be replaced with an Operand(Register) argument.
-  // This should be cleaned up and made more orthogonal. The questions
-  // is: should we always use Operands instead of Registers where an
-  // Operand is possible, or should we have a Register (overloaded) form
-  // instead? We must be careful to make sure that the selected instruction
-  // is obvious from the parameters to avoid hard-to-find code generation
-  // bugs.
+  // Function names correspond one-to-one to x64 instruction mnemonics.
+  // Unless specified otherwise, instructions operate on 64-bit operands.
+  //
+  // If we need versions of an assembly instruction that operate on  
different
+  // width arguments, we add a single-letter suffix specifying the width.
+  // This is done for the following instructions: mov, cmp.
+  // There are no versions of these instructions without the suffix.
+  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
+  // - Instructions on 16-bit (word) operands/registers have a  
trailing 'w'.
+  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
+  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
+  //
+  // Some mnemonics, such as "and", are the same as C++ keywords.
+  // Naming conflicts with C++ keywords are resolved by adding a  
trailing '_'.

    // Insert the smallest number of nop instructions
    // possible to align the pc offset to a multiple
@@ -552,6 +551,7 @@
    void adc(Register dst, int32_t imm32);
    void adc(Register dst, const Operand& src);

+  void add(Register dst, Register src);
    void add(Register dst, const Operand& src);
    void add(const Operand& dst, const Immediate& x);


--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to