Author: erik.co...@gmail.com
Date: Mon Jun 29 02:32:06 2009
New Revision: 2292

Modified:
    branches/bleeding_edge/src/arm/assembler-arm.cc
    branches/bleeding_edge/src/arm/disasm-arm.cc
    branches/bleeding_edge/src/ia32/assembler-ia32.cc
    branches/bleeding_edge/src/ia32/assembler-ia32.h
    branches/bleeding_edge/src/x64/assembler-x64.cc
    branches/bleeding_edge/src/x64/assembler-x64.h
    branches/bleeding_edge/test/cctest/test-assembler-x64.cc

Log:
* Add missing imul instruction on Intel.
* Fix incorrect signedness in disassembly of umull/mull on ARM.
* Fix incorrect register order in disassembly of umull/mull.
* Fix incorrect assembly of umull on ARM.
* Remove retroactively obsoleted restriction on choice of
   registers in mul instructions on ARM.
Review URL: http://codereview.chromium.org/150002

Modified: branches/bleeding_edge/src/arm/assembler-arm.cc
==============================================================================
--- branches/bleeding_edge/src/arm/assembler-arm.cc     (original)
+++ branches/bleeding_edge/src/arm/assembler-arm.cc     Mon Jun 29 02:32:06 2009
@@ -816,7 +816,6 @@
  void Assembler::mla(Register dst, Register src1, Register src2, Register  
srcA,
                      SBit s, Condition cond) {
    ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
-  ASSERT(!dst.is(src1));
    emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
         src2.code()*B8 | B7 | B4 | src1.code());
  }
@@ -825,7 +824,6 @@
  void Assembler::mul(Register dst, Register src1, Register src2,
                      SBit s, Condition cond) {
    ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dst.is(src1));
    emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
  }

@@ -837,7 +835,7 @@
                        SBit s,
                        Condition cond) {
    ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
+  ASSERT(!dstL.is(dstH));
    emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
         src2.code()*B8 | B7 | B4 | src1.code());
  }
@@ -850,7 +848,7 @@
                        SBit s,
                        Condition cond) {
    ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
+  ASSERT(!dstL.is(dstH));
    emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
         src2.code()*B8 | B7 | B4 | src1.code());
  }
@@ -863,7 +861,7 @@
                        SBit s,
                        Condition cond) {
    ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
+  ASSERT(!dstL.is(dstH));
    emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
         src2.code()*B8 | B7 | B4 | src1.code());
  }
@@ -876,8 +874,8 @@
                        SBit s,
                        Condition cond) {
    ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
-  emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
+  ASSERT(!dstL.is(dstH));
+  emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
         src2.code()*B8 | B7 | B4 | src1.code());
  }


Modified: branches/bleeding_edge/src/arm/disasm-arm.cc
==============================================================================
--- branches/bleeding_edge/src/arm/disasm-arm.cc        (original)
+++ branches/bleeding_edge/src/arm/disasm-arm.cc        Mon Jun 29 02:32:06 2009
@@ -438,7 +438,7 @@
        return 6;
      }
      case 'u': {  // 'u: signed or unsigned multiplies
-      if (instr->Bit(22) == 0) {
+      if (instr->Bit(22) == 1) {
          Print("u");
        } else {
          Print("s");
@@ -499,7 +499,7 @@
              Format(instr, "mla'cond's 'rd, 'rm, 'rs, 'rn");
            }
          } else {
-          Format(instr, "'um'al'cond's 'rn, 'rd, 'rs, 'rm");
+          Format(instr, "'um'al'cond's 'rn, 'rd, 'rm, 'rs");
          }
        } else {
          Unknown(instr);  // not used by V8

Modified: branches/bleeding_edge/src/ia32/assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/assembler-ia32.cc   (original)
+++ branches/bleeding_edge/src/ia32/assembler-ia32.cc   Mon Jun 29 02:32:06  
2009
@@ -919,6 +919,14 @@
  }


+void Assembler::imul(Register reg) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xF7);
+  EMIT(0xE8 | reg.code());
+}
+
+
  void Assembler::imul(Register dst, const Operand& src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;

Modified: branches/bleeding_edge/src/ia32/assembler-ia32.h
==============================================================================
--- branches/bleeding_edge/src/ia32/assembler-ia32.h    (original)
+++ branches/bleeding_edge/src/ia32/assembler-ia32.h    Mon Jun 29 02:32:06  
2009
@@ -544,15 +544,18 @@

    void idiv(Register src);

-  void imul(Register dst, const Operand& src);
-  void imul(Register dst, Register src, int32_t imm32);
+  // Signed multiply instructions.
+  void imul(Register src);                               // edx:eax = eax  
* src.
+  void imul(Register dst, const Operand& src);           // dst = dst *  
src.
+  void imul(Register dst, Register src, int32_t imm32);  // dst = src *  
imm32.

    void inc(Register dst);
    void inc(const Operand& dst);

    void lea(Register dst, const Operand& src);

-  void mul(Register src);
+  // Unsigned multiply instruction.
+  void mul(Register src);                                // edx:eax = eax  
* reg.

    void neg(Register dst);


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 29 02:32:06 2009
@@ -750,6 +750,15 @@
  }


+void Assembler::imul(Register src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_rex_64(src);
+  emit(0xF7);
+  emit_modrm(0x5, src);
+}
+
+
  void Assembler::imul(Register dst, Register src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;

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 29 02:32:06 2009
@@ -605,12 +605,13 @@
    // Divide rdx:rax by src.  Quotient in rax, remainder in rdx.
    void idiv(Register src);

-  void imul(Register dst, Register src);
-  void imul(Register dst, const Operand& src);
-  // Performs the operation dst = src * imm.
-  void imul(Register dst, Register src, Immediate imm);
+  // Signed multiply instructions.
+  void imul(Register src);                               // rdx:rax = rax  
* src.
+  void imul(Register dst, Register src);                 // dst = dst *  
src.
+  void imul(Register dst, const Operand& src);           // dst = dst *  
src.
+  void imul(Register dst, Register src, Immediate imm);  // dst = src *  
imm.
    // Multiply 32 bit registers
-  void imull(Register dst, Register src);
+  void imull(Register dst, Register src);                // dst = dst *  
src.

    void incq(Register dst);
    void incq(const Operand& dst);

Modified: branches/bleeding_edge/test/cctest/test-assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-assembler-x64.cc    (original)
+++ branches/bleeding_edge/test/cctest/test-assembler-x64.cc    Mon Jun 29  
02:32:06 2009
@@ -44,6 +44,7 @@
  using v8::internal::rax;
  using v8::internal::rsi;
  using v8::internal::rdi;
+using v8::internal::rdx;
  using v8::internal::rbp;
  using v8::internal::rsp;
  using v8::internal::FUNCTION_CAST;
@@ -63,8 +64,8 @@
  // with GCC.  A different convention is used on 64-bit windows.

  typedef int (*F0)();
-typedef int (*F1)(int x);
-typedef int (*F2)(int x, int y);
+typedef int (*F1)(int64_t x);
+typedef int (*F2)(int64_t x, int64_t y);

  #define __ assm.

@@ -130,7 +131,7 @@
    CHECK(buffer);
    Assembler assm(buffer, actual_size);

-  // Assemble a simple function that copies argument 2 and returns it.
+  // Assemble a simple function that adds arguments returning the sum.
    __ movq(rax, rsi);
    __ addq(rax, rdi);
    __ ret(0);
@@ -140,6 +141,33 @@
    // Call the function from C++.
    int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
    CHECK_EQ(5, result);
+}
+
+TEST(AssemblerX64ImulOperation) {
+  // Allocate an executable page of memory.
+  size_t actual_size;
+  byte* buffer =  
static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+                                                 &actual_size,
+                                                 true));
+  CHECK(buffer);
+  Assembler assm(buffer, actual_size);
+
+  // Assemble a simple function that multiplies arguments returning the  
high
+  // word.
+  __ movq(rax, rsi);
+  __ imul(rdi);
+  __ movq(rax, rdx);
+  __ ret(0);
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  // Call the function from C++.
+  int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
+  CHECK_EQ(0, result);
+  result =  FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l);
+  CHECK_EQ(1, result);
+  result =  FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l);
+  CHECK_EQ(-1, result);
  }

  TEST(AssemblerX64MemoryOperands) {

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to