root/tools/testing/selftests/x86/test_FISTTP.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test
  2. sighandler
  3. main

   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 
  17 unsigned long long res64 = -1;
  18 unsigned int res32 = -1;
  19 unsigned short res16 = -1;
  20 
  21 int 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 
 112 void sighandler(int sig)
 113 {
 114         printf("[FAIL]\tGot signal %d, exiting\n", sig);
 115         exit(1);
 116 }
 117 
 118 int 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 }

/* [<][>][^][v][top][bottom][index][help] */