sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
main.c
1#include <stdio.h>
2#include <string.h>
3#include <kernel.h>
4
5#include <math.h>
6#include <stdint.h>
7#include <string.h>
8
9extern int kputs(char *s);
10
11/* A program must never return from main on the rig: that reboots the console. */
12static int rig_failed;
13static int rig_kputs(char *s) {
14 if (strstr(s, ": FAIL")) rig_failed = 1;
15 printf("%s", s);
16 return kputs(s);
17}
18#define kputs rig_kputs
19
20#define NOINL __attribute__((noinline))
21
22/* Includes NaN, infinities, signed zeros, denormals and extremes on purpose: the R5900 FPU has no NaN or
23 infinity, so what each comparison returns for them is whatever the instruction sequence does. */
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])))
29
30static uint32_t h;
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; }
34
35static void hex8(uint32_t v, char *o) {
36 for (int i = 7; i >= 0; i--) { o[i] = "0123456789abcdef"[v & 15]; v >>= 4; }
37 o[8] = 0;
38}
39static void report(const char *name) {
40 char line[64];
41 int n = 0;
42 while (name[n] && n < 40) { line[n] = name[n]; n++; }
43 line[n++] = ' ';
44 hex8(h, line + n);
45 n += 8;
46 line[n++] = '\n';
47 line[n] = 0;
48 kputs(line);
49}
50
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); }
66
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)
69
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);
74 h = 2166136261u;
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))));
76 report("clamp");
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");
80 return 0;
81}
82
83int main(void) {
84 int result = test_main();
85 printf("[ps2rig] exit=%d\n", (result || rig_failed) ? 1 : 0);
86 SleepThread();
87 return 0;
88}