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