1
0
Files
2022-09-29 17:59:04 +03:00

115 lines
3.0 KiB
C

#if TFP
/*
* div2.c
*
* This test program is originated from iain@mti div2.c, I modified
* it for IP21prom environment.
* When FPU test failed in Slave processor, proper diag error code will
* return to Master processor.
*/
#include <sys/types.h>
#include <math.h>
#include <sys/cpu.h>
#include <sys/loaddrs.h>
#include <sys/sbd.h>
#include <pon.h>
#include <libsc.h>
#include <libsk.h>
#include <sys/EVEREST/evmp.h>
#include <sys/EVEREST/evintr.h>
#include <sys/EVEREST/evconfig.h>
#include <sys/EVEREST/gda.h>
#include <sys/EVEREST/nvram.h>
#include <sys/EVEREST/evdiag.h>
#include <sys/EVEREST/diagval_strs.i>
struct test_block {
double num[4];
double denom[4];
double res[4][4]; /* indexed by [numerator][denominator] */
double rem[4][4]; /* indexed by [numerator][denominator] */
long long destep;
long long des, pts;
int inexact_rem;
int bigrem;
double hulp;
double minrem[4];
double maxrem[4];
};
void fputest(void);
void prom_flash_leds(void);
void loop_block_div(struct test_block *);
int dtest(double , double , double , double , long long);
void
fputest(void)
{
long long p[14] = {3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int i, slot, slice;
slot = (load_double((long long *)EV_SPNUM)
& EV_SLOTNUM_MASK) >> EV_SLOTNUM_SHFT;
slice = (load_double((long long *)EV_SPNUM)
& EV_PROCNUM_MASK) >> EV_PROCNUM_SHFT;
for (i=0; i<14; i++) {
if (dtest(1.0, 1.0/p[i], 1.0, 1.0/p[i], p[i]) != 0) {
EVCFGINFO->ecfg_board[slot].eb_cpuarr[slice].cpu_diagval = EVDIAG_FPU;
prom_flash_leds();
}
}
}
int dtest(double nbase, double nstep, double dbase, double destep, long long p) {
long ns;
struct test_block test;
double min[4],max[4];
int n, d;
double margin, himargin, lomargin;
double maxround, minround;
long long denstart;
int fpu_error = 0;
maxround = minround = 0.;
*(long long*)&test.hulp = 0x3ca0000000000000;
test.destep = 0x6000000000000000/(long long)p;
test.pts = p;
for (ns = 0; ns < p; ns+=4) {
test.num[0] = nbase + ns *nstep;
test.num[1] = nbase + (ns+1)*nstep;
test.num[2] = nbase + (ns+2)*nstep;
test.num[3] = nbase + (ns+3)*nstep;
denstart = 0x1000000000000000;
test.denom[0] = *(double *)&denstart;
denstart += test.destep;
test.denom[1] = *(double *)&denstart;
denstart += test.destep;
test.denom[2] = *(double *)&denstart;
denstart += test.destep;
test.denom[3] = *(double *)&denstart;
test.minrem[0]=test.minrem[1]=test.minrem[2]=test.minrem[3]= 0;
test.maxrem[0]=test.maxrem[1]=test.maxrem[2]=test.maxrem[3]= 0;
for (test.des = 0; test.des < p;) {
loop_block_div(&test);
if (test.inexact_rem)
fpu_error++;
if (test.bigrem)
fpu_error++;
}
for (n=0; n<4; n++) {
min[n] = test.minrem[n]/(test.hulp*test.num[n]);
max[n] = test.maxrem[n]/(test.hulp*test.num[n]);
if (min[n] < minround) minround = min[n];
if (max[n] > maxround) maxround = max[n];
}
return(fpu_error);
}
}
#endif