9extern int kputs(
char *s);
13static int rig_kputs(
char *s) {
14 if (strstr(s,
": FAIL")) rig_failed = 1;
18#define kputs rig_kputs
20#define NOINL __attribute__((noinline))
24static volatile uint32_t vtbl[] = {
25 0x00000000u, 0x80000000u, 0x3f800000u, 0xbf800000u, 0x7fc00000u, 0xffc00000u, 0x7f800000u,
26 0xff800000u, 0x00000001u, 0x80000001u, 0x007fffffu, 0x00800000u, 0x7f7fffffu, 0xff7fffffu,
27 0x7fffffffu, 0x3f800001u, 0x40490fdbu, 0xc0490fdbu};
28#define N ((int)(sizeof(vtbl) / sizeof(vtbl[0])))
31static inline void mix(uint32_t v) { h = (h ^ v) * 16777619u; }
32static inline uint32_t bits(
float f) { uint32_t u; memcpy(&u, &f, 4);
return u; }
33static inline float val(
int i) {
float f; uint32_t u = vtbl[i]; memcpy(&f, &u, 4);
return f; }
35static void hex8(uint32_t v,
char *o) {
36 for (
int i = 7; i >= 0; i--) { o[i] =
"0123456789abcdef"[v & 15]; v >>= 4; }
39static void report(
const char *name) {
42 while (name[n] && n < 40) { line[n] = name[n]; n++; }
51NOINL
static int lt(
float a,
float b) {
return a < b; }
52NOINL
static int le(
float a,
float b) {
return a <= b; }
53NOINL
static int gt(
float a,
float b) {
return a > b; }
54NOINL
static int ge(
float a,
float b) {
return a >= b; }
55NOINL
static int eq(
float a,
float b) {
return a == b; }
56NOINL
static int ne(
float a,
float b) {
return a != b; }
57NOINL
static int unordered(
float a,
float b) {
return __builtin_isunordered(a, b); }
58NOINL
static int isn(
float a) {
return a != a; }
59NOINL
static float mx(
float a,
float b) {
return a > b ? a : b; }
60NOINL
static float mn(
float a,
float b) {
return a < b ? a : b; }
61NOINL
static float fmxf(
float a,
float b) {
return fmaxf(a, b); }
62NOINL
static float fmnf(
float a,
float b) {
return fminf(a, b); }
63NOINL
static float clamp(
float a,
float lo,
float hi) {
return a < lo ? lo : (a > hi ? hi : a); }
64NOINL
static float sq(
float a) {
return sqrtf(a); }
65NOINL
static float absf(
float a) {
return fabsf(a); }
67#define CMP(fn) do { h = 2166136261u; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) mix((uint32_t)fn(val(i), val(j))); report(#fn); } while (0)
68#define BIN(fn) do { h = 2166136261u; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) mix(bits(fn(val(i), val(j)))); report(#fn); } while (0)
70static int test_main(
void) {
71 CMP(lt); CMP(le); CMP(gt); CMP(ge); CMP(eq); CMP(ne); CMP(unordered);
72 h = 2166136261u;
for (
int i = 0; i < N; i++) mix((uint32_t)isn(val(i))); report(
"isnan");
73 BIN(mx); BIN(mn); BIN(fmxf); BIN(fmnf);
75 for (
int i = 0; i < N; i++)
for (
int j = 0; j < N; j++)
for (
int k = 0; k < N; k++) mix(bits(clamp(val(i), val(j), val(k))));
77 h = 2166136261u;
for (
int i = 0; i < N; i++) mix(bits(sq(val(i)))); report(
"sqrtf");
78 h = 2166136261u;
for (
int i = 0; i < N; i++) mix(bits(absf(val(i)))); report(
"fabsf");
79 kputs(
"fp-compare: PASS\n");
84 int result = test_main();
85 printf(
"[ps2rig] exit=%d\n", (result || rig_failed) ? 1 : 0);