Improve the assembly code for power function with integer exponential.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 17 Sep 2012 07:45:54 +0000 (07:45 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 17 Sep 2012 07:45:54 +0000 (07:45 +0000)
The change removes one unused multiply and reschedules
the shift, multiply and jump instructions to reduce
stall. Experiment shows it improve about 20% performance
on x86 for exponetials from about 100 to 2000.

Review URL: https://chromiumcodereview.appspot.com/10916311

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12521 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ia32/code-stubs-ia32.cc

index d75d5cd..1fdbaf1 100644 (file)
@@ -3213,21 +3213,28 @@ void MathPowStub::Generate(MacroAssembler* masm) {
   __ movsd(double_scratch2, double_result);  // Load double_exponent with 1.
 
   // Get absolute value of exponent.
-  Label no_neg, while_true, no_multiply;
+  Label no_neg, while_true, no_multiply, while_false;
   __ test(scratch, scratch);
   __ j(positive, &no_neg, Label::kNear);
   __ neg(scratch);
   __ bind(&no_neg);
 
-  __ bind(&while_true);
+  __ j(zero, &while_false, Label::kNear);
   __ shr(scratch, 1);
-  __ j(not_carry, &no_multiply, Label::kNear);
-  __ mulsd(double_result, double_scratch);
-  __ bind(&no_multiply);
+  // Above condition means CF==0 && ZF==0.  This means that the
+  // bit that has been shifted out is 0 and the result is not 0.
+  __ j(above, &while_true, Label::kNear);
+  __ movsd(double_result, double_scratch);
+  __ j(zero, &while_false, Label::kNear);
 
+  __ bind(&while_true);
+  __ shr(scratch, 1);
   __ mulsd(double_scratch, double_scratch);
+  __ j(above, &while_true, Label::kNear);
+  __ mulsd(double_result, double_scratch);
   __ j(not_zero, &while_true);
 
+  __ bind(&while_false);
   // scratch has the original value of the exponent - if the exponent is
   // negative, return 1/result.
   __ test(exponent, exponent);