Reviewers: ulan,

Message:
further breakdown from issue 23156006

Description:
ARM: Tweak Math.exp.

Avoid corrupting the input and small assembly tuning.

BUG=none
TEST=test/mjsunit/lithium/MathExp.js

Please review this at https://codereview.chromium.org/24278004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+42, -27 lines):
  M src/arm/codegen-arm.h
  M src/arm/codegen-arm.cc
  M src/arm/lithium-arm.cc
  A + test/mjsunit/lithium/MathExp.js


Index: src/arm/codegen-arm.cc
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 5b80d6facc5ea8e4a0b2fb6fcf985a83bdbc1cba..57e227d86949e5085bef9bc9fbc8e7b1aa123990 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -775,50 +775,63 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
   ASSERT(!temp2.is(temp3));
   ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);

-  Label done;
+  Label zero, infinity, done;

   __ mov(temp3, Operand(ExternalReference::math_exp_constants(0)));

   __ vldr(double_scratch1, ExpConstant(0, temp3));
-  __ vmov(result, kDoubleRegZero);
   __ VFPCompareAndSetFlags(double_scratch1, input);
-  __ b(ge, &done);
+  __ b(ge, &zero);
+
   __ vldr(double_scratch2, ExpConstant(1, temp3));
   __ VFPCompareAndSetFlags(input, double_scratch2);
-  __ vldr(result, ExpConstant(2, temp3));
-  __ b(ge, &done);
+  __ b(ge, &infinity);
+
   __ vldr(double_scratch1, ExpConstant(3, temp3));
   __ vldr(result, ExpConstant(4, temp3));
   __ vmul(double_scratch1, double_scratch1, input);
   __ vadd(double_scratch1, double_scratch1, result);
-  __ vmov(temp2, temp1, double_scratch1);
+  __ VmovLow(temp2, double_scratch1);
   __ vsub(double_scratch1, double_scratch1, result);
   __ vldr(result, ExpConstant(6, temp3));
   __ vldr(double_scratch2, ExpConstant(5, temp3));
   __ vmul(double_scratch1, double_scratch1, double_scratch2);
   __ vsub(double_scratch1, double_scratch1, input);
   __ vsub(result, result, double_scratch1);
-  __ vmul(input, double_scratch1, double_scratch1);
-  __ vmul(result, result, input);
-  __ mov(temp1, Operand(temp2, LSR, 11));
+  __ vmul(double_scratch2, double_scratch1, double_scratch1);
+  __ vmul(result, result, double_scratch2);
   __ vldr(double_scratch2, ExpConstant(7, temp3));
   __ vmul(result, result, double_scratch2);
   __ vsub(result, result, double_scratch1);
-  __ vldr(double_scratch2, ExpConstant(8, temp3));
+  // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1.
+  __ vmov(double_scratch2, 1);
   __ vadd(result, result, double_scratch2);
-  __ movw(ip, 0x7ff);
-  __ and_(temp2, temp2, Operand(ip));
+  __ mov(temp1, Operand(temp2, LSR, 11));
+  __ Ubfx(temp2, temp2, 0, 11);
   __ add(temp1, temp1, Operand(0x3ff));
-  __ mov(temp1, Operand(temp1, LSL, 20));

   // Must not call ExpConstant() after overwriting temp3!
   __ mov(temp3, Operand(ExternalReference::math_exp_log_table()));
-  __ ldr(ip, MemOperand(temp3, temp2, LSL, 3));
-  __ add(temp3, temp3, Operand(kPointerSize));
-  __ ldr(temp2, MemOperand(temp3, temp2, LSL, 3));
-  __ orr(temp1, temp1, temp2);
-  __ vmov(input, ip, temp1);
-  __ vmul(result, result, input);
+  __ add(temp3, temp3, Operand(temp2, LSL, 3));
+  __ ldm(ia, temp3, temp2.bit() | temp3.bit());
+  // The first word is loaded is the lower number register.
+  if (temp2.code() < temp3.code()) {
+    __ orr(temp1, temp3, Operand(temp1, LSL, 20));
+    __ vmov(double_scratch1, temp2, temp1);
+  } else {
+    __ orr(temp1, temp2, Operand(temp1, LSL, 20));
+    __ vmov(double_scratch1, temp3, temp1);
+  }
+  __ vmul(result, result, double_scratch1);
+  __ b(&done);
+
+  __ bind(&zero);
+  __ vmov(result, kDoubleRegZero);
+  __ b(&done);
+
+  __ bind(&infinity);
+  __ vldr(result, ExpConstant(2, temp3));
+
   __ bind(&done);
 }

Index: src/arm/codegen-arm.h
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 54530d87262df1577603039e1840e5f501c0bbd7..ecbe64cbad304d8f7eb5d875f99ea3e7e5ad7a61 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -97,6 +97,7 @@ class StringCharLoadGenerator : public AllStatic {

 class MathExpGenerator : public AllStatic {
  public:
+  // Register input isn't modified. All other registers are clobbered.
   static void EmitMathExp(MacroAssembler* masm,
                           DwVfpRegister input,
                           DwVfpRegister result,
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index f216a8e094d409bc80c5b492bd27744ab08d94f9..6fdbbb58934c0e852df086b589f55edab6f85905 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1240,7 +1240,7 @@ LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) {
 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->value()->representation().IsDouble());
-  LOperand* input = UseTempRegister(instr->value());
+  LOperand* input = UseRegister(instr->value());
   LOperand* temp1 = TempRegister();
   LOperand* temp2 = TempRegister();
   LOperand* double_temp = FixedTemp(d3);  // Chosen by fair dice roll.
Index: test/mjsunit/lithium/MathExp.js
diff --git a/test/mjsunit/compiler/type-feedback-after-throw.js b/test/mjsunit/lithium/MathExp.js
similarity index 92%
copy from test/mjsunit/compiler/type-feedback-after-throw.js
copy to test/mjsunit/lithium/MathExp.js
index 891e315c5c1121fb1674ee4094890266a7708889..854ff5fd7fd2a7a22bcc3557e4e2bb4c01d9b83f 100644
--- a/test/mjsunit/compiler/type-feedback-after-throw.js
+++ b/test/mjsunit/lithium/MathExp.js
@@ -27,12 +27,13 @@

 // Flags: --allow-natives-syntax

-function foo() {
-  throw "Error";
-  return 1 > 5;
-};
+function foo(x) {
+  return Math.exp(x);
+}

-try { foo() } catch(e) {}
-try { foo() } catch(e) {}
+foo(12.3);
+var r1 = foo(12.3);
 %OptimizeFunctionOnNextCall(foo);
-try { foo() } catch(e) {}
+var r2 = foo(12.3);
+
+assertEquals(r1, r2);


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