Revision: 6681
Author: [email protected]
Date: Tue Feb  8 06:37:50 2011
Log: x64: Add MulI and DivI to lithium instructions.


Review URL: http://codereview.chromium.org/6448001
http://code.google.com/p/v8/source/detail?r=6681

Added:
 /branches/bleeding_edge/test/mjsunit/regress/regress-1117.js
Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/x64/assembler-x64.cc
 /branches/bleeding_edge/src/x64/assembler-x64.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-1117.js Tue Feb 8 06:37:50 2011
@@ -0,0 +1,35 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that we actually return the right value (-0) when we multiply
+// constant 0 with a negative integer.
+
+function foo(y) {return 0 * y; }
+for( var i = 0; i< 1000000; i++){
+  foo(42);
+}
+assertEquals(1/foo(-42), -Infinity);
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Tue Feb  8 02:45:21 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Tue Feb  8 06:37:50 2011
@@ -1306,10 +1306,10 @@
     // the generated code, which requires registers r0
     // and r1 to be used. We should remove that
     // when we provide a native implementation.
-    LOperand* value = UseFixed(instr->left(), r0);
+    LOperand* dividend = UseFixed(instr->left(), r0);
     LOperand* divisor = UseFixed(instr->right(), r1);
     return AssignEnvironment(AssignPointerMap(
-             DefineFixed(new LDivI(value, divisor), r0)));
+             DefineFixed(new LDivI(dividend, divisor), r0)));
   } else {
     return DoArithmeticT(Token::DIV, instr);
   }
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Feb 8 02:08:47 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Feb 8 06:37:50 2011
@@ -1188,7 +1188,7 @@
     __ tst(left, Operand(left));
     __ b(ne, &done);
     if (instr->InputAt(1)->IsConstantOperand()) {
-      if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) < 0) {
+      if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) {
         DeoptimizeIf(kNoCondition, instr->environment());
       }
     } else {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Feb 8 02:08:47 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Feb 8 06:37:50 2011
@@ -804,7 +804,7 @@
     __ test(left, Operand(left));
     __ j(not_zero, &done);
     if (right->IsConstantOperand()) {
-      if (ToInteger32(LConstantOperand::cast(right)) < 0) {
+      if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
         DeoptimizeIf(no_condition, instr->environment());
       }
     } else {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Feb 8 02:45:21 2011 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Feb 8 06:37:50 2011
@@ -1322,9 +1322,9 @@
// The temporary operand is necessary to ensure that right is not allocated
     // into edx.
     LOperand* temp = FixedTemp(edx);
-    LOperand* value = UseFixed(instr->left(), eax);
+    LOperand* dividend = UseFixed(instr->left(), eax);
     LOperand* divisor = UseRegister(instr->right());
-    LDivI* result = new LDivI(value, divisor, temp);
+    LDivI* result = new LDivI(dividend, divisor, temp);
     return AssignEnvironment(DefineFixed(result, eax));
   } else {
     ASSERT(instr->representation().IsTagged());
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Mon Feb 7 06:15:05 2011 +++ /branches/bleeding_edge/src/x64/assembler-x64.cc Tue Feb 8 06:37:50 2011
@@ -1186,6 +1186,16 @@
   emit(0xAF);
   emit_modrm(dst, src);
 }
+
+
+void Assembler::imull(Register dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xAF);
+  emit_operand(dst, src);
+}


 void Assembler::imull(Register dst, Register src, Immediate imm) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h     Mon Feb  7 23:49:59 2011
+++ /branches/bleeding_edge/src/x64/assembler-x64.h     Tue Feb  8 06:37:50 2011
@@ -865,6 +865,7 @@
void imul(Register dst, Register src, Immediate imm); // dst = src * imm.
   // Signed 32-bit multiply instructions.
void imull(Register dst, Register src); // dst = dst * src. + void imull(Register dst, const Operand& src); // dst = dst * src. void imull(Register dst, Register src, Immediate imm); // dst = src * imm.

   void incq(Register dst);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Feb 8 03:26:42 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Feb 8 06:37:50 2011
@@ -657,11 +657,92 @@


 void LCodeGen::DoDivI(LDivI* instr) {
-  Abort("Unimplemented: %s", "DoDivI");}
+  LOperand* right = instr->InputAt(1);
+  ASSERT(ToRegister(instr->result()).is(rax));
+  ASSERT(ToRegister(instr->InputAt(0)).is(rax));
+  ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
+  ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
+
+  Register left_reg = rax;
+
+  // Check for x / 0.
+  Register right_reg = ToRegister(right);
+  if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ testl(right_reg, right_reg);
+    DeoptimizeIf(zero, instr->environment());
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    NearLabel left_not_zero;
+    __ testl(left_reg, left_reg);
+    __ j(not_zero, &left_not_zero);
+    __ testl(right_reg, right_reg);
+    DeoptimizeIf(sign, instr->environment());
+    __ bind(&left_not_zero);
+  }
+
+  // Check for (-kMinInt / -1).
+  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+    NearLabel left_not_min_int;
+    __ cmpl(left_reg, Immediate(kMinInt));
+    __ j(not_zero, &left_not_min_int);
+    __ cmpl(right_reg, Immediate(-1));
+    DeoptimizeIf(zero, instr->environment());
+    __ bind(&left_not_min_int);
+  }
+
+  // Sign extend to rdx.
+  __ cdq();
+  __ idivl(right_reg);
+
+  // Deoptimize if remainder is not 0.
+  __ testl(rdx, rdx);
+  DeoptimizeIf(not_zero, instr->environment());
+}


 void LCodeGen::DoMulI(LMulI* instr) {
-  Abort("Unimplemented: %s", "DoMultI");}
+  Register left = ToRegister(instr->InputAt(0));
+  LOperand* right = instr->InputAt(1);
+
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    __ movl(kScratchRegister, left);
+  }
+
+  if (right->IsConstantOperand()) {
+    int right_value = ToInteger32(LConstantOperand::cast(right));
+    __ imull(left, left, Immediate(right_value));
+  } else if (right->IsStackSlot()) {
+    __ imull(left, ToOperand(right));
+  } else {
+    __ imull(left, ToRegister(right));
+  }
+
+  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+    DeoptimizeIf(overflow, instr->environment());
+  }
+
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    // Bail out if the result is supposed to be negative zero.
+    NearLabel done;
+    __ testl(left, left);
+    __ j(not_zero, &done);
+    if (right->IsConstantOperand()) {
+      if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
+        DeoptimizeIf(no_condition, instr->environment());
+      }
+    } else if (right->IsStackSlot()) {
+      __ or_(kScratchRegister, ToOperand(right));
+      DeoptimizeIf(sign, instr->environment());
+    } else {
+      // Test the non-zero operand for negative sign.
+      __ or_(kScratchRegister, ToRegister(right));
+      DeoptimizeIf(sign, instr->environment());
+    }
+    __ bind(&done);
+  }
+}


 void LCodeGen::DoBitI(LBitI* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Tue Feb  8 03:26:42 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Tue Feb  8 06:37:50 2011
@@ -1264,8 +1264,20 @@


 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
-  Abort("Unimplemented: %s", "DoDiv");
-  return NULL;
+  if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::DIV, instr);
+  } else if (instr->representation().IsInteger32()) {
+ // The temporary operand is necessary to ensure that right is not allocated
+    // into rdx.
+    LOperand* temp = FixedTemp(rdx);
+    LOperand* dividend = UseFixed(instr->left(), rax);
+    LOperand* divisor = UseRegister(instr->right());
+    LDivI* result = new LDivI(dividend, divisor, temp);
+    return AssignEnvironment(DefineFixed(result, rax));
+  } else {
+    ASSERT(instr->representation().IsTagged());
+    return DoArithmeticT(Token::DIV, instr);
+  }
 }


@@ -1276,8 +1288,19 @@


 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
-  Abort("Unimplemented: %s", "DoMul");
-  return NULL;
+  if (instr->representation().IsInteger32()) {
+    ASSERT(instr->left()->representation().IsInteger32());
+    ASSERT(instr->right()->representation().IsInteger32());
+    LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
+    LOperand* right = UseOrConstant(instr->MostConstantOperand());
+    LMulI* mul = new LMulI(left, right);
+    return AssignEnvironment(DefineSameAsFirst(mul));
+  } else if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::MUL, instr);
+  } else {
+    ASSERT(instr->representation().IsTagged());
+    return DoArithmeticT(Token::MUL, instr);
+  }
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Tue Feb  8 02:45:21 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Tue Feb  8 06:37:50 2011
@@ -539,12 +539,11 @@
 };


-class LMulI: public LTemplateInstruction<1, 2, 1> {
+class LMulI: public LTemplateInstruction<1, 2, 0> {
  public:
-  LMulI(LOperand* left, LOperand* right, LOperand* temp) {
+  LMulI(LOperand* left, LOperand* right) {
     inputs_[0] = left;
     inputs_[1] = right;
-    temps_[0] = temp;
   }

   DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")

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

Reply via email to