xref: /openbsd/lib/libm/arch/sh/e_sqrt.c (revision 8932bfb7)
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