Bug 1515704 - ARM64: Generate code for LPowHalfD. r=sstangl
authorNicolas B. Pierron <nicolas.b.pierron@nbp.name>
Thu, 20 Dec 2018 18:53:41 +0100
changeset 452009 89834b056ca0e1969845185d0d007a695b03c503
parent 452008 21ce5e3998e3b7716ef95b44bea56c8c44ab72a5
child 452010 3487b5f2f426760ebc402e42755dcb164644f022
push id35278
push useraiakab@mozilla.com
push dateThu, 27 Dec 2018 21:57:04 +0000
treeherdermozilla-central@a77e8f3efc4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssstangl
bugs1515704
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515704 - ARM64: Generate code for LPowHalfD. r=sstangl
js/src/jit/arm64/Assembler-arm64.h
js/src/jit/arm64/CodeGenerator-arm64.cpp
js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
--- a/js/src/jit/arm64/Assembler-arm64.h
+++ b/js/src/jit/arm64/Assembler-arm64.h
@@ -32,25 +32,33 @@ static const Scale ScalePointer = TimesE
 // For safety, scratch registers should always be acquired using
 // vixl::UseScratchRegisterScope.
 static constexpr Register ScratchReg{Registers::ip0};
 static constexpr ARMRegister ScratchReg64 = {ScratchReg, 64};
 
 static constexpr Register ScratchReg2{Registers::ip1};
 static constexpr ARMRegister ScratchReg2_64 = {ScratchReg2, 64};
 
+static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::d0,
+                                                  FloatRegisters::Double};
 static constexpr FloatRegister ScratchDoubleReg = {FloatRegisters::d31,
                                                    FloatRegisters::Double};
-static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::d0,
-                                                  FloatRegisters::Double};
+struct ScratchDoubleScope : public AutoFloatRegisterScope {
+  explicit ScratchDoubleScope(MacroAssembler& masm)
+    : AutoFloatRegisterScope(masm, ScratchDoubleReg) {}
+};
 
 static constexpr FloatRegister ReturnFloat32Reg = {FloatRegisters::s0,
                                                    FloatRegisters::Single};
 static constexpr FloatRegister ScratchFloat32Reg = {FloatRegisters::s31,
                                                     FloatRegisters::Single};
+struct ScratchFloat32Scope : public AutoFloatRegisterScope {
+  explicit ScratchFloat32Scope(MacroAssembler& masm)
+    : AutoFloatRegisterScope(masm, ScratchFloat32Reg) {}
+};
 
 static constexpr Register InvalidReg{Registers::invalid_reg};
 static constexpr FloatRegister InvalidFloatReg = {FloatRegisters::invalid_fpreg,
                                                   FloatRegisters::Single};
 
 static constexpr Register OsrFrameReg{Registers::x3};
 static constexpr Register CallTempReg0{Registers::x9};
 static constexpr Register CallTempReg1{Registers::x10};
--- a/js/src/jit/arm64/CodeGenerator-arm64.cpp
+++ b/js/src/jit/arm64/CodeGenerator-arm64.cpp
@@ -739,17 +739,52 @@ void CodeGenerator::visitUrshD(LUrshD* i
   } else {
     masm.And(temp32, toWRegister(rhs), Operand(0x1F));
     masm.Lsr(temp32, lhs, temp32);
     masm.convertUInt32ToDouble(temp, out);
   }
 }
 
 void CodeGenerator::visitPowHalfD(LPowHalfD* ins) {
-  MOZ_CRASH("visitPowHalfD");
+  FloatRegister input = ToFloatRegister(ins->input());
+  FloatRegister output = ToFloatRegister(ins->output());
+
+  ScratchDoubleScope scratch(masm);
+
+  Label done, sqrt;
+
+  if (!ins->mir()->operandIsNeverNegativeInfinity()) {
+    // Branch if not -Infinity.
+    masm.loadConstantDouble(NegativeInfinity<double>(), scratch);
+
+    Assembler::DoubleCondition cond = Assembler::DoubleNotEqualOrUnordered;
+    if (ins->mir()->operandIsNeverNaN()) {
+      cond = Assembler::DoubleNotEqual;
+    }
+    masm.branchDouble(cond, input, scratch, &sqrt);
+
+    // Math.pow(-Infinity, 0.5) == Infinity.
+    masm.zeroDouble(output);
+    masm.subDouble(scratch, output);
+    masm.jump(&done);
+
+    masm.bind(&sqrt);
+  }
+
+  if (!ins->mir()->operandIsNeverNegativeZero()) {
+    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5).
+    // Adding 0 converts any -0 to 0.
+    masm.zeroDouble(scratch);
+    masm.addDouble(input, scratch);
+    masm.sqrtDouble(scratch, output);
+  } else {
+    masm.sqrtDouble(input, output);
+  }
+
+  masm.bind(&done);
 }
 
 MoveOperand CodeGeneratorARM64::toMoveOperand(const LAllocation a) const {
   if (a.isGeneralReg()) {
     return MoveOperand(ToRegister(a));
   }
   if (a.isFloatReg()) {
     return MoveOperand(ToFloatRegister(a));
--- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -750,18 +750,18 @@ void CodeGenerator::visitPowHalfD(LPowHa
     masm.zeroDouble(output);
     masm.subDouble(scratch, output);
     masm.jump(&done);
 
     masm.bind(&sqrt);
   }
 
   if (!ins->mir()->operandIsNeverNegativeZero()) {
-    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5). Adding 0 converts any -0 to
-    // 0.
+    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5).
+    // Adding 0 converts any -0 to 0.
     masm.zeroDouble(scratch);
     masm.addDouble(input, scratch);
     masm.vsqrtsd(scratch, output, output);
   } else {
     masm.vsqrtsd(input, output, output);
   }
 
   masm.bind(&done);