diff options
Diffstat (limited to 'pu2/pu2.out.c')
| -rw-r--r-- | pu2/pu2.out.c | 94 |
1 files changed, 67 insertions, 27 deletions
diff --git a/pu2/pu2.out.c b/pu2/pu2.out.c index 3091919..6922ccf 100644 --- a/pu2/pu2.out.c +++ b/pu2/pu2.out.c @@ -7,6 +7,7 @@ // - OLD_CLANG Use if your compiler version is not very up-to-date. // - SPEED_IMPROVEMENT Almost doubles clock rate for the VM with a few optimizations. // - EXTENDED_INSTRUCTION_SET Adds a few instructions which decrease token throughput for ir2. The high-level IR emitter will not work otherwise. + // - TIME_SLICE_SUPPORT Adds support for time slices, a way for the emulation layer to manage how long a pu2 program runs for. Only supported in the speed optimized version. // clang-format on /* -- BEGIN COMPILE TIME FLAGS -- */ @@ -17,6 +18,7 @@ // #define PU2_OLD_CLANG #define PU2_SPEED_IMPROVEMENT #define PU2_EXTENDED_INSTRUCTION_SET +#define PU2_TIME_SLICE_SUPPORT /* -- END COMPILE TIME FLAGS --*/ #ifdef PU2_NO_ASM @@ -25,6 +27,7 @@ #define _GNU_SOURCE #include <ctype.h> +#include <limits.h> #include <sched.h> #include <stdlib.h> #include <string.h> @@ -46,12 +49,16 @@ // #define A my_custom_cpu_error_trap() // ^ calls my_custom_cpu_error_trap() -#define S (1 << 24) +#define S (1 << 25) #define J while #define H !--c #ifndef PU2_SPEED_IMPROVEMENT + #ifdef PU2_TIME_SLICE_SUPPORT + #error Time slices are not supported in the basic, codegolfed versions. Please remove this flag before compilation. + #endif + #ifndef PU2_EXTENDED_INSTRUCTION_SET // clang-format off @@ -77,15 +84,6 @@ exit(1); \ }) -// pu2 optimized for speed implements a few new instructions for speed, -// and has a "bake" mode which will preprocess the memory and perform the required modifications. -// -// 14: nop -// 15: m[imm] = m[a] -// 16: a = m[imm] -// 17: m[a] = imm -// 18: m[a] = m[imm] - // not implemented yet, was lazy // bake(int start, int end) {} @@ -97,8 +95,7 @@ #define likely(JJ) (JJ) #endif -__attribute__((aligned(64))) int *m; -int a, b, u, c; +// __attribute__((aligned(64))) int *m; typedef struct { int c; int v; @@ -117,8 +114,9 @@ void set_affinity(int cpu) { } #endif -void init_pu2() { +int *init_pu2() { // set_affinity(0); + int *m; #ifndef PU2_NO_MMAP const int S_val = S * sizeof(int); @@ -135,15 +133,14 @@ void init_pu2() { 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` )", + " ( hint: enable hugepages in your kernel settings\n" + " `echo %i | sudo tee /proc/sys/vm/nr_hugepages` )", page_count); exit(1); } #else - m = malloc(S * sizeof(int)); - if(m == NULL) { + m = calloc(S, sizeof(int)); + if (m == NULL) { perror("[error] failed to allocate pu2 memory"); exit(1); } @@ -151,15 +148,34 @@ void init_pu2() { // size_t i; // for (i = 0; i < page_count; i++) ((char *) m)[ i * hugepage_size ] = 0; + + return m; } #define asm(...) __asm__(__VA_ARGS__) -void __attribute__((hot, aligned(64))) pu2() { - vminst *M2 = (vminst *) m; - vminst *M = &M2[ m[ 7 ] >> 1 ]; +__attribute__((hot, aligned(64))) + + #ifdef PU2_TIME_SLICE_SUPPORT +pu2(int __time_slice, int *m, int mem_size) + #else +pu2(int *m, int mem_size) + #endif +{ + #ifdef PU2_TIME_SLICE_SUPPORT +TIME_SLICE_AGAIN:; + int time_slice = __time_slice != -1 ?: INT_MAX; + #endif + + int a = 0, b = 0, c = 0, u = 0; - static int s1, s2, s3; + vminst *M2 = (vminst *) m; + vminst *M = &M2[ m[ 7 ] >> 1 ]; + vminst *M_END = M2 + mem_size; + + m[ 8 ] = mem_size; + + int s1 = 0, s2 = 0, s3 = 0; static const __attribute__((aligned(64))) void *PRECOMPUTED_TABLE[] = { &&PU2_END, &&C_ONE, &&C_TWO, &&C_THREE, &&C_FOUR, @@ -168,9 +184,18 @@ void __attribute__((hot, aligned(64))) pu2() { &&CB_FIFTEEN, &&CB_SIXTEEN, &&CB_SEVENTEEN, &&CB_EIGHTEEN, [32] = 0 }; static vminst inst __asm__("r21"); - while (1) { + #ifdef PU2_TIME_SLICE_SUPPORT + static int slice_i; + for (slice_i = 0; slice_i < time_slice; slice_i++) + #else + while (1) + #endif + + { PU2_START: + if (unlikely(M2 >= M_END)) return 0; inst = *M++; + // printf("running [%li] [%i] [%i]\n", M - M2, inst.c, inst.v); // if (unlikely(inst.c > 18)) A; #ifndef PU2_NO_INTRINSICS __builtin_prefetch(M + 1, 0, 3); @@ -246,9 +271,8 @@ void __attribute__((hot, aligned(64))) pu2() { goto PU2_START; CB_FIFTEEN: // if (unlikely(inst.v == 7)) M = M2 + (m[a] >> 1); - // if (unlikely(inst.v == a)) goto PU2_START; - m[ inst.v ] = m[ a ]; - // asm("mov %1, %0" : "=r"(m[inst.v]) : "r"(m[a])); + m[ inst.v ] = a; + // asm("mov %1, %0" : "=r"(m[inst.v]) : "r"(a)); goto PU2_START; CB_SIXTEEN: // asm("mov %1, %0" : "=r"(a) : "r"(m[inst.v])); @@ -267,8 +291,17 @@ void __attribute__((hot, aligned(64))) pu2() { goto PU2_START; } + #ifdef PU2_TIME_SLICE_SUPPORT + // this is when time slice ends + if (__time_slice == -1) goto TIME_SLICE_AGAIN; + #endif + PU2_END: + // normal halt m[ 7 ] = (M - M2) << 1; + + // return remaining time + return __time_slice - slice_i; } #endif @@ -289,6 +322,13 @@ PU2_END: // 11 U2A: a = u // 12 B2U: u = b // 13 U2B: b = u +// pu2 optimized for speed implements a few new instructions for speed, +// and has a "bake" mode which will preprocess the memory and perform the required modifications. +// 14 NOP: pc += imm +// 15 CB1: m[imm] = a +// 16 CB2: a = m[imm] +// 17 CB3: m[a] = imm +// 18 CB4: m[a] = m[imm] // NOTE: Memory indexes less than 1024 should be considered as temporary/compute memory, and // programs should be written at index 1024 and upwards. @@ -305,7 +345,7 @@ PU2_END: // therefore, i recommend you store a copy somewhere! // clang-format off -char*C="hltimmlodstrswpaddsubandnotacca2uu2ab2uu2bnopcb1cb2cb3",*Y[1<<10],*E,*L,i;*K;as2(char*I){J(c=*I++){if(c==35){J(*++I-10);c=*I++;}L=C;(!isspace(c)?c-39?c-125?c-123?c-64?({i=0,I--;J(i++,*L)strncmp(L,I,3)?L+=3:({I+=3;*K++=i-1;*K++=(i-2&&i-9)?0:strtol(I,&I,10);goto Q;});E=I;return 1;Q:;}):as2(Y[strtol(I,&I,10)]):({Y[strtol(I,&I,10)]=I+1;J(*I++-125);}):({break;}):({*K++=1;*K++=*I++;}):0);}} +char*C="hltimmlodstrswpaddsubandnotacca2uu2ab2uu2bnopcb1cb2cb3",*Y[1<<10],*E,*L;c,i;*K;as2(char*I){J(c=*I++){if(c==35){J(*++I-10);c=*I++;}L=C;(!isspace(c)?c-39?c-125?c-123?c-64?({i=0,I--;J(i++,*L)strncmp(L,I,3)?L+=3:({I+=3;*K++=i-1;*K++=(i-2&&i-9)?0:strtol(I,&I,10);goto Q;});E=I;return 1;Q:;}):as2(Y[strtol(I,&I,10)]):({Y[strtol(I,&I,10)]=I+1;J(*I++-125);}):({break;}):({*K++=1;*K++=*I++;}):0);}} // clang-format on // #undef S |
