aboutsummaryrefslogtreecommitdiff
path: root/pu2/pu2.out.c
diff options
context:
space:
mode:
authorGravatar Moon Flower <moon@coffin.ir> 2025-08-19 15:52:38 +0330
committerGravatar Moon Flower <moon@coffin.ir> 2025-08-19 15:52:38 +0330
commit0bd4c2925a32d384ea2c333b950115404b88c619 (patch)
treee5c447a5425869626473394010cc470b11b51451 /pu2/pu2.out.c
parentimproved pu2 (vm speed ~1GHz on 1.8GHz cpu), reduced code emission, added ano... (diff)
the speedster
Diffstat (limited to 'pu2/pu2.out.c')
-rw-r--r--pu2/pu2.out.c137
1 files changed, 87 insertions, 50 deletions
diff --git a/pu2/pu2.out.c b/pu2/pu2.out.c
index d168321..3f165de 100644
--- a/pu2/pu2.out.c
+++ b/pu2/pu2.out.c
@@ -1,6 +1,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#pragma clang diagnostic ignored "-Wparentheses"
#pragma clang diagnostic ignored "-Wreturn-type"
#pragma clang diagnostic ignored "-Wempty-body"
@@ -19,7 +20,7 @@
#define __PU2_SPEED_IMPROVEMENT
#define __PU2_EXTENDED_INSTRUCTION_SET
-#define S (1 << 25)
+#define S (1 << 26)
#define J while
#define H !--c
@@ -62,105 +63,141 @@
// not implemented yet, was lazy
// bake(int start, int end) {}
-__attribute__((aligned(64))) m[ S ], a, b, u, c;
+ #define unlikely(JJ) __builtin_expect((JJ), 0)
+ #define likely(JJ) __builtin_expect((JJ), 1)
+
+__attribute__((aligned(64))) * m, a, b, u, c;
typedef struct {
int c;
int v;
} vminst;
-pu2() {
- vminst *M = (vminst *) m;
- int s1, s2, s3;
+const int hugepage_size = 2 * 1024 * 1024;
+
+init_pu2() {
+ const int S_val = S * sizeof(int);
+ const int page_count = (S_val / hugepage_size) + 1;
+ const int page_size = page_count * hugepage_size;
+ m = mmap(
+ NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
+ if (m == MAP_FAILED) {
+ perror("[warn] couldn't allocate pu2 memory");
+ printf(
+ " ( hint: enable hugepages in your kernel settings\n `echo %i | "
+ "sudo "
+ "tee /proc/sys/vm/nr_hugepages` )",
+ page_count);
+ exit(1);
+ }
+
+ size_t i;
+ for (i = 0; i < 64; i++) ((char *) m)[ i * hugepage_size ] = 0;
+}
+
+ #define asm(...) __asm__(__VA_ARGS__)
+
+__attribute__((hot, aligned(64))) pu2() {
+ vminst *M2 = (vminst *) m;
+ vminst *M = &M2[ m[ 7 ] >> 1 ];
- const __attribute__((aligned(64))) void *PRECOMPUTED_TABLE[]
- = { &&C_ZERO, &&C_ONE, &&C_TWO, &&C_THREE, &&C_FOUR,
- &&C_FIVE, &&C_SIX, &&C_SEVEN, &&C_EIGHT, &&C_NINE,
- &&C_TEN, &&C_ELEVEN, &&C_TWELVE, &&C_THIRTEEN, &&CB_FOURTEEN,
- &&CB_FIFTEEN, &&CB_SIXTEEN, &&CB_SEVENTEEN, &&CB_EIGHTEEN };
- int pc = m[ 7 ] >> 1;
- register vminst inst;
- J(inst = M[ pc++ ], inst.c) {
- if (__builtin_expect(inst.c > 18, 0)) A;
+ static int s1, s2, s3;
+ static const __attribute__((aligned(64))) void *PRECOMPUTED_TABLE[]
+ = { &&C_ZERO, &&C_ONE, &&C_TWO, &&C_THREE, &&C_FOUR,
+ &&C_FIVE, &&C_SIX, &&C_SEVEN, &&C_EIGHT, &&C_NINE,
+ &&C_TEN, &&C_ELEVEN, &&C_TWELVE, &&C_THIRTEEN, &&CB_FOURTEEN,
+ &&CB_FIFTEEN, &&CB_SIXTEEN, &&CB_SEVENTEEN, &&CB_EIGHTEEN, [32] = 0 };
+ static vminst inst __asm__("r21");
+
+ while (1) {
+ PU2_START:
+ inst = *M++;
+ // if (unlikely(inst.c > 18)) A;
+ __builtin_prefetch(M + 1, 0, 3);
goto *PRECOMPUTED_TABLE[ inst.c ];
C_ZERO:
- break;
+ goto PU2_END;
C_ONE:
- a = inst.v;
- continue;
+ asm("mov %1, %0" : "=r"(a) : "r"(inst.v));
+ goto PU2_START;
C_TWO:
- a = m[ b ];
- continue;
+ asm("mov %1, %0" : "=r"(a) : "r"(m[b]));
+ goto PU2_START;
C_THREE:
- if (u) {
- if (__builtin_expect(a == 7, 0)) pc = b >> 1;
+ if (likely(u)) {
+ if (unlikely(a == 7)) M = M2 + (b >> 1);
m[ a ] = b;
}
- continue;
+ goto PU2_START;
C_FOUR:
- s1 = a;
- a = b;
- b = s1;
-
- continue;
+ asm("xchg %0, %1" : "+r"(a), "+r"(b));
+ goto PU2_START;
C_FIVE:
a += b;
- continue;
+ goto PU2_START;
C_SIX:
a -= b;
- continue;
+ goto PU2_START;
C_SEVEN:
- a = !a;
- continue;
+ a &= b;
+ goto PU2_START;
C_EIGHT:
- u = inst.v;
- continue;
+ a = !a;
+ goto PU2_START;
C_NINE:
u = inst.v;
- continue;
+ goto PU2_START;
C_TEN:
u = a;
- continue;
+ goto PU2_START;
C_ELEVEN:
a = u;
- continue;
+ goto PU2_START;
C_TWELVE:
u = b;
- continue;
+ goto PU2_START;
C_THIRTEEN:
b = u;
- continue;
- CB_FOURTEEN: // nop
+ goto PU2_START;
+ CB_FOURTEEN:
+ // nop
// this instruction allows for essentially embedding data inside a program, as pu2 will skip
// right over it
- pc += inst.v;
- continue;
+ M += inst.v;
+ goto PU2_START;
CB_FIFTEEN:
- if (__builtin_expect(inst.v == 7, 0)) pc = m[ a ] >> 1;
+ // if (unlikely(inst.v == 7)) pc = m[ a ] >> 1;
+ if (unlikely(inst.v == a)) goto PU2_START;
m[ inst.v ] = m[ a ];
- continue;
+ // asm("mov %1, %0" : "=r"(m[inst.v]) : "r"(m[a]));
+ goto PU2_START;
CB_SIXTEEN:
+ // asm("mov %1, %0" : "=r"(a) : "r"(m[inst.v]));
a = m[ inst.v ];
- continue;
+ goto PU2_START;
CB_SEVENTEEN:
- if (__builtin_expect(a == 7, 0)) pc = inst.v >> 1;
+ // if (unlikely(a == 7)) pc = inst.v >> 1;
+ // asm("mov %1, %0" : "=r"(m[a]) : "r"(inst.v));
m[ a ] = inst.v;
- continue;
+ goto PU2_START;
CB_EIGHTEEN:
- if (__builtin_expect(a == 7, 0)) pc = m[ inst.v ] >> 1;
+ // if (unlikely(a == 7)) pc = m[ inst.v ] >> 1;
+ if (unlikely(inst.v == a)) goto PU2_START;
m[ a ] = m[ inst.v ];
- continue;
+ // asm("mov %1, %0" : "=r"(m[a]) : "r"(m[inst.v]));
+ goto PU2_START;
}
- m[ 7 ] = pc << 1;
+PU2_END:
+ m[ 7 ] = (M - M2) << 1;
}
#endif
// there's just memory. no, really
-// ok actually there's c_one registers called a and b
+// ok actually there's two registers called a and b
// 0 HLT: halt
// 1 IMM: a = imm
// 2 LOD: a = m[b]