1*a58e2ecdSDenys Vlasenko #undef _GNU_SOURCE 2*a58e2ecdSDenys Vlasenko #define _GNU_SOURCE 1 3*a58e2ecdSDenys Vlasenko #undef __USE_GNU 4*a58e2ecdSDenys Vlasenko #define __USE_GNU 1 5*a58e2ecdSDenys Vlasenko #include <unistd.h> 6*a58e2ecdSDenys Vlasenko #include <stdlib.h> 7*a58e2ecdSDenys Vlasenko #include <string.h> 8*a58e2ecdSDenys Vlasenko #include <stdio.h> 9*a58e2ecdSDenys Vlasenko #include <signal.h> 10*a58e2ecdSDenys Vlasenko #include <sys/types.h> 11*a58e2ecdSDenys Vlasenko #include <sys/select.h> 12*a58e2ecdSDenys Vlasenko #include <sys/time.h> 13*a58e2ecdSDenys Vlasenko #include <sys/wait.h> 14*a58e2ecdSDenys Vlasenko #include <fenv.h> 15*a58e2ecdSDenys Vlasenko 16*a58e2ecdSDenys Vlasenko unsigned long long res64 = -1; 17*a58e2ecdSDenys Vlasenko unsigned int res32 = -1; 18*a58e2ecdSDenys Vlasenko unsigned short res16 = -1; 19*a58e2ecdSDenys Vlasenko 20*a58e2ecdSDenys Vlasenko int test(void) 21*a58e2ecdSDenys Vlasenko { 22*a58e2ecdSDenys Vlasenko int ex; 23*a58e2ecdSDenys Vlasenko 24*a58e2ecdSDenys Vlasenko feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 25*a58e2ecdSDenys Vlasenko asm volatile ("\n" 26*a58e2ecdSDenys Vlasenko " fld1""\n" 27*a58e2ecdSDenys Vlasenko " fisttp res16""\n" 28*a58e2ecdSDenys Vlasenko " fld1""\n" 29*a58e2ecdSDenys Vlasenko " fisttpl res32""\n" 30*a58e2ecdSDenys Vlasenko " fld1""\n" 31*a58e2ecdSDenys Vlasenko " fisttpll res64""\n" 32*a58e2ecdSDenys Vlasenko : : : "memory" 33*a58e2ecdSDenys Vlasenko ); 34*a58e2ecdSDenys Vlasenko if (res16 != 1 || res32 != 1 || res64 != 1) { 35*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp 1\n"); 36*a58e2ecdSDenys Vlasenko return 1; 37*a58e2ecdSDenys Vlasenko } 38*a58e2ecdSDenys Vlasenko ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 39*a58e2ecdSDenys Vlasenko if (ex != 0) { 40*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp 1: wrong exception state\n"); 41*a58e2ecdSDenys Vlasenko return 1; 42*a58e2ecdSDenys Vlasenko } 43*a58e2ecdSDenys Vlasenko 44*a58e2ecdSDenys Vlasenko feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 45*a58e2ecdSDenys Vlasenko asm volatile ("\n" 46*a58e2ecdSDenys Vlasenko " fldpi""\n" 47*a58e2ecdSDenys Vlasenko " fisttp res16""\n" 48*a58e2ecdSDenys Vlasenko " fldpi""\n" 49*a58e2ecdSDenys Vlasenko " fisttpl res32""\n" 50*a58e2ecdSDenys Vlasenko " fldpi""\n" 51*a58e2ecdSDenys Vlasenko " fisttpll res64""\n" 52*a58e2ecdSDenys Vlasenko : : : "memory" 53*a58e2ecdSDenys Vlasenko ); 54*a58e2ecdSDenys Vlasenko if (res16 != 3 || res32 != 3 || res64 != 3) { 55*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp pi\n"); 56*a58e2ecdSDenys Vlasenko return 1; 57*a58e2ecdSDenys Vlasenko } 58*a58e2ecdSDenys Vlasenko ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 59*a58e2ecdSDenys Vlasenko if (ex != FE_INEXACT) { 60*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp pi: wrong exception state\n"); 61*a58e2ecdSDenys Vlasenko return 1; 62*a58e2ecdSDenys Vlasenko } 63*a58e2ecdSDenys Vlasenko 64*a58e2ecdSDenys Vlasenko feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 65*a58e2ecdSDenys Vlasenko asm volatile ("\n" 66*a58e2ecdSDenys Vlasenko " fldpi""\n" 67*a58e2ecdSDenys Vlasenko " fchs""\n" 68*a58e2ecdSDenys Vlasenko " fisttp res16""\n" 69*a58e2ecdSDenys Vlasenko " fldpi""\n" 70*a58e2ecdSDenys Vlasenko " fchs""\n" 71*a58e2ecdSDenys Vlasenko " fisttpl res32""\n" 72*a58e2ecdSDenys Vlasenko " fldpi""\n" 73*a58e2ecdSDenys Vlasenko " fchs""\n" 74*a58e2ecdSDenys Vlasenko " fisttpll res64""\n" 75*a58e2ecdSDenys Vlasenko : : : "memory" 76*a58e2ecdSDenys Vlasenko ); 77*a58e2ecdSDenys Vlasenko if (res16 != 0xfffd || res32 != 0xfffffffd || res64 != 0xfffffffffffffffdULL) { 78*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp -pi\n"); 79*a58e2ecdSDenys Vlasenko return 1; 80*a58e2ecdSDenys Vlasenko } 81*a58e2ecdSDenys Vlasenko ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 82*a58e2ecdSDenys Vlasenko if (ex != FE_INEXACT) { 83*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp -pi: wrong exception state\n"); 84*a58e2ecdSDenys Vlasenko return 1; 85*a58e2ecdSDenys Vlasenko } 86*a58e2ecdSDenys Vlasenko 87*a58e2ecdSDenys Vlasenko feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 88*a58e2ecdSDenys Vlasenko asm volatile ("\n" 89*a58e2ecdSDenys Vlasenko " fldln2""\n" 90*a58e2ecdSDenys Vlasenko " fisttp res16""\n" 91*a58e2ecdSDenys Vlasenko " fldln2""\n" 92*a58e2ecdSDenys Vlasenko " fisttpl res32""\n" 93*a58e2ecdSDenys Vlasenko " fldln2""\n" 94*a58e2ecdSDenys Vlasenko " fisttpll res64""\n" 95*a58e2ecdSDenys Vlasenko : : : "memory" 96*a58e2ecdSDenys Vlasenko ); 97*a58e2ecdSDenys Vlasenko /* Test truncation to zero (round-to-nearest would give 1 here) */ 98*a58e2ecdSDenys Vlasenko if (res16 != 0 || res32 != 0 || res64 != 0) { 99*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp ln2\n"); 100*a58e2ecdSDenys Vlasenko return 1; 101*a58e2ecdSDenys Vlasenko } 102*a58e2ecdSDenys Vlasenko ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 103*a58e2ecdSDenys Vlasenko if (ex != FE_INEXACT) { 104*a58e2ecdSDenys Vlasenko printf("[BAD]\tfisttp ln2: wrong exception state\n"); 105*a58e2ecdSDenys Vlasenko return 1; 106*a58e2ecdSDenys Vlasenko } 107*a58e2ecdSDenys Vlasenko 108*a58e2ecdSDenys Vlasenko return 0; 109*a58e2ecdSDenys Vlasenko } 110*a58e2ecdSDenys Vlasenko 111*a58e2ecdSDenys Vlasenko void sighandler(int sig) 112*a58e2ecdSDenys Vlasenko { 113*a58e2ecdSDenys Vlasenko printf("[FAIL]\tGot signal %d, exiting\n", sig); 114*a58e2ecdSDenys Vlasenko exit(1); 115*a58e2ecdSDenys Vlasenko } 116*a58e2ecdSDenys Vlasenko 117*a58e2ecdSDenys Vlasenko int main(int argc, char **argv, char **envp) 118*a58e2ecdSDenys Vlasenko { 119*a58e2ecdSDenys Vlasenko int err = 0; 120*a58e2ecdSDenys Vlasenko 121*a58e2ecdSDenys Vlasenko /* SIGILL triggers on 32-bit kernels w/o fisttp emulation 122*a58e2ecdSDenys Vlasenko * when run with "no387 nofxsr". Other signals are caught 123*a58e2ecdSDenys Vlasenko * just in case. 124*a58e2ecdSDenys Vlasenko */ 125*a58e2ecdSDenys Vlasenko signal(SIGILL, sighandler); 126*a58e2ecdSDenys Vlasenko signal(SIGFPE, sighandler); 127*a58e2ecdSDenys Vlasenko signal(SIGSEGV, sighandler); 128*a58e2ecdSDenys Vlasenko 129*a58e2ecdSDenys Vlasenko printf("[RUN]\tTesting fisttp instructions\n"); 130*a58e2ecdSDenys Vlasenko err |= test(); 131*a58e2ecdSDenys Vlasenko if (!err) 132*a58e2ecdSDenys Vlasenko printf("[OK]\tfisttp\n"); 133*a58e2ecdSDenys Vlasenko else 134*a58e2ecdSDenys Vlasenko printf("[FAIL]\tfisttp errors: %d\n", err); 135*a58e2ecdSDenys Vlasenko 136*a58e2ecdSDenys Vlasenko return err; 137*a58e2ecdSDenys Vlasenko } 138