Revision: 18823
Author:   [email protected]
Date:     Fri Jan 24 13:24:18 2014 UTC
Log:      A64: Implement LModI for ARM A64.

BUG=none
[email protected]

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

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/a64/lithium-a64.cc Fri Jan 24 11:30:56 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.cc Fri Jan 24 13:24:18 2014 UTC
@@ -1761,16 +1761,37 @@
 }


-LInstruction* LChunkBuilder::DoMod(HMod* instr) {
-  if (instr->representation().IsInteger32()) {
-    ASSERT(instr->left()->representation().IsInteger32());
-    ASSERT(instr->right()->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoMod(HMod* hmod) {
+  HValue* hleft = hmod->left();
+  HValue* hright = hmod->right();
+
+  if (hmod->representation().IsInteger32()) {
+    ASSERT(hleft->representation().IsInteger32());
+    ASSERT(hleft->representation().IsInteger32());
+    LOperand* left_op;
+    LOperand* right_op;
+
+    if (hmod->HasPowerOf2Divisor()) {
+      left_op = UseRegisterAtStart(hleft);
+      right_op = UseConstant(hright);
+    } else {
+      right_op = UseRegister(hright);
+      left_op = UseRegister(hleft);
+    }
+
+    LModI* lmod = new(zone()) LModI(left_op, right_op);
+
+    if (hmod->right()->CanBeZero() ||
+        (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
+         hmod->left()->CanBeNegative() && hmod->CanBeZero())) {
+      AssignEnvironment(lmod);
+    }
+    return DefineAsRegister(lmod);

-    UNIMPLEMENTED_INSTRUCTION();
-  } else if (instr->representation().IsSmiOrTagged()) {
-    UNIMPLEMENTED_INSTRUCTION();
+  } else if (hmod->representation().IsSmiOrTagged()) {
+    return DoArithmeticT(Token::MOD, hmod);
   } else {
-    return DoArithmeticD(Token::MOD, instr);
+    return DoArithmeticD(Token::MOD, hmod);
   }
 }

=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 18:07:26 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.h Fri Jan 24 13:24:18 2014 UTC
@@ -148,6 +148,7 @@
   V(MathSin)                                    \
   V(MathSqrt)                                   \
   V(MathTan)                                    \
+  V(ModI)                                       \
   V(MulConstI)                                  \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -1926,6 +1927,21 @@
 };


+class LModI: public LTemplateInstruction<1, 2, 0> {
+ public:
+  LModI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
+  DECLARE_HYDROGEN_ACCESSOR(Mod)
+};
+
+
 class LMulConstI: public LTemplateInstruction<1, 2, 0> {
  public:
   LMulConstI(LOperand* left, LConstantOperand* right) {
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Fri Jan 24 11:30:56 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Fri Jan 24 13:24:18 2014 UTC
@@ -3801,6 +3801,64 @@
     }
   }
 }
+
+
+void LCodeGen::DoModI(LModI* instr) {
+  HMod* hmod = instr->hydrogen();
+  HValue* hleft = hmod->left();
+  HValue* hright = hmod->right();
+
+  Label done;
+  Register result = ToRegister32(instr->result());
+  Register dividend = ToRegister32(instr->left());
+
+ bool need_minus_zero_check = (hmod->CheckFlag(HValue::kBailoutOnMinusZero) && + hleft->CanBeNegative() && hmod->CanBeZero());
+
+  if (hmod->HasPowerOf2Divisor()) {
+    // Note: The code below even works when right contains kMinInt.
+    int32_t divisor = Abs(hright->GetInteger32Constant());
+
+    if (hleft->CanBeNegative()) {
+      __ Cmp(dividend, 0);
+      __ Cneg(result, dividend, mi);
+      __ And(result, result, divisor - 1);
+      __ Cneg(result, result, mi);
+      if (need_minus_zero_check) {
+        __ Cbnz(result, &done);
+        // The result is 0. Deoptimize if the dividend was negative.
+        DeoptimizeIf(mi, instr->environment());
+      }
+    } else {
+      __ And(result, dividend, divisor - 1);
+    }
+
+  } else {
+    Label deopt;
+    Register divisor = ToRegister32(instr->right());
+    // Compute:
+    //   modulo = dividend - quotient * divisor
+    __ Sdiv(result, dividend, divisor);
+    if (hright->CanBeZero()) {
+      // Combine the deoptimization sites.
+      Label ok;
+      __ Cbnz(divisor, &ok);
+      __ Bind(&deopt);
+      Deoptimize(instr->environment());
+      __ Bind(&ok);
+    }
+    __ Msub(result, result, divisor, dividend);
+    if (need_minus_zero_check) {
+      __ Cbnz(result, &done);
+      if (deopt.is_bound()) {
+        __ Tbnz(dividend, kWSignBit, &deopt);
+      } else {
+        DeoptimizeIfNegative(dividend, instr->environment());
+      }
+    }
+  }
+  __ Bind(&done);
+}


 void LCodeGen::DoMulConstI(LMulConstI* instr) {

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