#include <stdio.h>      /* standard I/O                */
#include <string.h>     /* for strcpy - 3 occurrences  */
#include <stdlib.h>     /* for exit   - 1 occurrence   */
#include <math.h>       /* for sin, exp etc.           */

struct timeval starttime,endtime;
double te0,te1,te2,te3,te4,te5,te6,te7;
double e1[4096]; /* 64MB array */
long ae = 4096;
double t = 0.49999975;
double t0 = 0.49999975;
double t1 = 0.50000025;
double t2 = 2.0;
double lsfpu;
double x,y,z;
long i,ix,j,k,l;
double pass0,pass1,pass2,pass3,pass4,pass5,pass6,pass7;
long x100 = 100;
long xtra = 100;
long n1;
long n2;
long n3;
long n4;
long n5;
long n6;
long n7;
long n8;
long n1mult;
void pa(double e[4], double t, double t2);	
void p3(double *x, double *y, double *z, double t, double t1, double t2);
void po(double e1[4], long j, long k, long l);

double Section1() {
	        /* Section 1, Math: Geometry */
	n1 = 12*x100;
	n1mult = 10;
	/* double_size=sizeof(double); */
        /* asize=1024*1024/double*mt; how many longs then in one array? */
	printf("\n\tPreparing test. Setting up a 64MB array and assigning values....\n");
	for (ix=0; ix<ae; ix++) {
		e1[ix] = 1;
		e1[ix+1] = 1;
		e1[ix+2] = 1;
		e1[ix+3] = 1;
		ix=ix+3;
	}
        gettimeofday(&starttime, NULL);
            for (ix=0; ix<ae; ix++)
              {
		x = sqrt(exp(log(x)/t1));
		e1[ix] = (e1[ix] + e1[ix+1] + e1[ix+2] - e1[ix+3]) * t;
		e1[ix+1] = (e1[ix] + e1[ix+1] - e1[ix+2] + e1[ix+3]) * t;
		e1[ix+2] = (e1[ix] - e1[ix+1] + e1[ix+2] + e1[ix+3]) * t;
		e1[ix+3] = (-e1[ix] + e1[ix+1] + e1[ix+2] + e1[ix+3]) * t;
		ix=ix+3;
               }
        gettimeofday(&endtime, NULL);
	te0=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	printf("\n\tTest #1:\t Array Elements:   \t%lfs\n", te0);	
	pass0 = ae / te0;
return pass0;
}

double Section2() {
	        /* Section 2, Array as Parameter */
	n2 = 14*x100;
        for (ix=0; ix<ae; ix++) {
                e1[ix] = 1;
                e1[ix+1] = -1;
                e1[ix+2] = 78;
                e1[ix+3] = -28282708;
                ix=ix+3;
        }

	gettimeofday(&starttime, NULL);
	for (ix=0; ix<xtra; ix++)
              {
		for(i=0; i<n2; i++)
                  {
                     pa(e1,t,t2);
                  }
                t = 1.0 - t;
              }
            t =  t0;
        gettimeofday(&endtime, NULL);
        te1=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #2:\t Array as Parameter:\t%lfs\n", te1);
	pass1 = ix / te1;
return pass1;
}


double Section3() {
	        /* Section 3, Conditional Jumps */
	n3 = 345*x100;
        j = 1;
	gettimeofday(&starttime, NULL);
	for (ix=0; ix<xtra; ix++)
              {
		for(i=0; i<n3; i++)
                  {
                     if(j==1)       j = 2;
                     else           j = 3;
                     if(j>2)        j = 0;
                     else           j = 1;
                     if(j<1)        j = 1;
                     else           j = 0;
                  }
              }
        gettimeofday(&endtime, NULL);
        te2=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #3:\t Conditional Jumps: \t%lfs\n", te2);
	pass2 = ix / te2;
return pass2;
}

double Section4() {
        /* Section 4, Integer Arithmetic */
	n4 = 210*x100;
        j = 1;
        k = 2;
        l = 3;
	gettimeofday(&starttime, NULL);
	for (ix=0; ix<xtra; ix++)
              {
                for(i=0; i<n4; i++)
                  {
                     j = j *(k-j)*(l-k);
                     k = l * k - (l-j) * k;
                     l = (l-k) * (k+j);
                     e1[l-2] = j + k + l;
                     e1[k-2] = j * k * l;
                  }
              }
        gettimeofday(&endtime, NULL);
        te3=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #4:\t Integer Arithmetic: \t%lfs\n", te3);
	pass3 = ix / te3;
return pass3;
}

double Section5() {
	        /* Section 5, Trig functions */
	n5 = 32*x100;
        x = 0.5;
        y = 0.5;
        gettimeofday(&starttime, NULL);
	for (ix=0; ix<xtra; ix++)
              {
                for(i=1; i<n5; i++)
                  {
                     x = t*atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0));
                     y = t*atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0));
                  }
                t = 1.0 - t;
              }
            t = t0;
        gettimeofday(&endtime, NULL);
        te4=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #5:\t Trig Functions:    \t%lfs\n", te4);
	pass4 = ix / te4;
return pass4;
}

double Section6() {
	        /* Section 6, Procedure calls */
	n6 = 899*x100;
        x = 1.0;
        y = 1.0;
        z = 1.0;
	gettimeofday(&starttime, NULL);
            for (ix=0; ix<xtra; ix++)
              {
                for(i=0; i<n6; i++)
                  {
                     p3(&x,&y,&z,t,t1,t2);
                  }
              }
        gettimeofday(&endtime, NULL);
        te5=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #6:\t Procedure Calls:   \t%lfs\n", te5);
	pass5 = ix / te5;
return pass5;
}

double Section7() {
	        /* Section 7, Array Refrences */
	n7 = 616*x100;
        j = 0;
        k = 1;
        l = 2;
        e1[0] = 1.0;
        e1[1] = 2.0;
        e1[2] = 3.0;
	gettimeofday(&starttime, NULL);
	for (ix=0; ix<xtra; ix++)
              {
		for(i=0;i<n7;i++)
                  {
                     po(e1,j,k,l);
                  }
              }
        gettimeofday(&endtime, NULL);
        te6=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #7:\t Array References:\t%lfs\n", te6);
	pass6 = ix / te6;
return pass6;
}

double Section8() {
	        /* Section 8, Standard functions */
	n8 = 93*x100;
        x = 0.75;
	gettimeofday(&starttime, NULL);
	for (ix=0; ix<xtra; ix++)
              {
		for(i=0; i<n8; i++)
                  {
                     x = sqrt(exp(log(x)/t1));
                  }
              }
        gettimeofday(&endtime, NULL);
        te7=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        printf("\tTest #8:\t Standard Functions: \t%lfs\n", te7);
	pass7 = ix / te7;
return pass7;
}


void pa(double e[4], double t, double t2)
      {
         long j;
         for(j=0;j<ae;j++)
            {
               e[j] = (e[j]+e[j+1]+e[j+2]-e[j+3])*t;
               e[j+1] = (e[j]+e[j+1]-e[j+2]+e[j+3])*t;
               e[j+2] = (e[j]-e[j+1]+e[j+2]+e[j+3])*t;
               e[j+3] = (-e[j]+e[j+1]+e[j+2]+e[j+3])/t2;
		j=j+3;
            }
return;
}

void p3(double *x, double *y, double *z, double t, double t1, double t2)
      {
         *x = *y;
         *y = *z;
         *x = t * (*x + *y);
         *y = t1 * (*x + *y);
         *z = (*x + *y)/t2;
return;
}

void po(double e1[4], long j, long k, long l)
      {
         e1[j] = e1[k];
         e1[k] = e1[l];
         e1[l] = e1[j];
return;
}


/*int main() {
	Section1();
	Section2();
	Section3();
	Section4();
	Section5();
	Section6();
	Section7();
	Section8();
	lsfpu = (te0 + te1 + te2 + te3 + te4 + te5 + te6 + te7);	
	printf("\nFPU index: %lf\n", lsfpu);

return 0;
} */
