Author: [email protected]
Date: Wed Jun  3 03:30:50 2009
New Revision: 2091

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

Log:
X64: Added implementations of Set(..., Immediate) to macro assembler.
Removed duplicates comments in assembler-x64.cc.

Review URL: http://codereview.chromium.org/119035


Modified: branches/bleeding_edge/src/assembler.h
==============================================================================
--- branches/bleeding_edge/src/assembler.h      (original)
+++ branches/bleeding_edge/src/assembler.h      Wed Jun  3 03:30:50 2009
@@ -424,8 +424,6 @@
  //  
-----------------------------------------------------------------------------
  // Utility functions

-// Move these into inline file?
-
  static inline bool is_intn(int x, int n)  {
    return -(1 << (n-1)) <= x && x < (1 << (n-1));
  }

Modified: branches/bleeding_edge/src/x64/assembler-x64-inl.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64-inl.h  (original)
+++ branches/bleeding_edge/src/x64/assembler-x64-inl.h  Wed Jun  3 03:30:50  
2009
@@ -61,66 +61,66 @@
  }


-// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
-// REX.W is set.  REX.X is cleared.
  void Assembler::emit_rex_64(Register reg, Register rm_reg) {
    emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
  }


-// The high bit of reg is used for REX.R, the high bit of op's base
-// register is used for REX.B, and the high bit of op's index register
-// is used for REX.X.  REX.W is set.
  void Assembler::emit_rex_64(Register reg, const Operand& op) {
    emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
  }


-// The high bit of the register is used for REX.B.
-// REX.W is set and REX.R and REX.X are clear.
  void Assembler::emit_rex_64(Register rm_reg) {
-  ASSERT_EQ(rm_reg.code() & 0x0f, rm_reg.code());
+  ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code());
    emit(0x48 | (rm_reg.code() >> 3));
  }


-// The high bit of op's base register is used for REX.B, and the high
-// bit of op's index register is used for REX.X.  REX.W is set and REX.R  
clear.
  void Assembler::emit_rex_64(const Operand& op) {
    emit(0x48 | op.rex_);
  }


-// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
-// REX.W and REX.X are clear.
  void Assembler::emit_rex_32(Register reg, Register rm_reg) {
    emit(0x40 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
  }


-// The high bit of reg is used for REX.R, the high bit of op's base
-// register is used for REX.B, and the high bit of op's index register
-// is used for REX.X.  REX.W is cleared.
  void Assembler::emit_rex_32(Register reg, const Operand& op) {
    emit(0x40 | (reg.code() & 0x8) >> 1 | op.rex_);
  }


-// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
-// REX.W and REX.X are cleared.  If no REX bits are set, no byte is  
emitted.
+void Assembler::emit_rex_32(Register rm_reg) {
+  emit(0x40 | (rm_reg.code() & 0x8) >> 3);
+}
+
+
+void Assembler::emit_rex_32(const Operand& op) {
+  emit(0x40 | op.rex_);
+}
+
+
  void Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
    byte rex_bits = (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3;
-  if (rex_bits) emit(0x40 | rex_bits);
+  if (rex_bits != 0) emit(0x40 | rex_bits);
  }


-// The high bit of reg is used for REX.R, the high bit of op's base
-// register is used for REX.B, and the high bit of op's index register
-// is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
-// is emitted.
  void Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
    byte rex_bits =  (reg.code() & 0x8) >> 1 | op.rex_;
-  if (rex_bits) emit(0x40 | rex_bits);
+  if (rex_bits != 0) emit(0x40 | rex_bits);
+}
+
+
+void Assembler::emit_optional_rex_32(Register rm_reg) {
+  if (rm_reg.code() & 0x8 != 0) emit(0x41);
+}
+
+
+void Assembler::emit_optional_rex_32(const Operand& op) {
+  if (op.rex_ != 0) emit(0x40 | op.rex_);
  }



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     Wed Jun  3 03:30:50 2009
@@ -685,6 +685,16 @@
  }


+void Assembler::movl(Register dst, Immediate value) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_optional_rex_32(dst);
+  emit(0xC7);
+  emit(0xC0 | (dst.code() & 0x7));
+  emit(value);  // Only 32-bit immediates are possible, not 8-bit  
immediates.
+}
+
+
  void Assembler::movq(Register dst, const Operand& src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
@@ -703,15 +713,6 @@
  }


-void Assembler::movq(const Operand& dst, Register src) {
-  EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
-  emit_rex_64(src, dst);
-  emit(0x89);
-  emit_operand(src, dst);
-}
-
-
  void Assembler::movq(Register dst, Immediate value) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
@@ -728,6 +729,15 @@
    emit_rex_64(dst);
    emit(0xB8 | (dst.code() & 0x7));
    emitq(value, rmode);
+}
+
+
+void Assembler::movq(const Operand& dst, Register src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(src, dst);
+  emit(0x89);
+  emit_operand(src, dst);
  }



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      Wed Jun  3 03:30:50 2009
@@ -40,6 +40,19 @@
  namespace v8 {
  namespace internal {

+// Utility functions
+
+// 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;
+}
+
+static inline bool is_int32(int64_t x) {
+  const int64_t kMinIntValue = V8_INT64_C(-0x80000000);
+  return is_uint32(x - kMinIntValue);
+}
+
  // CPU Registers.
  //
  // 1) We would prefer to use an enum, but enum values are assignment-
@@ -410,12 +423,16 @@
    void movl(Register dst, Register src);
    void movl(Register dst, const Operand& src);
    void movl(const Operand& dst, Register src);
+  // Load a 32-bit immediate value, zero-extended to 64 bits.
+  void movl(Register dst, Immediate imm32);

    void movq(Register dst, int32_t imm32);
-  void movq(Register dst, Immediate x);
    void movq(Register dst, const Operand& src);
+  // Sign extends immediate 32-bit value to 64 bits.
+  void movq(Register dst, Immediate x);
    void movq(Register dst, Register src);
-  void movq(const Operand& dst, const Immediate& x);
+
+  // Move 64 bit register value to 64-bit memory location.
    void movq(const Operand& dst, Register src);

    // New x64 instructions to load a 64-bit immediate into a register.
@@ -426,6 +443,7 @@
    void movq(Register dst, const ExternalReference& ext, RelocInfo::Mode  
rmode);
    void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);

+
    // New x64 instruction to load from an immediate 64-bit pointer into RAX.
    void load_rax(void* ptr, RelocInfo::Mode rmode);

@@ -874,6 +892,14 @@
    // is used for REX.X.  REX.W is cleared.
    inline void emit_rex_32(Register reg, const Operand& op);

+  // High bit of rm_reg goes to REX.B.
+  // REX.W, REX.R and REX.X are clear.
+  inline void emit_rex_32(Register rm_reg);
+
+  // High bit of base goes to REX.B and high bit of index to REX.X.
+  // REX.W and REX.R are clear.
+  inline void emit_rex_32(const Operand &);
+
    // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
    // REX.W is cleared.  If no REX bits are set, no byte is emitted.
    inline void emit_optional_rex_32(Register reg, Register rm_reg);
@@ -883,6 +909,15 @@
    // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
    // is emitted.
    inline void emit_optional_rex_32(Register 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);
+
+  // Optionally do as emit_rex_32(const Operand&) if the operand register
+  // numbers have a high bit set.
+  inline void emit_optional_rex_32(const Operand& op);
+

    // Emit the Mod/RM byte, and optionally the SIB byte and
    // 1- or 4-byte offset for a memory operand.  Also encodes

Modified: branches/bleeding_edge/src/x64/macro-assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/macro-assembler-x64.cc       (original)
+++ branches/bleeding_edge/src/x64/macro-assembler-x64.cc       Wed Jun  3  
03:30:50 2009
@@ -29,6 +29,7 @@

  #include "bootstrapper.h"
  #include "codegen-inl.h"
+#include "macro-assembler-x64.h"

  namespace v8 {
  namespace internal {
@@ -44,5 +45,29 @@
  void MacroAssembler::TailCallRuntime(ExternalReference const& a, int b) {
    UNIMPLEMENTED();
  }
+
+
+void MacroAssembler::Set(Register dst, int64_t x) {
+  if (is_int32(x)) {
+    movq(dst, Immediate(x));
+  } else if (is_uint32(x)) {
+    movl(dst, Immediate(x));
+  } else {
+    movq(dst, x, RelocInfo::NONE);
+  }
+}
+
+
+void MacroAssembler::Set(const Operand& dst, int64_t x) {
+  if (is_int32(x)) {
+    movq(kScratchRegister, Immediate(x));
+  } else if (is_uint32(x)) {
+    movl(kScratchRegister, Immediate(x));
+  } else {
+    movq(kScratchRegister, x, RelocInfo::NONE);
+  }
+  movq(dst, kScratchRegister);
+}
+

  } }  // namespace v8::internal

Modified: branches/bleeding_edge/src/x64/macro-assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/macro-assembler-x64.h        (original)
+++ branches/bleeding_edge/src/x64/macro-assembler-x64.h        Wed Jun  3  
03:30:50 2009
@@ -33,6 +33,8 @@
  namespace v8 {
  namespace internal {

+static const Register kScratchRegister = r10;
+
  // Forward declaration.
  class JumpTarget;

@@ -137,8 +139,8 @@
    void GetBuiltinEntry(Register target, Builtins::JavaScript id);

    // Expression support
-  void Set(Register dst, const Immediate& x);
-  void Set(const Operand& dst, const Immediate& x);
+  void Set(Register dst, int64_t x);
+  void Set(const Operand& dst, int64_t x);

    // Compare object type for heap object.
    // Incoming register is heap_object and outgoing register is map.

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

Reply via email to