aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Moon Flower <moon@coffin.ir> 2025-08-18 11:59:33 +0330
committerGravatar Moon Flower <moon@coffin.ir> 2025-08-18 11:59:33 +0330
commit450ced09c93ecb9c1c2c4c97fe2dde29439dac8f (patch)
tree5fef31b7d27b0d21373956245f444fb2d7050c3d
parenti cant stop making cpus... here's a parallelized one (diff)
ppu isn't useful. i'll just go back to pu2
-rw-r--r--ppu/code.p2p1
-rwxr-xr-xppu/ppubin0 -> 17464 bytes
-rw-r--r--ppu/ppu.c155
3 files changed, 137 insertions, 19 deletions
diff --git a/ppu/code.p2p b/ppu/code.p2p
new file mode 100644
index 0000000..596ca02
--- /dev/null
+++ b/ppu/code.p2p
@@ -0,0 +1 @@
+@1048566 movi 1 1 \ No newline at end of file
diff --git a/ppu/ppu b/ppu/ppu
new file mode 100755
index 0000000..addbcf2
--- /dev/null
+++ b/ppu/ppu
Binary files differ
diff --git a/ppu/ppu.c b/ppu/ppu.c
index 9b4fc5a..0111d97 100644
--- a/ppu/ppu.c
+++ b/ppu/ppu.c
@@ -1,13 +1,16 @@
+// c89 doesnt support inline, so we get rid of it
#define inline
#include <ctype.h>
+#include <limits.h>
#include <omp.h>
#include <stdio.h>
#include <string.h>
+#include <time.h>
#pragma clang diagnostic ignored "-Wreturn-type"
-typedef char* string;
+typedef char *string;
// opcodes!
// 0: halt
@@ -22,36 +25,150 @@ typedef char* string;
// program counter is m[0]
// Q is set to the previous A in memory
+#define S 1 << 22
+m[ S ] = { 0 }, c, N, Q, E;
+
+// comment to disable cpu batch counter which guesses how many branches to run
+#define __PPU_BATCH_COUNTER
+
+#ifdef __PPU_BATCH_COUNTER
+ #define BC (N = run_batch_counter())
+#else
+ #define BC ({})
+#endif
+
+#define MAX_BATCH_COUNT 16
+
+run_batch_counter() {
+ int max_value = MAX_BATCH_COUNT;
+ int bcup_c = 0, i_count, j_count;
+ int bcupt[ MAX_BATCH_COUNT ];
+ int *M = m;
+ // effects table
+ static const string effW = "001111111";
+ static const string effR = "001010101";
+
+ for (i_count = 0; i_count < MAX_BATCH_COUNT; i_count++) {
+ if (i_count > max_value) break;
+
+ int num = c + (i_count << 2);
+ int __N = M[ num++ ];
+ int __O = M[ num++ ];
+ int __A = M[ num++ ];
+ int __B = M[ num++ ];
+
+ if (__N != 0) {
+ max_value = i_count + __N;
+ break;
+ }
+ if (__O == 0) {
+ max_value = i_count;
+ break;
+ }
+ if (__O >= 9) {
+ max_value = i_count - 1;
+ break;
+ }
+
+ char w = effW[ __O ] - 48;
+ char r = effR[ __O ] - 48;
+
+ for (j_count = 0; j_count < bcup_c; j_count++) {
+ int prev = bcupt[ j_count ];
+ if ((prev == __A && w) || (prev == __B && r)) {
+ max_value = i_count - 1;
+ goto END;
+ }
+ }
+
+ if (w) bcupt[ bcup_c++ ] = __A;
+ }
+
+END:
+ return max_value;
+}
+
// error handling for unknown ops
#define W 0
-// clang-format off
#define J while
-#define S 1<<20
#define H !K--
-m[S]={0},c,N,Q,E;
-ppu(){E=1;_Pragma("omp parallel")J(E){_Pragma("omp single")N=m[m[0]],c=m[0],m[0]+=++N*4;int i;_Pragma("omp for")for(i=0;i<N;i++){int t=c+i*4,Y=m[t++],K=m[t++],A=m[t++],B=m[t++];H?E=0:H?:H?m[A]=m[B]:H?m[A]=B:H?m[A]+=m[B]:H?m[A]+=m[B]:H?m[A]-=m[B]?H:m[Q]?:(m[A]=m[B]):W;Q=A;}}}
+ppu() {
+ E = 1;
+ J(E) {
+ _Pragma("omp single") N = m[ m[ 0 ] ], c = m[ 0 ], N ?: BC, m[ 0 ] += ++N * 4;
+ int i;
+ _Pragma("omp for") for (i = 0; i < N; i++) {
+ int t = c + i * 4, Y = m[ t++ ], K = m[ t++ ], A = m[ t++ ], B = m[ t++ ];
+ H?E=0:H?:H?m[A]=m[B]:H?m[A]=B:H?m[A]+=m[B]:H?m[A]+=m[B]:H?m[A]-=m[B]?H:m[Q]?:(m[A]=m[B]):W;
+ Q = A;
+ }
+ }
+}
+// clang-format off
#define X J(isspace(*I))I++
char*t="halt\0\0nop\0\0mov\0\2movi\0\2add\0\2addi\0\2sub\0\2subi\0\2moveq\0\2\1";*D,Z;
char*pas(char*I){J(*I){X;if(*I==64)Z=strtol(++I,&I,10);X;char*O=t,F=0;J(*O!=1){int G=strlen(O),L=O[G+1],V=L,B=strncmp(I,O,G);F++,O+=G+2;if(B||!isspace(I[G]))continue;I+=G;*D++=Z,Z=0;*D++=F-1;J(V--){X;*D++=strtol(I,&I,10);}J(2-L++)*D++=0;goto N;}return I;N:;}return 0;}
// clang-format on
+string read_file(string path, size_t *out_size) {
+ FILE *f = fopen(path, "rb");
+ string buf;
+ size_t size;
+ if (!f) return NULL;
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ buf = malloc(size + 1);
+ if (!buf) {
+ fclose(f);
+ return NULL;
+ }
+ if (fread(buf, 1, size, f) != size) {
+ free(buf);
+ fclose(f);
+ return NULL;
+ }
+ buf[ size ] = '\0';
+ fclose(f);
+ if (out_size) *out_size = size;
+ return buf;
+}
+
+unsigned long long rdtsc(void) {
+ unsigned hi, lo;
+ __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
+ return ((unsigned long long) hi << 32) | lo;
+}
+
main() {
- D = &m[ 1 ];
- pas("@4 movi 10 2");
+ D = &m[ 1000 ];
+ m[ 0 ] = 1000;
+ size_t o_size;
+ string output = read_file("code.p2p", &o_size);
+ pas(output);
+ free(output);
// int C;
- // for (C = 0; C < 16; C++) printf("%i ", m[ C + 1 ]);
- // fflush(stdout);
-
- int x[] = { 1,
- 3, 3, 5, 1,
- 0, 3, 5, 2,
- 0, 3, 5, 3,
- 0, 3, 5, 4,
- 0, 0, 0, 0 };
- memcpy(m, x, sizeof(x));
- ppu();
- printf("result: %i\n", m[ 5 ]);
+ // for (C = 0; C < 16; C++) printf("%i ", m[ 1000 + C ]);
+ // putchar('\n');
+
+ // int x[] = { 1, 3, 3, 5, 1, 0, 3, 5, 2, 0, 3, 5, 3, 0, 3, 5, 4, 0, 0, 0, 0 };
+ // memcpy(m, x, sizeof(x));
+
+ _Pragma("omp parallel") {
+ _Pragma("omp single") {
+ clock_t start = clock();
+ ppu();
+ clock_t end = clock();
+
+ double seconds = (double) (end - start) / CLOCKS_PER_SEC;
+ printf("time: %.6fs, insts: %i\n", seconds, m[ 0 ] / 4);
+ double insts_per_sec = ((double) m[ 0 ] / 4) / seconds;
+ printf("ran at %f million instructions/second\n", insts_per_sec / 1e6);
+ }
+ }
+
+ printf("result: %i\n\n", m[ 1 ]);
} \ No newline at end of file