95 lines
4.6 KiB
C
95 lines
4.6 KiB
C
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||
│ │
|
||
│ This program is free software; you can redistribute it and/or modify │
|
||
│ it under the terms of the GNU General Public License as published by │
|
||
│ the Free Software Foundation; version 2 of the License. │
|
||
│ │
|
||
│ This program is distributed in the hope that it will be useful, but │
|
||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||
│ General Public License for more details. │
|
||
│ │
|
||
│ You should have received a copy of the GNU General Public License │
|
||
│ along with this program; if not, write to the Free Software │
|
||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||
│ 02110-1301 USA │
|
||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||
#include "libc/bits/weaken.h"
|
||
#include "libc/macros.h"
|
||
#include "libc/runtime/runtime.h"
|
||
#include "libc/stdio/stdio.h"
|
||
#include "test/tool/build/lib/numbers.h"
|
||
#include "test/tool/build/lib/optest.h"
|
||
#include "tool/build/lib/flags.h"
|
||
|
||
const char kOpSuffix[] = {'b', 'w', 'l', 'q'};
|
||
|
||
void(RunOpTests)(const uint8_t *ops, size_t n, const char *const *opnames,
|
||
const char *file, int line, const char *func) {
|
||
uint64_t x, y;
|
||
uint64_t xn, xp;
|
||
uint32_t f0, f1, f2;
|
||
long failed, succeeded;
|
||
int w, h, i, j, c, z, s, o, p;
|
||
failed = 0;
|
||
succeeded = 0;
|
||
for (w = 0; w < 4; ++w) {
|
||
for (h = 0; h < n; ++h) {
|
||
for (z = 0; z < 2; ++z) {
|
||
for (o = 0; o < 2; ++o) {
|
||
for (s = 0; s < 2; ++s) {
|
||
for (i = 0; i < ARRAYLEN(kNumbers); ++i) {
|
||
for (j = 0; j < ARRAYLEN(kNumbers); ++j) {
|
||
for (c = 0; c < 2; ++c) {
|
||
x = kNumbers[i];
|
||
y = kNumbers[j];
|
||
f2 = f1 = f0 = c << FLAGS_CF | z << FLAGS_ZF | s << FLAGS_SF |
|
||
o << FLAGS_OF;
|
||
xn = RunGolden(w, ops[h], x, y, &f1);
|
||
xp = RunOpTest(w, ops[h], x, y, &f2);
|
||
if (weaken(FixupUndefOpTestFlags)) {
|
||
FixupUndefOpTestFlags(w, ops[h], x, y, f1, &f2);
|
||
}
|
||
if (xn == xp && (f1 & FMASK) == (f2 & FMASK)) {
|
||
succeeded++;
|
||
} else if (failed++ < 10) {
|
||
fprintf(stderr,
|
||
"%s:%d:%s: %s%c failed\n\t"
|
||
"𝑥 %016x\n\t"
|
||
"𝑦 %016x %c%c%c%c 0NPlODITSZKA1PVC\n\t"
|
||
"𝑥ₙ %016x %c%c%c%c %016b\n\t"
|
||
"𝑥ₚ %016x %c%c%c%c %016b\n",
|
||
file, line, func, opnames[ops[h]], kOpSuffix[w], x,
|
||
y, ".C"[c], ".Z"[z], ".S"[s], ".O"[o], xn,
|
||
".C"[!!(f1 & (1 << FLAGS_CF))],
|
||
".Z"[!!(f1 & (1 << FLAGS_ZF))],
|
||
".S"[!!(f1 & (1 << FLAGS_SF))],
|
||
".O"[!!(f1 & (1 << FLAGS_OF))], f1, xp,
|
||
".C"[!!(f2 & (1 << FLAGS_CF))],
|
||
".Z"[!!(f2 & (1 << FLAGS_ZF))],
|
||
".S"[!!(f2 & (1 << FLAGS_SF))],
|
||
".O"[!!(f2 & (1 << FLAGS_OF))], f2);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (failed) {
|
||
fprintf(stderr,
|
||
"\n"
|
||
"passing: %d%%\n"
|
||
"succeeded: %,ld\n"
|
||
"failed: %,ld\n"
|
||
"\n",
|
||
(int)((1 - (double)failed / succeeded) * 100), succeeded, failed);
|
||
exit(1);
|
||
}
|
||
}
|