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 <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11extern int kputs(char *s);
12
13/* A program must never return from main on the rig: that reboots the console. */
14static int rig_failed;
15static int rig_kputs(char *s) {
16 if (strstr(s, ": FAIL")) rig_failed = 1;
17 printf("%s", s);
18 return kputs(s);
19}
20#define kputs rig_kputs
21#define NOINL __attribute__((noinline))
22
23static uint32_t h;
24static inline void mix(uint32_t v) { h = (h ^ v) * 16777619u; }
25static inline uint32_t bits(float f) { uint32_t u; memcpy(&u, &f, 4); return u; }
26static inline void mixd(double d) { uint64_t u; memcpy(&u, &d, 8); mix((uint32_t)u); mix((uint32_t)(u >> 32)); }
27static void hex8(uint32_t v, char *o) { for (int i = 7; i >= 0; i--) { o[i] = "0123456789abcdef"[v & 15]; v >>= 4; } o[8] = 0; }
28static void report(const char *name) {
29 char line[64]; int n = 0;
30 while (name[n] && n < 40) { line[n] = name[n]; n++; }
31 line[n++] = ' '; hex8(h, line + n); n += 8; line[n++] = '\n'; line[n] = 0; kputs(line);
32}
33#define START() (h = 2166136261u)
34
35static volatile uint32_t vbits[] = {
36 0x3f800000u, 0x40000000u, 0x3f000000u, 0x41200000u, 0x3dcccccdu, 0x3a83126fu, 0x42f6e979u, 0x461c4000u,
37 0x40490fdbu, 0x3fc90fdbu, 0x3f490fdbu, 0x3e99999au, 0x44fa0000u, 0x4b800000u, 0x3b03126fu, 0x41a00000u,
38 0x3f7fffffu, 0x40a00000u, 0x40e00000u, 0x42c80000u, 0x3f9e0419u, 0x3ea2f983u, 0x40135d8eu, 0x41c80000u};
39#define N ((int)(sizeof(vbits) / sizeof(vbits[0])))
40static float t[64];
41
42#define F1(NAME, EXPR) NOINL static float NAME(float x) { return EXPR; }
43F1(m_sinf, sinf(x)) F1(m_cosf, cosf(x)) F1(m_tanf, tanf(x)) F1(m_asinf, asinf(x / 100.0f))
44F1(m_acosf, acosf(x / 100.0f)) F1(m_atanf, atanf(x)) F1(m_expf, expf(x / 8.0f)) F1(m_logf, logf(x))
45F1(m_log10f, log10f(x)) F1(m_sqrtf, sqrtf(x)) F1(m_floorf, floorf(x * 1.3f)) F1(m_ceilf, ceilf(x * 1.3f))
46F1(m_roundf, roundf(x * 1.3f)) F1(m_truncf, truncf(x * 1.3f)) F1(m_fabsf, fabsf(-x)) F1(m_sinhf, sinhf(x / 8.0f))
47F1(m_coshf, coshf(x / 8.0f)) F1(m_tanhf, tanhf(x / 8.0f)) F1(m_cbrtf, cbrtf(x)) F1(m_exp2f, exp2f(x / 4.0f))
48F1(m_log2f, log2f(x))
49#define F2(NAME, EXPR) NOINL static float NAME(float x, float y) { return EXPR; }
50F2(m_powf, powf(x, y / 4.0f)) F2(m_atan2f, atan2f(x, y)) F2(m_fmodf, fmodf(x, y)) F2(m_hypotf, hypotf(x, y))
51F2(m_fmaxf, fmaxf(x, y)) F2(m_fminf, fminf(x, y)) F2(m_copysignf, copysignf(x, -y)) F2(m_remainderf, remainderf(x, y))
52#define D1(NAME, EXPR) NOINL static double NAME(double x) { return EXPR; }
53D1(d_sin, sin(x)) D1(d_cos, cos(x)) D1(d_sqrt, sqrt(x)) D1(d_exp, exp(x / 8.0)) D1(d_log, log(x)) D1(d_atan, atan(x))
54D1(d_floor, floor(x * 1.3)) D1(d_fabs, fabs(-x))
55NOINL static double d_add(double a, double b) { return a + b; }
56NOINL static double d_sub(double a, double b) { return a - b; }
57NOINL static double d_mul(double a, double b) { return a * b; }
58NOINL static double d_div(double a, double b) { return a / b; }
59NOINL static double d_pow(double a, double b) { return pow(a, b / 4.0); }
60NOINL static double f2d(float x) { return (double)x; }
61NOINL static float d2f(double x) { return (float)x; }
62NOINL static double i2d(int x) { return (double)x; }
63NOINL static int d2i(double x) { return (int)x; }
64NOINL static double u2d(unsigned x) { return (double)x; }
65NOINL static long long f2ll(float x) { return (long long)x; }
66NOINL static float ll2f(long long x) { return (float)x; }
67NOINL static unsigned f2u(float x) { return (unsigned)x; }
68NOINL static float u2f(unsigned x) { return (float)x; }
69
70static int test_main(void) {
71 for (int i = 0; i < N; i++) { uint32_t u = vbits[i]; memcpy(&t[i], &u, 4); }
72#define R1(K) do { START(); for (int i = 0; i < N; i++) mix(bits(K(t[i]))); report(#K); } while (0)
73#define R2(K) do { START(); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) mix(bits(K(t[i], t[j]))); report(#K); } while (0)
74#define RD1(K) do { START(); for (int i = 0; i < N; i++) mixd(K((double)t[i])); report(#K); } while (0)
75#define RD2(K) do { START(); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) mixd(K((double)t[i], (double)t[j])); report(#K); } while (0)
76 R1(m_sinf); R1(m_cosf); R1(m_tanf); R1(m_asinf); R1(m_acosf); R1(m_atanf); R1(m_expf); R1(m_logf);
77 R1(m_log10f); R1(m_sqrtf); R1(m_floorf); R1(m_ceilf); R1(m_roundf); R1(m_truncf); R1(m_fabsf);
78 R1(m_sinhf); R1(m_coshf); R1(m_tanhf); R1(m_cbrtf); R1(m_exp2f); R1(m_log2f);
79 R2(m_powf); R2(m_atan2f); R2(m_fmodf); R2(m_hypotf); R2(m_fmaxf); R2(m_fminf); R2(m_copysignf); R2(m_remainderf);
80 RD1(d_sin); RD1(d_cos); RD1(d_sqrt); RD1(d_exp); RD1(d_log); RD1(d_atan); RD1(d_floor); RD1(d_fabs);
81 RD2(d_add); RD2(d_sub); RD2(d_mul); RD2(d_div); RD2(d_pow);
82 START(); for (int i = 0; i < N; i++) mixd(f2d(t[i])); report("f2d");
83 START(); for (int i = 0; i < N; i++) mix(bits(d2f((double)t[i] * 1.0000001))); report("d2f");
84 START(); for (int i = -100; i < 100; i++) mixd(i2d(i * 123457)); report("i2d");
85 START(); for (int i = 0; i < N; i++) mix((uint32_t)d2i((double)t[i] * 1000.0)); report("d2i");
86 START(); for (unsigned i = 0; i < 100; i++) mixd(u2d(i * 40000001u)); report("u2d");
87 START(); for (int i = 0; i < N; i++) { long long v = f2ll(t[i] * 100000.0f); mix((uint32_t)v); mix((uint32_t)(v >> 32)); } report("f2ll");
88 START(); for (int i = -50; i < 50; i++) mix(bits(ll2f((long long)i * 1234567891LL))); report("ll2f");
89 START(); for (int i = 0; i < N; i++) mix(f2u(t[i] * 3.0f)); report("f2u");
90 START(); for (unsigned i = 0; i < 100; i++) mix(bits(u2f(i * 40000001u))); report("u2f");
91
92 /* formatted output and parsing */
93 {
94 char buf[96];
95 START();
96 for (int i = 0; i < N; i++) {
97 int n = snprintf(buf, sizeof buf, "%f %.3f %e %g", (double)t[i], (double)t[i], (double)t[i], (double)t[i]);
98 for (int k = 0; k < n; k++) mix((uint32_t)buf[k]);
99 }
100 report("snprintf_f");
101 START();
102 for (int i = 0; i < N; i++) {
103 int n = snprintf(buf, sizeof buf, "%d %u %x %5.2f %s %c %ld", i * -7, i * 90000u, i * 77, (double)t[i], "str", 'a' + i % 20, (long)i * 100000L);
104 for (int k = 0; k < n; k++) mix((uint32_t)buf[k]);
105 }
106 report("snprintf_i");
107 START();
108 {
109 static const char *strs[] = {"1.5", "0.1", "3.14159", "1e10", "123456.789", "-2.5e-3", "100", "0.333333333", "65504", "1e-5", "2.718281828", "17"};
110 for (int i = 0; i < 12; i++) { mix(bits(strtof(strs[i], NULL))); mixd(strtod(strs[i], NULL)); mix((uint32_t)atoi(strs[i])); }
111 }
112 report("strto");
113 }
114 {
115 START();
116 srand(12345);
117 for (int i = 0; i < 100; i++) mix((uint32_t)rand());
118 report("rand");
119 START();
120 for (int i = 0; i < 64; i++) mix((uint32_t)abs((int)(i * 1000003u) - 30000000));
121 report("abs");
122 }
123 kputs("fpdiff: PASS\n");
124 return 0;
125}
126
127int main(void) {
128 int result = test_main();
129 printf("[ps2rig] exit=%d\n", (result || rig_failed) ? 1 : 0);
130 SleepThread();
131 return 0;
132}