diff options
Diffstat (limited to 'pu2/pu2.out.c')
| -rw-r--r-- | pu2/pu2.out.c | 137 |
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] |
