Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #undef _GNU_SOURCE
0003 #define _GNU_SOURCE 1
0004 #undef __USE_GNU
0005 #define __USE_GNU 1
0006 #include <unistd.h>
0007 #include <stdlib.h>
0008 #include <string.h>
0009 #include <stdio.h>
0010 #include <signal.h>
0011 #include <sys/types.h>
0012 #include <sys/select.h>
0013 #include <sys/time.h>
0014 #include <sys/wait.h>
0015 #include <fenv.h>
0016 
0017 unsigned long long res64 = -1;
0018 unsigned int res32 = -1;
0019 unsigned short res16 = -1;
0020 
0021 int test(void)
0022 {
0023     int ex;
0024 
0025     feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0026     asm volatile ("\n"
0027     "   fld1""\n"
0028     "   fisttp  res16""\n"
0029     "   fld1""\n"
0030     "   fisttpl res32""\n"
0031     "   fld1""\n"
0032     "   fisttpll res64""\n"
0033     : : : "memory"
0034     );
0035     if (res16 != 1 || res32 != 1 || res64 != 1) {
0036         printf("[BAD]\tfisttp 1\n");
0037         return 1;
0038     }
0039     ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0040     if (ex != 0) {
0041         printf("[BAD]\tfisttp 1: wrong exception state\n");
0042         return 1;
0043     }
0044 
0045     feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0046     asm volatile ("\n"
0047     "   fldpi""\n"
0048     "   fisttp  res16""\n"
0049     "   fldpi""\n"
0050     "   fisttpl res32""\n"
0051     "   fldpi""\n"
0052     "   fisttpll res64""\n"
0053     : : : "memory"
0054     );
0055     if (res16 != 3 || res32 != 3 || res64 != 3) {
0056         printf("[BAD]\tfisttp pi\n");
0057         return 1;
0058     }
0059     ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0060     if (ex != FE_INEXACT) {
0061         printf("[BAD]\tfisttp pi: wrong exception state\n");
0062         return 1;
0063     }
0064 
0065     feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0066     asm volatile ("\n"
0067     "   fldpi""\n"
0068     "   fchs""\n"
0069     "   fisttp  res16""\n"
0070     "   fldpi""\n"
0071     "   fchs""\n"
0072     "   fisttpl res32""\n"
0073     "   fldpi""\n"
0074     "   fchs""\n"
0075     "   fisttpll res64""\n"
0076     : : : "memory"
0077     );
0078     if (res16 != 0xfffd || res32 != 0xfffffffd || res64 != 0xfffffffffffffffdULL) {
0079         printf("[BAD]\tfisttp -pi\n");
0080         return 1;
0081     }
0082     ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0083     if (ex != FE_INEXACT) {
0084         printf("[BAD]\tfisttp -pi: wrong exception state\n");
0085         return 1;
0086     }
0087 
0088     feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0089     asm volatile ("\n"
0090     "   fldln2""\n"
0091     "   fisttp  res16""\n"
0092     "   fldln2""\n"
0093     "   fisttpl res32""\n"
0094     "   fldln2""\n"
0095     "   fisttpll res64""\n"
0096     : : : "memory"
0097     );
0098     /* Test truncation to zero (round-to-nearest would give 1 here) */
0099     if (res16 != 0 || res32 != 0 || res64 != 0) {
0100         printf("[BAD]\tfisttp ln2\n");
0101         return 1;
0102     }
0103     ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
0104     if (ex != FE_INEXACT) {
0105         printf("[BAD]\tfisttp ln2: wrong exception state\n");
0106         return 1;
0107     }
0108 
0109     return 0;
0110 }
0111 
0112 void sighandler(int sig)
0113 {
0114     printf("[FAIL]\tGot signal %d, exiting\n", sig);
0115     exit(1);
0116 }
0117 
0118 int main(int argc, char **argv, char **envp)
0119 {
0120     int err = 0;
0121 
0122     /* SIGILL triggers on 32-bit kernels w/o fisttp emulation
0123      * when run with "no387 nofxsr". Other signals are caught
0124      * just in case.
0125      */
0126     signal(SIGILL, sighandler);
0127     signal(SIGFPE, sighandler);
0128     signal(SIGSEGV, sighandler);
0129 
0130     printf("[RUN]\tTesting fisttp instructions\n");
0131     err |= test();
0132     if (!err)
0133         printf("[OK]\tfisttp\n");
0134     else
0135         printf("[FAIL]\tfisttp errors: %d\n", err);
0136 
0137     return err;
0138 }