![]()
Parent Directory
|
Revision Log
Copy old working vx32 version from vxa-060115 tag.
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <inttypes.h>
#include <openssl/aes.h>
#include <openssl/sha.h>
float z = 0.0;
int iters = 1000*1;
//int iters = 1000*1000*1000;
unsigned char zkey[128/8] = "the key!!!";
AES_KEY aeskey;
union block {
int32_t i[4];
int64_t l[2];
float f[4];
double d[2];
uint8_t b[16];
};
struct opargs {
union block i;
union block o;
SHA_CTX c;
};
#define DEFOP(name,op) \
void name(struct opargs *a) { op; }
// Single-precision operations
#define ia1 a->i.f[0]
#define ia2 a->i.f[1]
#define ib1 a->i.f[2]
#define ib2 a->i.f[3]
#define oa a->o.f[0]
#define ob a->o.f[1]
DEFOP(sadd, (oa = ia1 + ia2, ob = ib1 + ib2))
DEFOP(ssub, (oa = ia1 - ia2, ob = ib1 - ib2))
DEFOP(smul, (oa = ia1 * ia2, ob = ib1 * ib2))
DEFOP(sdiv, (oa = ia1 / ia2, ob = ib1 / ib2))
DEFOP(srec, (oa = 1.0 / ia1, ob = 1.0 / ib1))
DEFOP(stoi, (a->o.i[0] = (int32_t)ia1, a->o.i[1] = (int32_t)ib1))
DEFOP(sfri, (oa = a->i.i[0], ob = a->i.i[2]))
DEFOP(ssqrt, (oa = sqrtf(ia1), ob = sqrtf(ib1)))
DEFOP(ssin, (oa = sinf(ia1), ob = sinf(ib1)))
DEFOP(sexp, (oa = expf(ia1), ob = expf(ib1)))
#undef ia1
#undef ia2
#undef ib1
#undef ib2
#undef oa
#undef ob
// Double-precision operations
#define i1 a->i.d[0]
#define i2 a->i.d[1]
#define oo a->o.d[0]
DEFOP(dadd, (oo = i1 + i2))
DEFOP(dsub, (oo = i1 - i2))
DEFOP(dmul, (oo = i1 * i2))
DEFOP(ddiv, (oo = i1 / i2))
DEFOP(drec, (oo = 1.0 / i1))
DEFOP(dtol, (a->o.l[0] = (int64_t)i1))
DEFOP(dfrl, (oo = a->i.l[0]))
DEFOP(dsqrt, (oo = sqrt(i1)))
DEFOP(dsin, (oo = sin(i1)))
DEFOP(dexp, (oo = exp(i1)))
#undef i1
#undef i2
#undef o
void stest(char *name, int dbl, void (*op)(struct opargs *a))
{
printf("%30s: ", name);
fflush(stdout);
int rc = AES_set_encrypt_key(zkey, 128, &aeskey);
assert(rc == 0);
// initialize the loop arguments
struct opargs a;
memset(&a, 0, sizeof(a));
SHA1_Init(&a.c);
// compute the op hash
for (int i = 0; i < iters; i++) {
// generate another block of arguments
AES_encrypt(a.i.b, a.i.b, &aeskey);
// perform the appropriate operation
op(&a);
// Squash NANs
if (dbl) {
if (isnan(a.o.d[0]))
a.o.d[0] = 0.0;
} else {
if (isnan(a.o.f[0]))
a.o.f[0] = 0.0;
if (isnan(a.o.f[1]))
a.o.f[1] = 0.0;
}
// hash the results
SHA1_Update(&a.c, a.o.b, 8);
#if 1
uint8_t hash[20];
SHA1_Final(hash, &a.c);
if (dbl) {
printf("%d: %f,%f->%f\n", i,
a.i.d[0], a.i.d[1], a.o.d[0]);
printf("hex: %016llx,%016llx->%016llx\n",
a.i.l[0], a.i.l[1], a.o.l[0]);
} else {
printf("%d: %f,%f->%f, %f,%f->%f\n", i,
a.i.f[0], a.i.f[1], a.o.f[0],
a.i.f[2], a.i.f[3], a.o.f[1]);
}
for (int j = 0; j < 20; j++)
printf("%02x", hash[j]);
printf("\n");
#endif
}
// output the op hash
uint8_t hash[20];
SHA1_Final(hash, &a.c);
for (int i = 0; i < 20; i++)
printf("%02x", hash[i]);
printf("\n");
}
int main()
{
#if 0
stest("Single-precision add", 0, sadd);
stest("Single-precision subtract", 0, ssub);
stest("Single-precision multiply", 0, smul);
stest("Single-precision divide", 0, sdiv);
stest("Single-precision reciprocal", 0, srec);
stest("Single-precision to int", 0, stoi);
stest("Single-precision from int", 0, sfri);
stest("Single-precision square root", 0, ssqrt);
stest("Single-precision sine", 0, ssin);
stest("Single-precision exponent", 0, sexp);
stest("Double-precision add", 1, dadd);
stest("Double-precision subtract", 1, dsub);
stest("Double-precision multiply", 1, dmul);
stest("Double-precision divide", 1, ddiv);
stest("Double-precision reciprocal", 1, drec);
stest("Double-precision to long", 1, dtol);
stest("Double-precision from long", 1, dfrl);
stest("Double-precision square root", 1, dsqrt);
stest("Double-precision sine", 1, dsin);
stest("Double-precision exponent", 1, dexp);
#endif
stest("Double-precision multiply", 1, dmul);
}
| Maintained by PDOS | ViewVC Help |
| Powered by ViewVC 1.0.3 |