File Index
Files and directories
Sign in
FILE

test_FISTTP.c

File preview with syntax highlighting.

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