minix/test/test53.c
Thomas Veerman a209c3ae12 Fix a ton of compiler warnings
This patch fixes most of current reasons to generate compiler warnings.
The changes consist of:
 - adding missing casts
 - hiding or unhiding function declarations
 - including headers where missing
 - add __UNCONST when assigning a const char * to a char *
 - adding missing return statements
 - changing some types from unsigned to signed, as the code seems to want
   signed ints
 - converting old-style function definitions to current style (i.e.,
   void func(param1, param2) short param1, param2; {...} to
   void func (short param1, short param2) {...})
 - making the compiler silent about signed vs unsigned comparisons. We
   have too many of those in the new libc to fix.

A number of bugs in the test set were fixed. These bugs were never
triggered with our old libc. Consequently, these tests are now forced to
link with the new libc or they will generate errors (in particular tests 43
and 55).

Most changes in NetBSD libc are limited to moving aroudn "#ifndef __minix"
or stuff related to Minix-specific things (code in sys-minix or gen/minix).
2011-11-14 10:07:49 +00:00

280 lines
6.2 KiB
C

#include <assert.h>
#include <minix/u64.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#define ERR err(__LINE__)
#define MAX_ERROR 4
#define TIMED 0
#include "common.c"
static volatile int expect_SIGFPE;
static u64_t i, j, k;
static jmp_buf jmpbuf_SIGFPE, jmpbuf_main;
static void err(int line)
{
/* print error information */
printf("error line %d; i=0x%.8lx%.8lx; j=0x%.8lx%.8lx; k=0x%.8lx%.8lx\n",
line,
ex64hi(i), ex64lo(i),
ex64hi(j), ex64lo(j),
ex64hi(k), ex64lo(k));
/* quit after too many errors */
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
quit();
}
}
#define LENGTHOF(arr) (sizeof(arr) / sizeof(arr[0]))
static u64_t getargval(int index, int *done)
{
u32_t values[] = {
/* corner cases */
0,
1,
0x7fffffff,
0x80000000,
0x80000001,
0xffffffff,
/* random values */
0xa9,
0x0d88,
0x242811,
0xeb44d1bc,
0x5b,
0xfb50,
0x569c02,
0xb23c8f7d,
0xc3,
0x2366,
0xfabb73,
0xcb4e8aef,
0xe9,
0xffdc,
0x05842d,
0x3fff902d};
assert(done);
/* values with corner case and random 32-bit components */
if (index < LENGTHOF(values) * LENGTHOF(values))
return make64(values[index / LENGTHOF(values)], values[index % LENGTHOF(values)]);
index -= LENGTHOF(values) * LENGTHOF(values);
/* small numbers */
if (index < 16) return make64(index + 2, 0);
index -= 16;
/* big numbers */
if (index < 16) return make64(-index - 2, -1);
index -= 16;
/* powers of two */
if (index < 14) return make64(1 << (index * 2 + 5), 0);
index -= 14;
if (index < 16) return make64(0, 1 << (index * 2 + 1));
index -= 16;
/* done */
*done = 1;
return make64(0, 0);
}
static void handler_SIGFPE(int signum)
{
assert(signum == SIGFPE);
/* restore the signal handler */
if (signal(SIGFPE, handler_SIGFPE) == SIG_ERR) ERR;
/* division by zero occurred, was this expected? */
if (expect_SIGFPE) {
/* expected: jump back to test */
expect_SIGFPE = 0;
longjmp(jmpbuf_SIGFPE, -1);
} else {
/* not expected: error and jump back to main */
longjmp(jmpbuf_main, -1);
}
/* not reachable */
assert(0);
exit(-1);
}
static void testmul(void)
{
int kdone, kidx;
u32_t ilo = ex64lo(i), jlo = ex64lo(j);
u64_t prod = mul64(i, j);
int prodbits;
/* compute maximum index of highest-order bit */
prodbits = bsr64(i) + bsr64(j) + 1;
if (cmp64u(i, 0) == 0 || cmp64u(j, 0) == 0) prodbits = -1;
if (bsr64(prod) > prodbits) ERR;
/* compare to 32-bit multiplication if possible */
if (ex64hi(i) == 0 && ex64hi(j) == 0) {
if (cmp64(prod, mul64u(ilo, jlo)) != 0) ERR;
/* if there is no overflow we can check against pure 32-bit */
if (prodbits < 32 && cmp64u(prod, ilo * jlo) != 0) ERR;
}
/* in 32-bit arith low-order DWORD matches regardless of overflow */
if (ex64lo(prod) != ilo * jlo) ERR;
/* multiplication by zero yields zero */
if (prodbits < 0 && cmp64u(prod, 0) != 0) ERR;
/* if there is no overflow, check absence of zero divisors */
if (prodbits >= 0 && prodbits < 64 && cmp64u(prod, 0) == 0) ERR;
/* commutativity */
if (cmp64(prod, mul64(j, i)) != 0) ERR;
/* loop though all argument value combinations for third argument */
for (kdone = 0, kidx = 0; k = getargval(kidx, &kdone), !kdone; kidx++) {
/* associativity */
if (cmp64(mul64(mul64(i, j), k), mul64(i, mul64(j, k))) != 0) ERR;
/* left and right distributivity */
if (cmp64(mul64(add64(i, j), k), add64(mul64(i, k), mul64(j, k))) != 0) ERR;
if (cmp64(mul64(i, add64(j, k)), add64(mul64(i, j), mul64(i, k))) != 0) ERR;
}
}
static void testdiv0(void)
{
int funcidx;
assert(cmp64u(j, 0) == 0);
/* loop through the 5 different division functions */
for (funcidx = 0; funcidx < 5; funcidx++) {
expect_SIGFPE = 1;
if (setjmp(jmpbuf_SIGFPE) == 0) {
/* divide by zero using various functions */
switch (funcidx) {
case 0: div64(i, j); ERR; break;
case 1: div64u64(i, ex64lo(j)); ERR; break;
case 2: div64u(i, ex64lo(j)); ERR; break;
case 3: rem64(i, j); ERR; break;
case 4: rem64u(i, ex64lo(j)); ERR; break;
default: assert(0); ERR; break;
}
/* if we reach this point there was no signal and an
* error has been recorded
*/
expect_SIGFPE = 0;
} else {
/* a signal has been received and expect_SIGFPE has
* been reset; all is ok now
*/
assert(!expect_SIGFPE);
}
}
}
static void testdiv(void)
{
u64_t q, r;
#if TIMED
struct timeval tvstart, tvend;
printf("i=0x%.8x%.8x; j=0x%.8x%.8x\n",
ex64hi(i), ex64lo(i),
ex64hi(j), ex64lo(j));
fflush(stdout);
if (gettimeofday(&tvstart, NULL) < 0) ERR;
#endif
/* division by zero has a separate test */
if (cmp64u(j, 0) == 0) {
testdiv0();
return;
}
/* perform division, store q in k to make ERR more informative */
q = div64(i, j);
r = rem64(i, j);
k = q;
#if TIMED
if (gettimeofday(&tvend, NULL) < 0) ERR;
tvend.tv_sec -= tvstart.tv_sec;
tvend.tv_usec -= tvstart.tv_usec;
if (tvend.tv_usec < 0) {
tvend.tv_sec -= 1;
tvend.tv_usec += 1000000;
}
printf("q=0x%.8x%.8x; r=0x%.8x%.8x; time=%d.%.6d\n",
ex64hi(q), ex64lo(q),
ex64hi(r), ex64lo(r),
tvend.tv_sec, tvend.tv_usec);
fflush(stdout);
#endif
/* compare to 64/32-bit division if possible */
if (!ex64hi(j)) {
if (cmp64(q, div64u64(i, ex64lo(j))) != 0) ERR;
if (!ex64hi(q)) {
if (cmp64u(q, div64u(i, ex64lo(j))) != 0) ERR;
}
if (cmp64u(r, rem64u(i, ex64lo(j))) != 0) ERR;
/* compare to 32-bit division if possible */
if (!ex64hi(i)) {
if (cmp64u(q, ex64lo(i) / ex64lo(j)) != 0) ERR;
if (cmp64u(r, ex64lo(i) % ex64lo(j)) != 0) ERR;
}
}
/* check results using i = q j + r and r < j */
if (cmp64(i, add64(mul64(q, j), r)) != 0) ERR;
if (cmp64(r, j) >= 0) ERR;
}
static void test(void)
{
int idone, jdone, iidx, jidx;
/* loop though all argument value combinations */
for (idone = 0, iidx = 0; i = getargval(iidx, &idone), !idone; iidx++)
for (jdone = 0, jidx = 0; j = getargval(jidx, &jdone), !jdone; jidx++) {
testmul();
testdiv();
}
}
int main(void)
{
start(53);
/* set up signal handler to deal with div by zero */
if (setjmp(jmpbuf_main) == 0) {
if (signal(SIGFPE, handler_SIGFPE) == SIG_ERR) ERR;
/* perform tests */
test();
} else {
/* an unexpected SIGFPE has occurred */
ERR;
}
/* this was all */
quit();
}