aboutsummaryrefslogtreecommitdiff
path: root/pu2/pu2.out.c
diff options
context:
space:
mode:
Diffstat (limited to 'pu2/pu2.out.c')
-rw-r--r--pu2/pu2.out.c94
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