diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-24 17:57:51 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-24 17:57:51 +0200 |
| commit | 77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507 (patch) | |
| tree | 93d4e30a207265af03394d347bfff76ba677f3ce /src/benchmarks/cfrac/padd.c | |
| parent | 971adefadb94e8780b1a73f08ed11d76c2ead8a2 (diff) | |
| download | allocbench-77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507.tar.gz allocbench-77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507.zip | |
add cfrac benchmark
Diffstat (limited to 'src/benchmarks/cfrac/padd.c')
| -rw-r--r-- | src/benchmarks/cfrac/padd.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/benchmarks/cfrac/padd.c b/src/benchmarks/cfrac/padd.c new file mode 100644 index 0000000..62b93d5 --- /dev/null +++ b/src/benchmarks/cfrac/padd.c @@ -0,0 +1,94 @@ +#include "pdefs.h" +#include "precision.h" +#include <string.h> + +#ifdef ASM_16BIT +#include "asm16bit.h" +#endif + +/* + * Add + * + * This will work correctly if -0 is passed as input + */ +precision padd(u, v) + register precision v; +#ifndef ASM_16BIT + precision u; +{ + register digitPtr wPtr, uPtr, vPtr; +#else + register precision u; +{ + register digitPtr wPtr; + digitPtr uPtr; +#endif + precision w; /* function result */ + register accumulator temp; /* 0 <= temp < 2*base */ + register digit carry; /* 0 <= carry <= 1 */ +#ifdef ASM_16BIT + register int size; +#endif + + (void) pparm(u); + (void) pparm(v); + if (u->sign != v->sign) { /* Are we are actually subtracting? */ + w = pUndef; + if (v->sign) { + v->sign = !v->sign; /* can't generate -0 */ + pset(&w, psub(u, v)); + v->sign = !v->sign; + } else { + u->sign = !u->sign; /* can't generate -0 */ + pset(&w, psub(v, u)); + u->sign = !u->sign; + } + } else { + if (u->size < v->size) { /* u is always biggest number */ + w = u; u = v; v = w; + } + + w = palloc(u->size+1); /* there is at most one added digit */ + if (w == pUndef) return w; /* arguments not destroyed */ + + w->sign = u->sign; + + uPtr = u->value; + wPtr = w->value; +#ifndef ASM_16BIT + vPtr = v->value; + carry = 0; + do { /* Add digits in both args */ + temp = *uPtr++ + *vPtr++; /* 0 <= temp < 2*base-1 */ + temp += carry; /* 0 <= temp < 2*base */ + carry = divBase(temp); /* 0 <= carry <= 1 */ + *wPtr++ = modBase(temp); /* mod has positive args */ + } while (vPtr < v->value + v->size); + + while (uPtr < u->value + u->size) { /* propogate carry */ + temp = *uPtr++ + carry; + carry = divBase(temp); + *wPtr++ = modBase(temp); + } + *wPtr = carry; +#else + size = v->size; + temp = u->size - size; + carry = memaddw(wPtr, uPtr, v->value, size); + if (temp > 0) { + memcpy(wPtr + size, uPtr + size, temp * sizeof(digit)); + if (carry) { + carry = memincw(wPtr + size, temp); + } + } + wPtr[u->size] = carry; /* yes, I do mean u->size */ +#endif + if (carry == 0) { + --(w->size); + } + } + + pdestroy(u); + pdestroy(v); + return presult(w); +} |
