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