linux/tools/testing/selftests/x86/test_FISTTP.c
<<
>>
Prefs
   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
  16unsigned long long res64 = -1;
  17unsigned int res32 = -1;
  18unsigned short res16 = -1;
  19
  20int 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
 111void sighandler(int sig)
 112{
 113        printf("[FAIL]\tGot signal %d, exiting\n", sig);
 114        exit(1);
 115}
 116
 117int 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