0001
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
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
0123
0124
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 }