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.c149
1 files changed, 142 insertions, 7 deletions
diff --git a/pu2/pu2.out.c b/pu2/pu2.out.c
index d6b2a5f..d168321 100644
--- a/pu2/pu2.out.c
+++ b/pu2/pu2.out.c
@@ -7,7 +7,6 @@
// pu2!
// maybe compacter? idk
-// last cpu: 167 chars
#define A 8
// change this for error reporting on unknown instructions!
@@ -17,15 +16,151 @@
// #define A my_custom_cpu_error_trap()
// ^ calls my_custom_cpu_error_trap()
-// clang-format off
-#define S 1<<28
+#define __PU2_SPEED_IMPROVEMENT
+#define __PU2_EXTENDED_INSTRUCTION_SET
+
+#define S (1 << 25)
#define J while
#define H !--c
-m[S],c,v,a,b,u;pu2(){J(c=m[m[7]++],v=m[m[7]++],c){H?a=v:H?a=m[b]:H?u?m[a]=b:0:H?v=a,a=b,b=v:H?a+=b:H?a-=b:H?a&=b:H?a=!a:H?u=v:H?u=a:H?a=u:H?u=b:H?b=u:A;}}
-// clang-format on
+
+#ifndef __PU2_SPEED_IMPROVEMENT
+
+ #ifndef __PU2_EXTENDED_INSTRUCTION_SET
+
+// clang-format off
+ m[S],c,v,a,b,u;pu2(){J(c=m[m[7]++],v=m[m[7]++],c){H?a=v:H?a=m[b]:H?u?m[a]=b:0:H?v=a,a=b,b=v:H?a+=b:H?a-=b:H?a&=b:H?a=!a:H?u=v:H?u=a:H?a=u:H?u=b:H?b=u:A;}}
+ // clang-format on
+
+ #else
+
+// clang-format off
+ m[S],c,v,a,b,u;pu2(){J(c=m[m[7]++],v=m[m[7]++],c){H?a=v:H?a=m[b]:H?u?m[a]=b:0:H?v=a,a=b,b=v:H?a+=b:H?a-=b:H?a&=b:H?a=!a:H?u=v:H?u=a:H?a=u:H?u=b:H?b=u:H?m[0]+=v*2:H?m[v]=m[a]:H?a=m[v]:H?m[a]=v:H?m[a]=m[v]:A;}}
+ // clang-format on
+
+ #endif
+
+#else
+
+ #include <stdio.h>
+
+ #undef A
+ #define A \
+ ({ \
+ printf("ERROR: Invalid instruction!\n"); \
+ 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) {}
+
+__attribute__((aligned(64))) m[ S ], a, b, u, c;
+typedef struct {
+ int c;
+ int v;
+} vminst;
+pu2() {
+ vminst *M = (vminst *) m;
+
+ int s1, s2, s3;
+
+ 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;
+
+ goto *PRECOMPUTED_TABLE[ inst.c ];
+
+ C_ZERO:
+ break;
+ C_ONE:
+ a = inst.v;
+ continue;
+ C_TWO:
+ a = m[ b ];
+ continue;
+ C_THREE:
+ if (u) {
+ if (__builtin_expect(a == 7, 0)) pc = b >> 1;
+ m[ a ] = b;
+ }
+
+ continue;
+ C_FOUR:
+ s1 = a;
+ a = b;
+ b = s1;
+
+ continue;
+ C_FIVE:
+ a += b;
+ continue;
+ C_SIX:
+ a -= b;
+ continue;
+ C_SEVEN:
+ a = !a;
+ continue;
+ C_EIGHT:
+ u = inst.v;
+ continue;
+ C_NINE:
+ u = inst.v;
+ continue;
+ C_TEN:
+ u = a;
+ continue;
+ C_ELEVEN:
+ a = u;
+ continue;
+ C_TWELVE:
+ u = b;
+ continue;
+ C_THIRTEEN:
+ b = u;
+ continue;
+ CB_FOURTEEN: // nop
+ // this instruction allows for essentially embedding data inside a program, as pu2 will skip
+ // right over it
+ pc += inst.v;
+ continue;
+ CB_FIFTEEN:
+ if (__builtin_expect(inst.v == 7, 0)) pc = m[ a ] >> 1;
+ m[ inst.v ] = m[ a ];
+ continue;
+ CB_SIXTEEN:
+ a = m[ inst.v ];
+ continue;
+ CB_SEVENTEEN:
+ if (__builtin_expect(a == 7, 0)) pc = inst.v >> 1;
+ m[ a ] = inst.v;
+ continue;
+ CB_EIGHTEEN:
+ if (__builtin_expect(a == 7, 0)) pc = m[ inst.v ] >> 1;
+ m[ a ] = m[ inst.v ];
+ continue;
+ }
+
+ m[ 7 ] = pc << 1;
+}
+
+#endif
// there's just memory. no, really
-// ok actually there's two registers called a and b
+// ok actually there's c_one registers called a and b
// 0 HLT: halt
// 1 IMM: a = imm
// 2 LOD: a = m[b]
@@ -56,7 +191,7 @@ m[S],c,v,a,b,u;pu2(){J(c=m[m[7]++],v=m[m[7]++],c){H?a=v:H?a=m[b]:H?u?m[a]=b:0:H?
// therefore, i recommend you store a copy somewhere!
// clang-format off
-char*C="hltimmlodstrswpaddsubandnotacca2uu2ab2uu2b",*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,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