brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · b9ae9d8 Raw
139 lines · c
1// SPDX-License-Identifier: GPL-2.02#undef _GNU_SOURCE3#define _GNU_SOURCE 14#undef __USE_GNU5#define __USE_GNU 16#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 emulation123	 * when run with "no387 nofxsr". Other signals are caught124	 * 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	else135		printf("[FAIL]\tfisttp errors: %d\n", err);136 137	return err;138}139