cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test_FISTTP.c (3120B)


      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	"	fisttp	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	"	fisttp	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	"	fisttp	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	"	fisttp	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}