1 /* $OpenBSD: fpu.c,v 1.3 2021/06/17 12:55:38 kettenis Exp $ */ 2 3 #include <err.h> 4 #include <fenv.h> 5 #include <stdlib.h> 6 7 int 8 main(int argc, char *argv[]) 9 { 10 fexcept_t flag; 11 int rv; 12 13 /* Set up the FPU control word register. */ 14 rv = fesetround(FE_UPWARD); 15 if (rv != 0) 16 errx(2, "fesetround FE_UPWARD returned %d", rv); 17 fedisableexcept(FE_ALL_EXCEPT); 18 feenableexcept(FE_DIVBYZERO); 19 20 /* Set the FPU exception flags. */ 21 flag = FE_OVERFLOW; 22 rv = fesetexceptflag(&flag, FE_ALL_EXCEPT); 23 if (rv != 0) 24 errx(2, "fesetexceptflag returned %d", rv); 25 26 /* Schedule another process, to check if kernel preserves state. */ 27 rv = system("true"); 28 if (rv == -1) 29 err(2, "system"); 30 if (rv != 0) 31 errx(2, "true: %d", rv); 32 33 /* Verify that the FPU control word is preserved. */ 34 rv = fegetround(); 35 if (rv != FE_UPWARD) 36 errx(1, "fegetround returned %d, not FE_UPWARD", rv); 37 #if !defined(__arm__) && !defined(__aarch64__) && !defined(__riscv) 38 rv = fegetexcept(); 39 if (rv != FE_DIVBYZERO) 40 errx(1, "fegetexcept returned %d, not FE_DIVBYZERO", 41 rv); 42 #endif 43 44 /* Verify that the FPU exception flags weren't clobbered. */ 45 flag = 0; 46 rv = fegetexceptflag(&flag, FE_ALL_EXCEPT); 47 if (rv != 0) 48 errx(2, "fegetexceptflag returned %d", rv); 49 if (flag != FE_OVERFLOW) 50 errx(1, "except flag is %d, no FE_OVERFLOW", rv); 51 52 return (0); 53 } 54