summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64/code-stubs-x64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/x64/code-stubs-x64.cc')
-rw-r--r--deps/v8/src/x64/code-stubs-x64.cc114
1 files changed, 51 insertions, 63 deletions
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc
index 2ff00f0402..fc98006f78 100644
--- a/deps/v8/src/x64/code-stubs-x64.cc
+++ b/deps/v8/src/x64/code-stubs-x64.cc
@@ -122,69 +122,57 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movp(scratch, Immediate(1));
__ Cvtlsi2sd(double_result, scratch);
- if (exponent_type() == TAGGED) {
- __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
- __ SmiToInteger32(exponent, exponent);
- __ jmp(&int_exponent);
-
- __ bind(&exponent_not_smi);
- __ Movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
- }
-
- if (exponent_type() != INTEGER) {
- Label fast_power, try_arithmetic_simplification;
- // Detect integer exponents stored as double.
- __ DoubleToI(exponent, double_exponent, double_scratch,
- &try_arithmetic_simplification,
- &try_arithmetic_simplification);
- __ jmp(&int_exponent);
-
- __ bind(&try_arithmetic_simplification);
- __ Cvttsd2si(exponent, double_exponent);
- // Skip to runtime if possibly NaN (indicated by the indefinite integer).
- __ cmpl(exponent, Immediate(0x1));
- __ j(overflow, &call_runtime);
-
- // Using FPU instructions to calculate power.
- Label fast_power_failed;
- __ bind(&fast_power);
- __ fnclex(); // Clear flags to catch exceptions later.
- // Transfer (B)ase and (E)xponent onto the FPU register stack.
- __ subp(rsp, Immediate(kDoubleSize));
- __ Movsd(Operand(rsp, 0), double_exponent);
- __ fld_d(Operand(rsp, 0)); // E
- __ Movsd(Operand(rsp, 0), double_base);
- __ fld_d(Operand(rsp, 0)); // B, E
-
- // Exponent is in st(1) and base is in st(0)
- // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B)
- // FYL2X calculates st(1) * log2(st(0))
- __ fyl2x(); // X
- __ fld(0); // X, X
- __ frndint(); // rnd(X), X
- __ fsub(1); // rnd(X), X-rnd(X)
- __ fxch(1); // X - rnd(X), rnd(X)
- // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1
- __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X)
- __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X)
- __ faddp(1); // 2^(X-rnd(X)), rnd(X)
- // FSCALE calculates st(0) * 2^st(1)
- __ fscale(); // 2^X, rnd(X)
- __ fstp(1);
- // Bail out to runtime in case of exceptions in the status word.
- __ fnstsw_ax();
- __ testb(rax, Immediate(0x5F)); // Check for all but precision exception.
- __ j(not_zero, &fast_power_failed, Label::kNear);
- __ fstp_d(Operand(rsp, 0));
- __ Movsd(double_result, Operand(rsp, 0));
- __ addp(rsp, Immediate(kDoubleSize));
- __ jmp(&done);
-
- __ bind(&fast_power_failed);
- __ fninit();
- __ addp(rsp, Immediate(kDoubleSize));
- __ jmp(&call_runtime);
- }
+ Label fast_power, try_arithmetic_simplification;
+ // Detect integer exponents stored as double.
+ __ DoubleToI(exponent, double_exponent, double_scratch,
+ &try_arithmetic_simplification, &try_arithmetic_simplification);
+ __ jmp(&int_exponent);
+
+ __ bind(&try_arithmetic_simplification);
+ __ Cvttsd2si(exponent, double_exponent);
+ // Skip to runtime if possibly NaN (indicated by the indefinite integer).
+ __ cmpl(exponent, Immediate(0x1));
+ __ j(overflow, &call_runtime);
+
+ // Using FPU instructions to calculate power.
+ Label fast_power_failed;
+ __ bind(&fast_power);
+ __ fnclex(); // Clear flags to catch exceptions later.
+ // Transfer (B)ase and (E)xponent onto the FPU register stack.
+ __ subp(rsp, Immediate(kDoubleSize));
+ __ Movsd(Operand(rsp, 0), double_exponent);
+ __ fld_d(Operand(rsp, 0)); // E
+ __ Movsd(Operand(rsp, 0), double_base);
+ __ fld_d(Operand(rsp, 0)); // B, E
+
+ // Exponent is in st(1) and base is in st(0)
+ // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B)
+ // FYL2X calculates st(1) * log2(st(0))
+ __ fyl2x(); // X
+ __ fld(0); // X, X
+ __ frndint(); // rnd(X), X
+ __ fsub(1); // rnd(X), X-rnd(X)
+ __ fxch(1); // X - rnd(X), rnd(X)
+ // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1
+ __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X)
+ __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X)
+ __ faddp(1); // 2^(X-rnd(X)), rnd(X)
+ // FSCALE calculates st(0) * 2^st(1)
+ __ fscale(); // 2^X, rnd(X)
+ __ fstp(1);
+ // Bail out to runtime in case of exceptions in the status word.
+ __ fnstsw_ax();
+ __ testb(rax, Immediate(0x5F)); // Check for all but precision exception.
+ __ j(not_zero, &fast_power_failed, Label::kNear);
+ __ fstp_d(Operand(rsp, 0));
+ __ Movsd(double_result, Operand(rsp, 0));
+ __ addp(rsp, Immediate(kDoubleSize));
+ __ jmp(&done);
+
+ __ bind(&fast_power_failed);
+ __ fninit();
+ __ addp(rsp, Immediate(kDoubleSize));
+ __ jmp(&call_runtime);
// Calculate power with integer exponent.
__ bind(&int_exponent);