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);
|
|||
|
}
|
|||
|
}
|