| |
| #undef _GNU_SOURCE |
| #define _GNU_SOURCE 1 |
| #undef __USE_GNU |
| #define __USE_GNU 1 |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <signal.h> |
| #include <sys/types.h> |
| #include <sys/select.h> |
| #include <sys/time.h> |
| #include <sys/wait.h> |
| #include <fenv.h> |
| |
| unsigned long long res64 = -1; |
| unsigned int res32 = -1; |
| unsigned short res16 = -1; |
| |
| int test(void) |
| { |
| <------>int ex; |
| |
| <------>feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>asm volatile ("\n" |
| <------>" fld1""\n" |
| <------>" fisttp res16""\n" |
| <------>" fld1""\n" |
| <------>" fisttpl res32""\n" |
| <------>" fld1""\n" |
| <------>" fisttpll res64""\n" |
| <------>: : : "memory" |
| <------>); |
| <------>if (res16 != 1 || res32 != 1 || res64 != 1) { |
| <------><------>printf("[BAD]\tfisttp 1\n"); |
| <------><------>return 1; |
| <------>} |
| <------>ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>if (ex != 0) { |
| <------><------>printf("[BAD]\tfisttp 1: wrong exception state\n"); |
| <------><------>return 1; |
| <------>} |
| |
| <------>feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>asm volatile ("\n" |
| <------>" fldpi""\n" |
| <------>" fisttp res16""\n" |
| <------>" fldpi""\n" |
| <------>" fisttpl res32""\n" |
| <------>" fldpi""\n" |
| <------>" fisttpll res64""\n" |
| <------>: : : "memory" |
| <------>); |
| <------>if (res16 != 3 || res32 != 3 || res64 != 3) { |
| <------><------>printf("[BAD]\tfisttp pi\n"); |
| <------><------>return 1; |
| <------>} |
| <------>ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>if (ex != FE_INEXACT) { |
| <------><------>printf("[BAD]\tfisttp pi: wrong exception state\n"); |
| <------><------>return 1; |
| <------>} |
| |
| <------>feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>asm volatile ("\n" |
| <------>" fldpi""\n" |
| <------>" fchs""\n" |
| <------>" fisttp res16""\n" |
| <------>" fldpi""\n" |
| <------>" fchs""\n" |
| <------>" fisttpl res32""\n" |
| <------>" fldpi""\n" |
| <------>" fchs""\n" |
| <------>" fisttpll res64""\n" |
| <------>: : : "memory" |
| <------>); |
| <------>if (res16 != 0xfffd || res32 != 0xfffffffd || res64 != 0xfffffffffffffffdULL) { |
| <------><------>printf("[BAD]\tfisttp -pi\n"); |
| <------><------>return 1; |
| <------>} |
| <------>ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>if (ex != FE_INEXACT) { |
| <------><------>printf("[BAD]\tfisttp -pi: wrong exception state\n"); |
| <------><------>return 1; |
| <------>} |
| |
| <------>feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>asm volatile ("\n" |
| <------>" fldln2""\n" |
| <------>" fisttp res16""\n" |
| <------>" fldln2""\n" |
| <------>" fisttpl res32""\n" |
| <------>" fldln2""\n" |
| <------>" fisttpll res64""\n" |
| <------>: : : "memory" |
| <------>); |
| <------> |
| <------>if (res16 != 0 || res32 != 0 || res64 != 0) { |
| <------><------>printf("[BAD]\tfisttp ln2\n"); |
| <------><------>return 1; |
| <------>} |
| <------>ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); |
| <------>if (ex != FE_INEXACT) { |
| <------><------>printf("[BAD]\tfisttp ln2: wrong exception state\n"); |
| <------><------>return 1; |
| <------>} |
| |
| <------>return 0; |
| } |
| |
| void sighandler(int sig) |
| { |
| <------>printf("[FAIL]\tGot signal %d, exiting\n", sig); |
| <------>exit(1); |
| } |
| |
| int main(int argc, char **argv, char **envp) |
| { |
| <------>int err = 0; |
| |
| <------> |
| <------> * when run with "no387 nofxsr". Other signals are caught |
| <------> * just in case. |
| <------> */ |
| <------>signal(SIGILL, sighandler); |
| <------>signal(SIGFPE, sighandler); |
| <------>signal(SIGSEGV, sighandler); |
| |
| <------>printf("[RUN]\tTesting fisttp instructions\n"); |
| <------>err |= test(); |
| <------>if (!err) |
| <------><------>printf("[OK]\tfisttp\n"); |
| <------>else |
| <------><------>printf("[FAIL]\tfisttp errors: %d\n", err); |
| |
| <------>return err; |
| } |
| |