xref: /linux-6.15/lib/test_fpu_impl.c (revision 9613736d)
1*9613736dSSamuel Holland // SPDX-License-Identifier: GPL-2.0+
2*9613736dSSamuel Holland 
3*9613736dSSamuel Holland #include <linux/errno.h>
4*9613736dSSamuel Holland 
5*9613736dSSamuel Holland #include "test_fpu.h"
6*9613736dSSamuel Holland 
test_fpu(void)7*9613736dSSamuel Holland int test_fpu(void)
8*9613736dSSamuel Holland {
9*9613736dSSamuel Holland 	/*
10*9613736dSSamuel Holland 	 * This sequence of operations tests that rounding mode is
11*9613736dSSamuel Holland 	 * to nearest and that denormal numbers are supported.
12*9613736dSSamuel Holland 	 * Volatile variables are used to avoid compiler optimizing
13*9613736dSSamuel Holland 	 * the calculations away.
14*9613736dSSamuel Holland 	 */
15*9613736dSSamuel Holland 	volatile double a, b, c, d, e, f, g;
16*9613736dSSamuel Holland 
17*9613736dSSamuel Holland 	a = 4.0;
18*9613736dSSamuel Holland 	b = 1e-15;
19*9613736dSSamuel Holland 	c = 1e-310;
20*9613736dSSamuel Holland 
21*9613736dSSamuel Holland 	/* Sets precision flag */
22*9613736dSSamuel Holland 	d = a + b;
23*9613736dSSamuel Holland 
24*9613736dSSamuel Holland 	/* Result depends on rounding mode */
25*9613736dSSamuel Holland 	e = a + b / 2;
26*9613736dSSamuel Holland 
27*9613736dSSamuel Holland 	/* Denormal and very large values */
28*9613736dSSamuel Holland 	f = b / c;
29*9613736dSSamuel Holland 
30*9613736dSSamuel Holland 	/* Depends on denormal support */
31*9613736dSSamuel Holland 	g = a + c * f;
32*9613736dSSamuel Holland 
33*9613736dSSamuel Holland 	if (d > a && e > a && g > a)
34*9613736dSSamuel Holland 		return 0;
35*9613736dSSamuel Holland 	else
36*9613736dSSamuel Holland 		return -EINVAL;
37*9613736dSSamuel Holland }
38