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