1 /* $OpenBSD: e_sqrt.c,v 1.1 2009/04/05 19:26:27 martynas Exp $ */ 2 3 /* 4 * Written by Martynas Venckus. Public domain 5 */ 6 7 #include <sys/types.h> 8 #include <sys/cdefs.h> 9 #include <math.h> 10 11 #define FPSCR_PR (1 << 19) 12 #define FPSCR_SZ (1 << 20) 13 14 double 15 sqrt(double d) 16 { 17 register_t fpscr, nfpscr; 18 19 __asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr)); 20 21 /* Set floating-point mode to double-precision. */ 22 nfpscr = fpscr | FPSCR_PR; 23 24 /* Do not set SZ and PR to 1 simultaneously. */ 25 nfpscr &= ~FPSCR_SZ; 26 27 __asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr)); 28 __asm__ __volatile__ ("fsqrt %0" : "+f" (d)); 29 30 /* Restore fp status/control register. */ 31 __asm__ __volatile__ ("lds %0, fpscr" : : "r" (fpscr)); 32 33 return (d); 34 } 35 36 /* No extended-precision is present. */ 37 __weak_alias(sqrtl,sqrt); 38 39