diff options
Diffstat (limited to 'emfloat.c')
-rw-r--r-- | emfloat.c | 123 |
1 files changed, 21 insertions, 102 deletions
@@ -26,11 +26,26 @@ #include <stdio.h> #include <string.h> -#include <time.h> #include "nmglobal.h" #include "randnum.h" #include "emfloat.h" +static void SetInternalFPFZero(InternalFPF *dest, + unsigned char sign); +static void SetInternalFPFInfinity(InternalFPF *dest, + unsigned char sign); +static void SetInternalFPFNaN(InternalFPF *dest); +static int IsMantissaZero(uint16_t *mant); +static void Add16Bits(uint16_t *carry,uint16_t *a,uint16_t b,uint16_t c); +static void Sub16Bits(uint16_t *borrow,uint16_t *a,uint16_t b,uint16_t c); +static void ShiftMantLeft1(uint16_t *carry,uint16_t *mantissa); +static void ShiftMantRight1(uint16_t *carry,uint16_t *mantissa); +static void StickyShiftRightMant(InternalFPF *ptr,int amount); +static void RoundInternalFPF(InternalFPF *ptr); +static void normalize(InternalFPF *ptr); +static void denormalize(InternalFPF *ptr,int minimum_exponent); +static void choose_nan(InternalFPF *x,InternalFPF *y,InternalFPF *z, + int intel_flag); /* ** Floating-point emulator. ** These routines are only "sort of" IEEE-compliant. All work is @@ -46,100 +61,6 @@ ** Computer Hobbyists" by Neill Graham. */ -/************************** -** SetupCPUEmFloatArrays ** -*************************** -** Set up the arrays that will be used in the emulated -** floating-point tests. -** This is done by loading abase and bbase elements with -** random numbers. We use our long-to-floating point -** routine to set them up. -** NOTE: We really don't need the pointer to cbase...cbase -** is overwritten in the benchmark. -*/ -void SetupCPUEmFloatArrays(InternalFPF *abase, - InternalFPF *bbase, - InternalFPF *cbase, - unsigned long arraysize) -{ -unsigned long i; -InternalFPF locFPF1,locFPF2; -/* -** Reset random number generator so things repeat. Inserted by Uwe F. Mayer. -*/ -extern int32_t randnum(int32_t lngval); -randnum(13); - -for(i=0;i<arraysize;i++) -{/* LongToInternalFPF(randwc(50000L),&locFPF1); */ - Int32ToInternalFPF(randwc(50000),&locFPF1); - /* LongToInternalFPF(randwc(50000L)+1L,&locFPF2); */ - Int32ToInternalFPF(randwc(50000)+1,&locFPF2); - DivideInternalFPF(&locFPF1,&locFPF2,abase+i); - /* LongToInternalFPF(randwc(50000L)+1L,&locFPF2); */ - Int32ToInternalFPF(randwc(50000)+1,&locFPF2); - DivideInternalFPF(&locFPF1,&locFPF2,bbase+i); -} -return; -} - -/*********************** -** DoEmFloatIteration ** -************************ -** Perform an iteration of the emulated floating-point -** benchmark. Note that "an iteration" can involve multiple -** loops through the benchmark. -*/ -unsigned long DoEmFloatIteration(InternalFPF *abase, - InternalFPF *bbase, - InternalFPF *cbase, - unsigned long arraysize, unsigned long loops) -{ - clock_t start, stop; -static unsigned char jtable[16] = {0,0,0,0,1,1,1,1,2,2,2,2,2,3,3,3}; -unsigned long i; - - start = clock(); - -/* -** Each pass through the array performs operations in -** the followingratios: -** 4 adds, 4 subtracts, 5 multiplies, 3 divides -** (adds and subtracts being nearly the same operation) -*/ -while(loops--) -{ - for(i=0;i<arraysize;i++) - switch(jtable[i % 16]) - { - case 0: /* Add */ - AddSubInternalFPF(0,abase+i, - bbase+i, - cbase+i); - break; - case 1: /* Subtract */ - AddSubInternalFPF(1,abase+i, - bbase+i, - cbase+i); - break; - case 2: /* Multiply */ - MultiplyInternalFPF(abase+i, - bbase+i, - cbase+i); - break; - case 3: /* Divide */ - DivideInternalFPF(abase+i, - bbase+i, - cbase+i); - break; - } - } - - stop = clock(); - - return stop - start; -} - /*********************** ** SetInternalFPFZero ** ************************ @@ -433,7 +354,7 @@ return; ** The kind of rounding we do here is simplest...referred to as ** "chop". "Extraneous" rightmost bits are simply hacked off. */ -void RoundInternalFPF(InternalFPF *ptr) +void static RoundInternalFPF(InternalFPF *ptr) { /* int i; */ @@ -522,7 +443,7 @@ return; ** Internal-representation numbers pointed to by x and y are ** added/subtracted and the result returned in z. */ -static void AddSubInternalFPF(unsigned char operation, +void AddSubInternalFPF(unsigned char operation, InternalFPF *x, InternalFPF *y, InternalFPF *z) @@ -731,7 +652,7 @@ return; ** Two internal-representation numbers x and y are multiplied; the ** result is returned in z. */ -static void MultiplyInternalFPF(InternalFPF *x, +void MultiplyInternalFPF(InternalFPF *x, InternalFPF *y, InternalFPF *z) { @@ -893,7 +814,7 @@ return; *********************** ** Divide internal FPF number x by y. Return result in z. */ -static void DivideInternalFPF(InternalFPF *x, +void DivideInternalFPF(InternalFPF *x, InternalFPF *y, InternalFPF *z) { @@ -1046,13 +967,11 @@ RoundInternalFPF(z); } /********************** -** LongToInternalFPF ** ** Int32ToInternalFPF ** *********************** ** Convert a signed (long) 32-bit integer into an internal FPF number. */ -/* static void LongToInternalFPF(long mylong, */ -static void Int32ToInternalFPF(int32_t mylong, +void Int32ToInternalFPF(int32_t mylong, InternalFPF *dest) { int i; /* Index */ |