Revision: 6909
Author: [email protected]
Date: Wed Feb 23 02:41:13 2011
Log: ARM: Implement DoPower in the lithium code generator.

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

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.h
 /branches/bleeding_edge/src/assembler.cc
 /branches/bleeding_edge/src/v8.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Mon Feb 21 02:30:25 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Feb 23 02:41:13 2011
@@ -1417,8 +1417,19 @@


 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
-  Abort("LPower instruction not implemented on ARM");
-  return NULL;
+  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(), d1);
+  LOperand* right = exponent_type.IsDouble() ?
+      UseFixedDouble(instr->right(), d2) :
+      UseFixed(instr->right(), r0);
+  LPower* result = new LPower(left, right);
+  return MarkAsCall(DefineFixedDouble(result, d3),
+                    instr,
+                    CAN_DEOPTIMIZE_EAGERLY);
 }


=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Wed Feb 16 00:21:45 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Wed Feb 23 02:41:13 2011
@@ -135,6 +135,7 @@
   V(OuterContext)                               \
   V(Parameter)                                  \
   V(PixelArrayLength)                           \
+  V(Power)                                      \
   V(PushArgument)                               \
   V(RegExpLiteral)                              \
   V(Return)                                     \
@@ -1058,6 +1059,18 @@
 };


+class LPower: public LTemplateInstruction<1, 2, 0> {
+ public:
+  LPower(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
+  DECLARE_HYDROGEN_ACCESSOR(Power)
+};
+
+
 class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
  public:
   LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Feb 22 08:56:57 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Feb 23 02:41:13 2011
@@ -1226,7 +1226,7 @@
       __ vmov(r2, r3, right);
__ CallCFunction(ExternalReference::double_fp_operation(Token::MOD), 4);
       // Move the result in the double result register.
-      __ vmov(ToDoubleRegister(instr->result()), r0, r1);
+      __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result()));

       // Restore r0-r3.
       __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
@@ -2682,6 +2682,64 @@
   ASSERT(ToDoubleRegister(instr->result()).is(input));
   __ vsqrt(input, input);
 }
+
+
+void LCodeGen::DoPower(LPower* instr) {
+  LOperand* left = instr->InputAt(0);
+  LOperand* right = instr->InputAt(1);
+  Register scratch = scratch0();
+  DoubleRegister result_reg = ToDoubleRegister(instr->result());
+ Representation exponent_type = instr->hydrogen()->right()->representation();
+  if (exponent_type.IsDouble()) {
+    // Prepare arguments and call C function.
+    __ PrepareCallCFunction(4, scratch);
+    __ vmov(r0, r1, ToDoubleRegister(left));
+    __ vmov(r2, r3, ToDoubleRegister(right));
+    __ CallCFunction(ExternalReference::power_double_double_function(), 4);
+  } else if (exponent_type.IsInteger32()) {
+    ASSERT(ToRegister(right).is(r0));
+    // Prepare arguments and call C function.
+    __ PrepareCallCFunction(4, scratch);
+    __ mov(r2, ToRegister(right));
+    __ vmov(r0, r1, ToDoubleRegister(left));
+    __ CallCFunction(ExternalReference::power_double_int_function(), 4);
+  } else {
+    ASSERT(exponent_type.IsTagged());
+    ASSERT(instr->hydrogen()->left()->representation().IsDouble());
+
+    Register right_reg = ToRegister(right);
+
+    // Check for smi on the right hand side.
+    Label non_smi, call;
+    __ JumpIfNotSmi(right_reg, &non_smi);
+
+    // Untag smi and convert it to a double.
+    __ SmiUntag(right_reg);
+    SwVfpRegister single_scratch = double_scratch0().low();
+    __ vmov(single_scratch, right_reg);
+    __ vcvt_f64_s32(result_reg, single_scratch);
+    __ jmp(&call);
+
+    // Heap number map check.
+    __ bind(&non_smi);
+    __ ldr(scratch, FieldMemOperand(right_reg, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
+    __ cmp(scratch, Operand(ip));
+    DeoptimizeIf(ne, instr->environment());
+    int32_t value_offset = HeapNumber::kValueOffset - kHeapObjectTag;
+    __ add(scratch, right_reg, Operand(value_offset));
+    __ vldr(result_reg, scratch, 0);
+
+    // Prepare arguments and call C function.
+    __ bind(&call);
+    __ PrepareCallCFunction(4, scratch);
+    __ vmov(r0, r1, ToDoubleRegister(left));
+    __ vmov(r2, r3, result_reg);
+    __ CallCFunction(ExternalReference::power_double_double_function(), 4);
+  }
+  // Store the result in the result register.
+  __ GetCFunctionDoubleResult(result_reg);
+}


 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Feb 21 03:29:45 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Feb 23 02:41:13 2011
@@ -745,6 +745,14 @@
     add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2));
   }
 }
+
+void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) {
+#if !defined(USE_ARM_EABI)
+  UNREACHABLE();
+#else
+  vmov(dst, r0, r1);
+#endif
+}


 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon Feb 21 03:29:45 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Feb 23 02:41:13 2011
@@ -684,6 +684,8 @@
   void CallCFunction(ExternalReference function, int num_arguments);
   void CallCFunction(Register function, int num_arguments);

+  void GetCFunctionDoubleResult(const DoubleRegister dst);
+
   // Calls an API function. Allocates HandleScope, extracts returned value
   // from handle and propagates exceptions. Restores context.
   // stack_space - space to be unwound on exit (includes the call js
=======================================
--- /branches/bleeding_edge/src/assembler.cc    Tue Feb 22 04:28:33 2011
+++ /branches/bleeding_edge/src/assembler.cc    Wed Feb 23 02:41:13 2011
@@ -852,12 +852,14 @@


 ExternalReference ExternalReference::power_double_double_function() {
-  return ExternalReference(Redirect(FUNCTION_ADDR(power_double_double)));
+  return ExternalReference(Redirect(FUNCTION_ADDR(power_double_double),
+                                    FP_RETURN_CALL));
 }


 ExternalReference ExternalReference::power_double_int_function() {
-  return ExternalReference(Redirect(FUNCTION_ADDR(power_double_int)));
+  return ExternalReference(Redirect(FUNCTION_ADDR(power_double_int),
+                                    FP_RETURN_CALL));
 }


=======================================
--- /branches/bleeding_edge/src/v8.cc   Fri Feb 11 04:25:41 2011
+++ /branches/bleeding_edge/src/v8.cc   Wed Feb 23 02:41:13 2011
@@ -54,7 +54,12 @@
   if (has_been_disposed_ || has_fatal_error_) return false;
   if (IsRunning()) return true;

+#if defined(V8_TARGET_ARCH_ARM) && !defined(USE_ARM_EABI)
+  use_crankshaft_ = false;
+#else
   use_crankshaft_ = FLAG_crankshaft;
+#endif
+
   // Peephole optimization might interfere with deoptimization.
   FLAG_peephole_optimization = !use_crankshaft_;
   is_running_ = true;

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

Reply via email to