diff options
Diffstat (limited to 'pu2')
| -rw-r--r-- | pu2/code.i2 | 17 | ||||
| -rw-r--r-- | pu2/pu2.c | 123 | ||||
| -rw-r--r-- | pu2/pu2.out.c | 7 |
3 files changed, 123 insertions, 24 deletions
diff --git a/pu2/code.i2 b/pu2/code.i2 index 06d1c54..22ab74f 100644 --- a/pu2/code.i2 +++ b/pu2/code.i2 @@ -1,3 +1,5 @@ + + /* testing grounds for the ir2 assembler @@ -21,17 +23,14 @@ macro putchar(1) { system(); } -@10 = 0; +@90 = 5; -// if statement!! -if (@10) { - puts(["hi"], [2]); -} +while (@90) { + @90--; -putchar([10]); -puts([" hello world"], [15]); -putchar([10]); -putchar([10]); + puts(["hello"], [5]); + putchar([10]); +} exit(0); @@ -310,6 +310,7 @@ int ir2_depth = 0; bool has_jump_warned = false; bool has_useless_if_warned = false; +bool has_false_while_warned = false; string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label_delegated_t forward_refs[ 1 << 10 ]) { char T; @@ -366,7 +367,11 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label swap(); mem_in_a(mem_index); op(sub); + swap(); + imm(mem_index); store(); + + continue; } if(*I == '+' && I[1] == '+') { // increment @@ -377,7 +382,11 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label swap(); mem_in_a(mem_index); op(add); + swap(); + imm(mem_index); store(); + + continue; } char extra_op = '='; @@ -406,7 +415,7 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label } else if (extra_op == '&') { perform_op(and); } else if (extra_op == '!') { - // @1 != @2; + // @1 != @2; (@1 = !@2) mem_in_a(mem2_index); op(not); swap(); @@ -431,20 +440,20 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label swap(); mem_in_a(mem_index); op(sub); + swap(); + imm(mem_index); store(); } else if (extra_op == '&') { imm(imm); swap(); mem_in_a(mem_index); op(and); - store(); - } else if (extra_op == '!') { - // @1 != 5; - imm(imm); - op(not); swap(); imm(mem_index); store(); + } else if (extra_op == '!') { + // @1 != 5; (@1 = !5;) + imm_in_mem(mem_index, !imm); } } @@ -721,22 +730,23 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label int *Code_B = Code; int *Data_B = Data; + // completely eliminate code generated in useless if statement + int m2[S/4]; + Data = Code = m2; + // get new I location string new_I = _ir2(I, macros, labels, forward_refs); I = new_I; // restore values Code = Code_B; Data = Data_B; - - continue; - } - - else { + } else { // just... i mean, i guess run the code..? string new_I = _ir2(I, macros, labels, forward_refs); I = new_I; - continue; } + + continue; } bool was_negated = false; @@ -769,6 +779,95 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label continue; } + else if (strncmp("while", I, 5) == 0 && !isalnum(I[5])) { + I += 5; + space; checkskip('(', "expected open paren for while loop"); space; + ir2_depth++; + + if (isdigit(*I)) { + int value = strtol(I, &I, 10); space; + + checkskip(')', "expected closing paren after while loop argument"); space; + checkskip('{', "expected opening bracket for while loop body"); space; + + if (!value) { + // non-running while loop + + if(!has_false_while_warned) { + has_false_while_warned = true; + printf("warn: dead code inside while loop\n"); + } + + // just skip over everything inside + + int *Code_B = Code; + int *Data_B = Data; + + // completely eliminate code generated in useless while loop + int m2[S/4]; + Data = Code = m2; + + // get new I location + string new_I = _ir2(I, macros, labels, forward_refs); + I = new_I; + // restore values + Code = Code_B; + Data = Data_B; + } else { + // run forever! + + int start = Code - m; + + string new_I = _ir2(I, macros, labels, forward_refs); + I = new_I; + + imm_in_mem(7, start); // always jump back to the start + } + + continue; + } + + bool was_negated = false; + if (*I == '!') { + was_negated = true; + I++; space; + } + + checkskip('@', "expected memory address for while loop expression (hint: only simple conditions are supported)"); + if (!isdigit(*I)) run_err(I, "expected memory index"); + int mem_index = strtol(I, &I, 10); space; + checkskip(')', "expected closing paren after while loop condition"); space; + checkskip('{', "expected opening bracket for while loop body"); space; + + mem_in_a(mem_index); + if (!was_negated) op(not); + op(a2u); + imm(0xDEAD10C4); // DEADLOCK - placeholder for the patchback + int* patchback = Code - 1; + swap(); + imm(7); + op(str); + + int start_index = Code - m; + + // handle the code stuff + string new_I = _ir2(I, macros, labels, forward_refs); + I = new_I; + + *patchback = Code - m; // patch the jump instruction + + // check the condition and jump back if true + mem_in_a(mem_index); + if (was_negated) op(not); + op(a2u); + imm(start_index); + swap(); + imm(7); + op(str); + + continue; + } + // macro call, maybe? else if (isalpha(*I)) { string old_I = I; diff --git a/pu2/pu2.out.c b/pu2/pu2.out.c index f35a7ab..8bc9f52 100644 --- a/pu2/pu2.out.c +++ b/pu2/pu2.out.c @@ -153,7 +153,7 @@ void __attribute__((hot, aligned(64))) pu2() { static int s1, s2, s3; static const __attribute__((aligned(64))) void *PRECOMPUTED_TABLE[] - = { &&C_ZERO, &&C_ONE, &&C_TWO, &&C_THREE, &&C_FOUR, + = { &&PU2_END, &&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 }; @@ -166,8 +166,8 @@ void __attribute__((hot, aligned(64))) pu2() { __builtin_prefetch(M + 1, 0, 3); goto *PRECOMPUTED_TABLE[ inst.c ]; - C_ZERO: - goto PU2_END; +// C_ZERO: +// goto PU2_END; C_ONE: #ifndef PU2_NO_ASM asm("mov %1, %0" : "=r"(a) : "r"(inst.v)); @@ -183,6 +183,7 @@ void __attribute__((hot, aligned(64))) pu2() { #endif goto PU2_START; C_THREE: + // if (unlikely(a == 7)) printf("conditional jmp %i (%i) [a=%i b=%i u=%i]\n", M - M2, u, a, b, u); if (likely(u)) { if (unlikely(a == 7)) M = M2 + (b >> 1); m[ a ] = b; |
