Author: [email protected]
Date: Mon Jun 22 01:17:44 2009
New Revision: 2231

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

Log:
X64 implementation: Add high_bit() and low_bits() to register methods.
Review URL: http://codereview.chromium.org/141032

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  Mon Jun 22 01:17:44  
2009
@@ -70,18 +70,18 @@


  void Assembler::emit_rex_64(Register reg, Register rm_reg) {
-  emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
+  emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
  }


  void Assembler::emit_rex_64(Register reg, const Operand& op) {
-  emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
+  emit(0x48 | reg.high_bit() << 2 | op.rex_);
  }


  void Assembler::emit_rex_64(Register rm_reg) {
    ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code());
-  emit(0x48 | (rm_reg.code() >> 3));
+  emit(0x48 | rm_reg.high_bit());
  }


@@ -91,17 +91,17 @@


  void Assembler::emit_rex_32(Register reg, Register rm_reg) {
-  emit(0x40 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
+  emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit());
  }


  void Assembler::emit_rex_32(Register reg, const Operand& op) {
-  emit(0x40 | (reg.code() & 0x8) >> 1 | op.rex_);
+  emit(0x40 | reg.high_bit() << 2  | op.rex_);
  }


  void Assembler::emit_rex_32(Register rm_reg) {
-  emit(0x40 | (rm_reg.code() & 0x8) >> 3);
+  emit(0x40 | rm_reg.high_bit());
  }


@@ -111,19 +111,19 @@


  void Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
-  byte rex_bits = (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3;
+  byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit();
    if (rex_bits != 0) emit(0x40 | rex_bits);
  }


  void Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
-  byte rex_bits =  (reg.code() & 0x8) >> 1 | op.rex_;
+  byte rex_bits =  reg.high_bit() << 2 | op.rex_;
    if (rex_bits != 0) emit(0x40 | rex_bits);
  }


  void Assembler::emit_optional_rex_32(Register rm_reg) {
-  if (rm_reg.code() > 0x7) emit(0x41);
+  if (rm_reg.high_bit()) emit(0x41);
  }


@@ -244,11 +244,11 @@
  //  
-----------------------------------------------------------------------------
  // Implementation of Operand

-void Operand::set_modrm(int mod, Register rm) {
-  ASSERT((mod & -4) == 0);
-  buf_[0] = (mod << 6) | (rm.code() & 0x7);
+void Operand::set_modrm(int mod, Register rm_reg) {
+  ASSERT(is_uint2(mod));
+  buf_[0] = mod << 6 | rm_reg.low_bits();
    // Set REX.B to the high bit of rm.code().
-  rex_ |= (rm.code() >> 3);
+  rex_ |= rm_reg.high_bit();
  }


@@ -258,8 +258,8 @@
    // Use SIB with no index register only for base rsp or r12. Otherwise we
    // would skip the SIB byte entirely.
    ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12));
-  buf_[1] = scale << 6 | (index.code() & 0x7) << 3 | (base.code() & 0x7);
-  rex_ |= (index.code() >> 3) << 1 | base.code() >> 3;
+  buf_[1] = scale << 6 | index.low_bits() << 3 | base.low_bits();
+  rex_ |= index.high_bit() << 1 | base.high_bit();
    len_ = 2;
  }


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 Jun 22 01:17:44 2009
@@ -380,13 +380,14 @@
  }


-void Assembler::emit_operand(int rm, const Operand& adr) {
-  ASSERT_EQ(rm & 0x07, rm);
+void Assembler::emit_operand(int code, const Operand& adr) {
+  ASSERT(is_uint3(code));
    const unsigned length = adr.len_;
    ASSERT(length > 0);

    // Emit updated ModR/M byte containing the given register.
-  pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3);
+  ASSERT((adr.buf_[0] & 0x38) == 0);
+  pc_[0] = adr.buf_[0] | code << 3;

    // Emit the rest of the encoded operand.
    for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
@@ -593,7 +594,7 @@
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
    // Opcode: FF /2 r64
-  if (adr.code() > 7) {
+  if (adr.high_bit()) {
      emit_rex_64(adr);
    }
    emit(0xFF);
@@ -763,7 +764,7 @@
  void Assembler::j(Condition cc, Label* L) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  ASSERT(0 <= cc && cc < 16);
+  ASSERT(is_uint4(cc));
    if (L->is_bound()) {
      const int short_size = 2;
      const int long_size  = 6;
@@ -831,7 +832,7 @@
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
    // Opcode FF/4 r64
-  if (target.code() > 7) {
+  if (target.high_bit()) {
      emit_rex_64(target);
    }
    emit(0xFF);
@@ -982,7 +983,7 @@
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
    emit_rex_64(dst);
-  emit(0xB8 | (dst.code() & 0x7));
+  emit(0xB8 | dst.low_bits());
    emitq(reinterpret_cast<uintptr_t>(value), rmode);
  }

@@ -991,7 +992,7 @@
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
    emit_rex_64(dst);
-  emit(0xB8 | (dst.code() & 0x7));  // Not a ModR/M byte.
+  emit(0xB8 | dst.low_bits());
    emitq(value, rmode);
  }

@@ -1000,7 +1001,7 @@
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
    emit_rex_64(dst);
-  emit(0xB8 | (dst.code() & 0x7));
+  emit(0xB8 | dst.low_bits());
    emitq(reinterpret_cast<uintptr_t>(ref.address()),
          RelocInfo::EXTERNAL_REFERENCE);
  }
@@ -1021,7 +1022,7 @@
    last_pc_ = pc_;
    ASSERT(!Heap::InNewSpace(*value));
    emit_rex_64(dst);
-  emit(0xB8 | (dst.code() & 0x7));
+  emit(0xB8 | dst.low_bits());
    if (value->IsHeapObject()) {
      emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
    } else {
@@ -1192,10 +1193,10 @@
  void Assembler::pop(Register dst) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  if (dst.code() > 7) {
+  if (dst.high_bit()) {
      emit_rex_64(dst);
    }
-  emit(0x58 | (dst.code() & 0x7));
+  emit(0x58 | dst.low_bits());
  }


@@ -1218,10 +1219,10 @@
  void Assembler::push(Register src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  if (src.code() > 7) {
+  if (src.high_bit()) {
      emit_rex_64(src);
    }
-  emit(0x50 | (src.code() & 0x7));
+  emit(0x50 | src.low_bits());
  }


@@ -1295,7 +1296,7 @@
  void Assembler::setcc(Condition cc, Register reg) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  ASSERT(0 <= cc && cc < 16);
+  ASSERT(is_uint4(cc));
    if (reg.code() > 3) {  // Use x64 byte registers, where different.
      emit_rex_32(reg);
    }
@@ -1331,7 +1332,7 @@
    if (src.is(rax) || dst.is(rax)) {  // Single-byte encoding
      Register other = src.is(rax) ? dst : src;
      emit_rex_64(other);
-    emit(0x90 | (other.code() & 0x7));
+    emit(0x90 | other.low_bits());
    } else {
      emit_rex_64(src, dst);
      emit(0x87);
@@ -1755,7 +1756,7 @@

  void Assembler::emit_farith(int b1, int b2, int i) {
    ASSERT(is_uint8(b1) && is_uint8(b2));  // wrong opcode
-  ASSERT(0 <= i &&  i < 8);  // illegal stack offset
+  ASSERT(is_uint3(i));  // illegal stack offset
    emit(b1);
    emit(b2 + i);
  }

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 Jun 22 01:17:44 2009
@@ -92,6 +92,17 @@
      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_;
@@ -983,7 +994,7 @@
    // 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
@@ -993,14 +1004,14 @@

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

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

Reply via email to