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