xref: /aosp_15_r20/external/musl/src/math/i386/sqrt.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include "libm.h"
2*c9945492SAndroid Build Coastguard Worker 
sqrt(double x)3*c9945492SAndroid Build Coastguard Worker double sqrt(double x)
4*c9945492SAndroid Build Coastguard Worker {
5*c9945492SAndroid Build Coastguard Worker 	union ldshape ux;
6*c9945492SAndroid Build Coastguard Worker 	unsigned fpsr;
7*c9945492SAndroid Build Coastguard Worker 	__asm__ ("fsqrt; fnstsw %%ax": "=t"(ux.f), "=a"(fpsr) : "0"(x));
8*c9945492SAndroid Build Coastguard Worker 	if ((ux.i.m & 0x7ff) != 0x400)
9*c9945492SAndroid Build Coastguard Worker 		return (double)ux.f;
10*c9945492SAndroid Build Coastguard Worker 	/* Rounding to double would have encountered an exact halfway case.
11*c9945492SAndroid Build Coastguard Worker 	   Adjust mantissa downwards if fsqrt rounded up, else upwards.
12*c9945492SAndroid Build Coastguard Worker 	   (result of fsqrt could not have been exact) */
13*c9945492SAndroid Build Coastguard Worker 	ux.i.m ^= (fpsr & 0x200) + 0x300;
14*c9945492SAndroid Build Coastguard Worker 	return (double)ux.f;
15*c9945492SAndroid Build Coastguard Worker }
16