Revision: 18779
Author:   [email protected]
Date:     Thu Jan 23 13:51:32 2014 UTC
Log: A64: Implement LPower and extend MathPowStub to support args in registers

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

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

Modified:
 /branches/experimental/a64/src/a64/code-stubs-a64.cc
 /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/code-stubs-a64.cc Wed Jan 22 12:46:44 2014 UTC +++ /branches/experimental/a64/src/a64/code-stubs-a64.cc Thu Jan 23 13:51:32 2014 UTC
@@ -2253,9 +2253,11 @@
   Register exponent_integer = x12;
   Register scratch1 = x14;
   Register scratch0 = x15;
+  Register saved_lr = x19;
   FPRegister result_double = d0;
-  FPRegister base_double = d1;
-  FPRegister exponent_double = d2;
+  FPRegister base_double = d0;
+  FPRegister exponent_double = d1;
+  FPRegister base_double_copy = d2;
   FPRegister scratch1_double = d6;
   FPRegister scratch0_double = d7;

@@ -2266,10 +2268,6 @@
   // Allocate a heap number for the result, and return it.
   Label done;

- // TODO(all): Cases other than ON_STACK are only used by Lithium, and we do
-  // not yet support them.
-  ASSERT(exponent_type_ == ON_STACK);
-
   // Unpack the inputs.
   if (exponent_type_ == ON_STACK) {
     Label base_is_smi;
@@ -2295,8 +2293,10 @@
     // exponent_tagged is a heap number, so load its double value.
     __ Ldr(exponent_double,
            FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset));
-  } else {
- UNIMPLEMENTED_M("MathPowStub types other than ON_STACK are unimplemented.");
+  } else if (exponent_type_ == TAGGED) {
+    __ JumpIfSmi(exponent_tagged, &exponent_is_smi);
+    __ Ldr(exponent_double,
+           FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset));
   }

   // Handle double (heap number) exponents.
@@ -2383,17 +2383,17 @@
       __ Fmov(scratch0_double, 1.0);
       __ Fdiv(result_double, scratch0_double, result_double);
       __ B(&done);
-    } else {
-      UNIMPLEMENTED_M(
-          "MathPowStub types other than ON_STACK are unimplemented.");
     }

- // TODO(all): From here, call the C power function for non-ON_STACK types.
-    // ON_STACK types should not be able to reach this point.
-    ASM_UNIMPLEMENTED_BREAK(
-        "MathPowStub types other than ON_STACK are unimplemented.");
-  } else {
- UNIMPLEMENTED_M("MathPowStub types other than ON_STACK are unimplemented.");
+    {
+      AllowExternalCallThatCantCauseGC scope(masm);
+      __ Mov(saved_lr, lr);
+      __ CallCFunction(
+          ExternalReference::power_double_double_function(masm->isolate()),
+          0, 2);
+      __ Mov(lr, saved_lr);
+      __ B(&done);
+    }
   }

   // Handle integer (and SMI) exponents.
@@ -2427,6 +2427,7 @@
   //  }
   Label power_loop, power_loop_entry, power_loop_exit;
   __ Fmov(scratch1_double, base_double);
+  __ Fmov(base_double_copy, base_double);
   __ Fmov(result_double, 1.0);
   __ B(&power_loop_entry);

@@ -2474,7 +2475,18 @@
         masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1);
     __ Ret();
   } else {
- UNIMPLEMENTED_M("MathPowStub types other than ON_STACK are unimplemented.");
+    AllowExternalCallThatCantCauseGC scope(masm);
+    __ Mov(saved_lr, lr);
+    __ Fmov(base_double, base_double_copy);
+    __ Scvtf(exponent_double, exponent_integer);
+    __ CallCFunction(
+        ExternalReference::power_double_double_function(masm->isolate()),
+        0, 2);
+    __ Mov(lr, saved_lr);
+    __ Bind(&done);
+    __ IncrementCounter(
+        masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1);
+    __ Ret();
   }
 }

=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Thu Jan 23 12:18:12 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.cc Thu Jan 23 13:51:32 2014 UTC
@@ -1812,7 +1812,19 @@


 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
-  UNIMPLEMENTED_INSTRUCTION();
+  ASSERT(instr->representation().IsDouble());
+  // We call a C function for double power. It can't trigger a GC.
+  // We need to use fixed result register for the call.
+  Representation exponent_type = instr->right()->representation();
+  ASSERT(instr->left()->representation().IsDouble());
+  LOperand* left = UseFixedDouble(instr->left(), d0);
+  LOperand* right = exponent_type.IsDouble() ?
+      UseFixedDouble(instr->right(), d1) :
+      UseFixed(instr->right(), x11);
+  LPower* result = new(zone()) LPower(left, right);
+  return MarkAsCall(DefineFixedDouble(result, d0),
+                    instr,
+                    CAN_DEOPTIMIZE_EAGERLY);
 }


=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 12:18:12 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 13:51:32 2014 UTC
@@ -154,6 +154,7 @@
   V(OsrEntry)                                   \
   V(OuterContext)                               \
   V(Parameter)                                  \
+  V(Power)                                      \
   V(PushArgument)                               \
   V(RegExpLiteral)                              \
   V(Return)                                     \
@@ -1985,6 +1986,21 @@
 };


+class LPower: public LTemplateInstruction<1, 2, 0> {
+ public:
+  LPower(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
+  DECLARE_HYDROGEN_ACCESSOR(Power)
+};
+
+
 class LPushArgument: public LTemplateInstruction<0, 1, 0> {
  public:
   explicit LPushArgument(LOperand* value) {
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Thu Jan 23 12:18:12 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Thu Jan 23 13:51:32 2014 UTC
@@ -3622,6 +3622,40 @@

   __ Bind(&done);
 }
+
+
+void LCodeGen::DoPower(LPower* instr) {
+ Representation exponent_type = instr->hydrogen()->right()->representation();
+  // Having marked this as a call, we can use any registers.
+  // Just make sure that the input/output registers are the expected ones.
+  ASSERT(!instr->right()->IsDoubleRegister() ||
+         ToDoubleRegister(instr->right()).is(d1));
+  ASSERT(!instr->right()->IsRegister() ||
+         ToRegister(instr->right()).is(x11));
+  ASSERT(ToDoubleRegister(instr->left()).is(d0));
+  ASSERT(ToDoubleRegister(instr->result()).is(d0));
+
+  if (exponent_type.IsSmi()) {
+    MathPowStub stub(MathPowStub::TAGGED);
+    __ CallStub(&stub);
+  } else if (exponent_type.IsTagged()) {
+    Label no_deopt;
+    __ JumpIfSmi(x11, &no_deopt);
+    __ Ldr(x0, FieldMemOperand(x11, HeapObject::kMapOffset));
+    DeoptimizeIfNotRoot(x0, Heap::kHeapNumberMapRootIndex,
+                        instr->environment());
+    __ Bind(&no_deopt);
+    MathPowStub stub(MathPowStub::TAGGED);
+    __ CallStub(&stub);
+  } else if (exponent_type.IsInteger32()) {
+    MathPowStub stub(MathPowStub::INTEGER);
+    __ CallStub(&stub);
+  } else {
+    ASSERT(exponent_type.IsDouble());
+    MathPowStub stub(MathPowStub::DOUBLE);
+    __ CallStub(&stub);
+  }
+}


 void LCodeGen::DoMathRound(LMathRound* 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