Revision: 18780
Author:   [email protected]
Date:     Thu Jan 23 13:53:20 2014 UTC
Log: A64: Implement LMathFloorOfDiv and enable the instruction in hydrogen

BUG=314606
[email protected], [email protected]

Review URL: https://codereview.chromium.org/145273005
http://code.google.com/p/v8/source/detail?r=18780

Modified:
 /branches/experimental/a64/src/a64/lithium-a64.cc
 /branches/experimental/a64/src/a64/lithium-a64.h
 /branches/experimental/a64/src/a64/lithium-codegen-a64.cc
 /branches/experimental/a64/src/hydrogen-instructions.cc

=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Thu Jan 23 13:51:32 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.cc Thu Jan 23 13:53:20 2014 UTC
@@ -1690,10 +1690,48 @@
   LOperand* map = UseRegisterAtStart(instr->value());
   return DefineAsRegister(new(zone()) LMapEnumLength(map));
 }
+
+
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { + // A value with an integer representation does not need to be transformed.
+  if (dividend->representation().IsInteger32()) {
+    return dividend;
+  // A change from an integer32 can be replaced by the integer32 value.
+  } else if (dividend->IsChange() &&
+      HChange::cast(dividend)->from().IsInteger32()) {
+    return HChange::cast(dividend)->value();
+  }
+  return NULL;
+}
+
+
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { + // A value with an integer representation does not need to be transformed.
+  if (divisor->representation().IsInteger32()) {
+    return divisor;
+  // A change from an integer32 can be replaced by the integer32 value.
+  } else if (divisor->IsChange() &&
+             HChange::cast(divisor)->from().IsInteger32()) {
+    return HChange::cast(divisor)->value();
+  }
+
+ if (divisor->IsConstant() && HConstant::cast(divisor)->HasInteger32Value()) {
+    HConstant* constant_val = HConstant::cast(divisor);
+    return constant_val->CopyToRepresentation(Representation::Integer32(),
+                                              divisor->block()->zone());
+  }
+
+  return NULL;
+}


 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
-  UNIMPLEMENTED_INSTRUCTION();
+  HValue* right = instr->right();
+  LOperand* dividend = UseRegister(instr->left());
+  LOperand* divisor = UseRegister(right);
+  LOperand* remainder = TempRegister();
+  return AssignEnvironment(DefineAsRegister(
+          new(zone()) LMathFloorOfDiv(dividend, divisor, remainder)));
 }


=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 13:51:32 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 13:53:20 2014 UTC
@@ -139,6 +139,7 @@
   V(MathAbsTagged)                              \
   V(MathExp)                                    \
   V(MathFloor)                                  \
+  V(MathFloorOfDiv)                             \
   V(MathLog)                                    \
   V(MathMinMax)                                 \
   V(MathPowHalf)                                \
@@ -1835,6 +1836,25 @@
 };


+class LMathFloorOfDiv : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LMathFloorOfDiv(LOperand* left,
+                  LOperand* right,
+                  LOperand* temp = NULL) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+    temps_[0] = temp;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
 class LMathLog: public LUnaryMathOperation<0> {
  public:
   explicit LMathLog(LOperand* value) : LUnaryMathOperation<0>(value) { }
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Thu Jan 23 13:51:32 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Thu Jan 23 13:53:20 2014 UTC
@@ -3587,6 +3587,49 @@

   __ Bind(&done);
 }
+
+
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+  const Register result = ToRegister32(instr->result());
+  const Register left = ToRegister32(instr->left());
+  const Register right = ToRegister32(instr->right());
+  const Register remainder = ToRegister32(instr->temp());
+
+  // Check for x / 0.
+  DeoptimizeIfZero(right, instr->environment());
+
+  // Check for (kMinInt / -1).
+  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+    __ Cmp(left, kMinInt);
+    __ Ccmp(right, -1, ZFlag, eq);
+    DeoptimizeIf(eq, instr->environment());
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    __ Cmp(right, 0);
+    __ Ccmp(left, 0, ZFlag, mi);
+    // "right" can't be null because the code would have already been
+    // deoptimized. The Z flag is set only if (right < 0) and (left == 0).
+    // In this case we need to deoptimize to produce a -0.
+    DeoptimizeIf(eq, instr->environment());
+  }
+
+  Label done;
+  __ Sdiv(result, left, right);
+  // If both operands have the same sign then we are done.
+  __ Eor(remainder, left, Operand(right));
+  __ Tbz(remainder, kWSignBit, &done);
+
+  // Check if the result needs to be corrected.
+  __ Mul(remainder, result, right);
+  __ Sub(remainder, remainder, left);
+  __ Cmp(remainder, 0);
+  __ B(eq, &done);
+  __ Sub(result, result, Operand(1));
+
+  __ Bind(&done);
+}


 void LCodeGen::DoMathLog(LMathLog* instr) {
=======================================
--- /branches/experimental/a64/src/hydrogen-instructions.cc Wed Jan 22 11:44:47 2014 UTC +++ /branches/experimental/a64/src/hydrogen-instructions.cc Thu Jan 23 13:53:20 2014 UTC
@@ -1526,7 +1526,7 @@
     if (value()->representation().IsInteger32()) return value();

 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
-        defined(V8_TARGET_ARCH_X64)
+        defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_A64)
     if (value()->IsDiv() && (value()->UseCount() == 1)) {
       // TODO(2038): Implement this optimization for non ARM architectures.
       HDiv* hdiv = HDiv::cast(value());

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to