162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#undef _GNU_SOURCE 362306a36Sopenharmony_ci#define _GNU_SOURCE 1 462306a36Sopenharmony_ci#undef __USE_GNU 562306a36Sopenharmony_ci#define __USE_GNU 1 662306a36Sopenharmony_ci#include <unistd.h> 762306a36Sopenharmony_ci#include <stdlib.h> 862306a36Sopenharmony_ci#include <string.h> 962306a36Sopenharmony_ci#include <stdio.h> 1062306a36Sopenharmony_ci#include <signal.h> 1162306a36Sopenharmony_ci#include <sys/types.h> 1262306a36Sopenharmony_ci#include <sys/select.h> 1362306a36Sopenharmony_ci#include <sys/time.h> 1462306a36Sopenharmony_ci#include <sys/wait.h> 1562306a36Sopenharmony_ci#include <fenv.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ciunsigned long long res64 = -1; 1862306a36Sopenharmony_ciunsigned int res32 = -1; 1962306a36Sopenharmony_ciunsigned short res16 = -1; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciint test(void) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci int ex; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 2662306a36Sopenharmony_ci asm volatile ("\n" 2762306a36Sopenharmony_ci " fld1""\n" 2862306a36Sopenharmony_ci " fisttp res16""\n" 2962306a36Sopenharmony_ci " fld1""\n" 3062306a36Sopenharmony_ci " fisttpl res32""\n" 3162306a36Sopenharmony_ci " fld1""\n" 3262306a36Sopenharmony_ci " fisttpll res64""\n" 3362306a36Sopenharmony_ci : : : "memory" 3462306a36Sopenharmony_ci ); 3562306a36Sopenharmony_ci if (res16 != 1 || res32 != 1 || res64 != 1) { 3662306a36Sopenharmony_ci printf("[BAD]\tfisttp 1\n"); 3762306a36Sopenharmony_ci return 1; 3862306a36Sopenharmony_ci } 3962306a36Sopenharmony_ci ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 4062306a36Sopenharmony_ci if (ex != 0) { 4162306a36Sopenharmony_ci printf("[BAD]\tfisttp 1: wrong exception state\n"); 4262306a36Sopenharmony_ci return 1; 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 4662306a36Sopenharmony_ci asm volatile ("\n" 4762306a36Sopenharmony_ci " fldpi""\n" 4862306a36Sopenharmony_ci " fisttp res16""\n" 4962306a36Sopenharmony_ci " fldpi""\n" 5062306a36Sopenharmony_ci " fisttpl res32""\n" 5162306a36Sopenharmony_ci " fldpi""\n" 5262306a36Sopenharmony_ci " fisttpll res64""\n" 5362306a36Sopenharmony_ci : : : "memory" 5462306a36Sopenharmony_ci ); 5562306a36Sopenharmony_ci if (res16 != 3 || res32 != 3 || res64 != 3) { 5662306a36Sopenharmony_ci printf("[BAD]\tfisttp pi\n"); 5762306a36Sopenharmony_ci return 1; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 6062306a36Sopenharmony_ci if (ex != FE_INEXACT) { 6162306a36Sopenharmony_ci printf("[BAD]\tfisttp pi: wrong exception state\n"); 6262306a36Sopenharmony_ci return 1; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 6662306a36Sopenharmony_ci asm volatile ("\n" 6762306a36Sopenharmony_ci " fldpi""\n" 6862306a36Sopenharmony_ci " fchs""\n" 6962306a36Sopenharmony_ci " fisttp res16""\n" 7062306a36Sopenharmony_ci " fldpi""\n" 7162306a36Sopenharmony_ci " fchs""\n" 7262306a36Sopenharmony_ci " fisttpl res32""\n" 7362306a36Sopenharmony_ci " fldpi""\n" 7462306a36Sopenharmony_ci " fchs""\n" 7562306a36Sopenharmony_ci " fisttpll res64""\n" 7662306a36Sopenharmony_ci : : : "memory" 7762306a36Sopenharmony_ci ); 7862306a36Sopenharmony_ci if (res16 != 0xfffd || res32 != 0xfffffffd || res64 != 0xfffffffffffffffdULL) { 7962306a36Sopenharmony_ci printf("[BAD]\tfisttp -pi\n"); 8062306a36Sopenharmony_ci return 1; 8162306a36Sopenharmony_ci } 8262306a36Sopenharmony_ci ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 8362306a36Sopenharmony_ci if (ex != FE_INEXACT) { 8462306a36Sopenharmony_ci printf("[BAD]\tfisttp -pi: wrong exception state\n"); 8562306a36Sopenharmony_ci return 1; 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 8962306a36Sopenharmony_ci asm volatile ("\n" 9062306a36Sopenharmony_ci " fldln2""\n" 9162306a36Sopenharmony_ci " fisttp res16""\n" 9262306a36Sopenharmony_ci " fldln2""\n" 9362306a36Sopenharmony_ci " fisttpl res32""\n" 9462306a36Sopenharmony_ci " fldln2""\n" 9562306a36Sopenharmony_ci " fisttpll res64""\n" 9662306a36Sopenharmony_ci : : : "memory" 9762306a36Sopenharmony_ci ); 9862306a36Sopenharmony_ci /* Test truncation to zero (round-to-nearest would give 1 here) */ 9962306a36Sopenharmony_ci if (res16 != 0 || res32 != 0 || res64 != 0) { 10062306a36Sopenharmony_ci printf("[BAD]\tfisttp ln2\n"); 10162306a36Sopenharmony_ci return 1; 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); 10462306a36Sopenharmony_ci if (ex != FE_INEXACT) { 10562306a36Sopenharmony_ci printf("[BAD]\tfisttp ln2: wrong exception state\n"); 10662306a36Sopenharmony_ci return 1; 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return 0; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_civoid sighandler(int sig) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci printf("[FAIL]\tGot signal %d, exiting\n", sig); 11562306a36Sopenharmony_ci exit(1); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint main(int argc, char **argv, char **envp) 11962306a36Sopenharmony_ci{ 12062306a36Sopenharmony_ci int err = 0; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci /* SIGILL triggers on 32-bit kernels w/o fisttp emulation 12362306a36Sopenharmony_ci * when run with "no387 nofxsr". Other signals are caught 12462306a36Sopenharmony_ci * just in case. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci signal(SIGILL, sighandler); 12762306a36Sopenharmony_ci signal(SIGFPE, sighandler); 12862306a36Sopenharmony_ci signal(SIGSEGV, sighandler); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci printf("[RUN]\tTesting fisttp instructions\n"); 13162306a36Sopenharmony_ci err |= test(); 13262306a36Sopenharmony_ci if (!err) 13362306a36Sopenharmony_ci printf("[OK]\tfisttp\n"); 13462306a36Sopenharmony_ci else 13562306a36Sopenharmony_ci printf("[FAIL]\tfisttp errors: %d\n", err); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci return err; 13862306a36Sopenharmony_ci} 139