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