MIPS: Implement sqrt in inline assembly.
authorplind44@gmail.com <plind44@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 9 Jan 2014 19:00:06 +0000 (19:00 +0000)
committerplind44@gmail.com <plind44@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 9 Jan 2014 19:00:06 +0000 (19:00 +0000)
Port r18506 (c7b2885)

Original commit message:
Call VSQRT directly to avoid the tiniest (1ulp) precision
error that occurs in the system-supplied sqrt on QNX/ARM.

All precision tests in SunSpider are now passing on this platform.

BUG=
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/131263003

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

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

src/mips/codegen-mips.cc
src/mips/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h

index 7a207120a23d020c958855588ac084532d3b7bee..d07a6bbd21c0ef506fe1c9d5e1fbe6a729285aae 100644 (file)
@@ -525,13 +525,33 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
 }
 #endif
 
-#undef __
+UnaryMathFunction CreateSqrtFunction() {
+#if defined(USE_SIMULATOR)
+  return &std::sqrt;
+#else
+  size_t actual_size;
+  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
+  if (buffer == NULL) return &std::sqrt;
 
+  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
 
-UnaryMathFunction CreateSqrtFunction() {
-  return &sqrt;
+  __ GetFromCDoubleArguments(f12);
+  __ sqrt_d(f0, f12);
+  __ SetForCDoubleResult(f0);
+  __ Ret();
+
+  CodeDesc desc;
+  masm.GetCode(&desc);
+  ASSERT(!RelocInfo::RequiresRelocation(desc));
+
+  CPU::FlushICache(buffer, actual_size);
+  OS::ProtectCode(buffer, actual_size);
+  return FUNCTION_CAST<UnaryMathFunction>(buffer);
+#endif
 }
 
+#undef __
+
 
 // -------------------------------------------------------------------------
 // Platform-specific RuntimeCallHelper functions.
index d67e58e660e8679a320957f9efdc522310632de4..116cb05655305f933a825a140a9ff76fa952fbdd 100644 (file)
@@ -3526,6 +3526,15 @@ void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) {
 }
 
 
+void MacroAssembler::GetFromCDoubleArguments(const DoubleRegister dst) {
+  if (IsMipsSoftFloatABI) {
+    Move(dst, a0, a1);
+  } else {
+    Move(dst, f12);  // Reg f12 is o32 ABI FP first argument value.
+  }
+}
+
+
 void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) {
   if (!IsMipsSoftFloatABI) {
     Move(f12, dreg);
@@ -3535,6 +3544,15 @@ void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) {
 }
 
 
+void MacroAssembler::SetForCDoubleResult(DoubleRegister dreg) {
+  if (!IsMipsSoftFloatABI) {
+    Move(f0, dreg);
+  } else {
+    Move(v0, v1, dreg);
+  }
+}
+
+
 void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1,
                                              DoubleRegister dreg2) {
   if (!IsMipsSoftFloatABI) {
index 4a7d9adf10eb37bf195de2840aa1488a70a3f198..c3f265faa2f514425ad615f13423dc0a6efbe1ba 100644 (file)
@@ -1278,6 +1278,7 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
                      int num_reg_arguments,
                      int num_double_arguments);
   void GetCFunctionDoubleResult(const DoubleRegister dst);
+  void GetFromCDoubleArguments(const DoubleRegister dst);
 
   // There are two ways of passing double arguments on MIPS, depending on
   // whether soft or hard floating point ABI is used. These functions
@@ -1286,6 +1287,7 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
   void SetCallCDoubleArguments(DoubleRegister dreg);
   void SetCallCDoubleArguments(DoubleRegister dreg1, DoubleRegister dreg2);
   void SetCallCDoubleArguments(DoubleRegister dreg, Register reg);
+  void SetForCDoubleResult(DoubleRegister dreg);
 
   // Calls an API function.  Allocates HandleScope, extracts returned value
   // from handle and propagates exceptions.  Restores context.  stack_space