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