diff options
| author | 2025-08-14 12:02:50 +0330 | |
|---|---|---|
| committer | 2025-08-14 12:02:50 +0330 | |
| commit | 9e7d03382cfcf6cc10fdb6b4a16b7056a9ce6a25 (patch) | |
| tree | c16e4085a2132590068cdc06bb3d5d0e74529e9d /pu2/pu2.c | |
| parent | arithmetics unit in emu (diff) | |
benchmark + operations + extra stufferinos
Diffstat (limited to 'pu2/pu2.c')
| -rw-r--r-- | pu2/pu2.c | 165 |
1 files changed, 152 insertions, 13 deletions
@@ -1,5 +1,6 @@ #include "pu2.out.c" #include <stdio.h> +#include <time.h> typedef char *string; @@ -66,6 +67,17 @@ error_debug(string fail_point, string code, int sz) { fprintf(stderr, "\x1b[1m\x1b[31m^\x1b[0m \x1b[90mparsing stopped here\x1b[0m\n"); } +long powi(long x, unsigned n) { + long p = x, r = 1; + + while (n > 0) { + if (n & 1) r *= p; + p *= p, n /= 2; + } + + return r; +} + emu() { while (1) { pu2(); @@ -112,6 +124,10 @@ emu() { } else if (op == 4) { // right shift m[ 3 ] = val1 >> val2; + } else if (op == 5) { + // pow + if (val1 == 2) m[ 3 ] = val1 << val2; + else { m[ 3 ] = powi(val1, val2); } } else { @@ -135,9 +151,9 @@ skip_space(string *I) { // IR parser for pu2's as2 // clang-format off struct { - int hlt; int imm; int lod; int str; int swp; int add; int sub; int and; int not; int acc; + int hlt, imm, lod, str, swp, add, sub, and, not, acc, a2u, u2a, b2u, u2b; } opcode = { - 0, 1, 2, 3, 4, 5, 6, 7, 8,9 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; // clang-format on @@ -235,6 +251,45 @@ clean_slice_ref(slice *val) { free(val->ref); } value; \ }) +#define op(mode) emit(opcode.mode, 0) +#define swap() emit(opcode.swp, 0) +#define imm(value) emit(opcode.imm, value) +#define load() emit(opcode.lod, 0) +#define imm_in_mem(__mem, __imm) \ + ({ \ + imm(__imm); \ + swap(); \ + imm(__mem); \ + store(); \ + }) +#define mov_mem_mem(__mem1, __mem2) \ + ({ \ + imm(__mem2); \ + swap(); \ + load(); \ + swap(); \ + imm(__mem1); \ + store(); \ + }) +#define mem_in_a(__mem) \ + ({ \ + op(b2u); \ + imm(__mem); \ + swap(); \ + load(); \ + op(u2b); \ + }) +#define perform_op(operation) \ + ({ \ + mem_in_a(mem2_index); \ + swap(); \ + mem_in_a(mem_index); \ + emit(opcode.operation, 0); \ + swap(); \ + imm(mem_index); \ + store(); \ + }) + char T; string ERR; string ERR_code; @@ -257,7 +312,9 @@ _ir2(string I, entry macros[ 1 << 9 ]) { I++; int mem_index = strtol(I, &I, 10); skip_space(&I); - checkskip('=', "expected assigment after memory blob"); + char extra_op = '='; + if (*I == '+' || *I == '-' || *I == '&' || *I == '!') extra_op = *I++; + checkskip('=', "expected assigment after memory blob (hint: only +-&! are supported)"); skip_space(&I); if (*I == '@') { @@ -269,19 +326,53 @@ _ir2(string I, entry macros[ 1 << 9 ]) { int mem2_index = strtol(I, &I, 10); - emit(opcode.imm, mem2_index); - emit(opcode.swp, 0); - emit(opcode.lod, 0); - emit(opcode.swp, 0); - emit(opcode.imm, mem_index); - store(); + if (extra_op == '=') { + mov_mem_mem(mem_index, mem2_index); + } else if (extra_op == '+') { + perform_op(add); + } else if (extra_op == '-') { + perform_op(sub); + } else if (extra_op == '&') { + perform_op(and); + } else if (extra_op == '!') { + // @1 != @2; + mem_in_a(mem2_index); + emit(opcode.not, 0); + swap(); + imm(mem_index); + store(); + } } else { int imm = scanvalue(); - emit(opcode.imm, imm); - emit(opcode.swp, 0); - emit(opcode.imm, mem_index); - store(); + if (extra_op == '=') { + imm_in_mem(mem_index, imm); + } else if (extra_op == '+') { + imm(imm); + swap(); + mem_in_a(mem_index); + emit(opcode.add, 0); + store(); + } else if (extra_op == '-') { + imm(imm); + swap(); + mem_in_a(mem_index); + emit(opcode.sub, 0); + store(); + } else if (extra_op == '&') { + imm(imm); + swap(); + mem_in_a(mem_index); + emit(opcode.and, 0); + store(); + } else if (extra_op == '!') { + // @1 != 5; + imm(imm); + emit(opcode.not, 0); + swap(); + imm(mem_index); + store(); + } } skip_space(&I); @@ -528,6 +619,53 @@ ir2(string I) { string op_names[] = { "hlt", "imm", "lod", "str", "swp", "add", "sub", "and", "not", "acc" }; +unsigned long long rdtsc(void) { + unsigned hi, lo; + __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi)); + return ((unsigned long long) hi << 32) | lo; +} + +double bench_cycle(int instr) { + int i; + for (i = 0; i < S - 2; i += 2) { + m[ i ] = instr; + m[ i + 1 ] = 5; + } + m[ S - 2 ] = 0; + m[ S - 1 ] = 0; + + m[ 7 ] = 0; + c = 0; + + clock_t start = clock(); + pu2(); + clock_t end = clock(); + + double seconds = (double) (end - start) / CLOCKS_PER_SEC; + printf("time: %.6f s\n", seconds); + return (double) m[ 7 ] / seconds / 1e6; +} + +benchmark() { + double results[ 13 ]; + double sum = 0; + for (i = 0; i < 13; i++) { + results[ i ] = bench_cycle(i); + sum += results[ i ]; + } + sum /= 13; + + unsigned long long start, end; + start = rdtsc(); + sleep(1); + end = rdtsc(); + + float clock_speed = (end - start) / 1e6; + printf("clock speed ~ %.6f MHz\n", clock_speed); + printf("results sum: %f\n", sum); + printf("instructions per cycle: %f\n", clock_speed / sum); +} + main() { size_t o_size; ir2(read_file("code.i2", &o_size)); @@ -552,6 +690,7 @@ main() { // printf("\n\n"); emu(); + printf("result: %i\n", m[ 10 ]); } main2(int argc, char **argv) { |
