From e82c73d2b57e58894d8c93fc720559df6392d58b Mon Sep 17 00:00:00 2001 From: Kimplul Date: Tue, 4 Jul 2023 23:37:51 +0300 Subject: add loop example --- bcgen | 4 ++++ bcode.c | 29 +++++++++++++++++++++++++---- bcode.h | 3 +++ example/Makefile | 17 +++++++++++++++++ example/exec | Bin 0 -> 93744 bytes example/main.c | 25 +++++++++++++++++++++++++ example/rules.py | 5 +++++ 7 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 example/Makefile create mode 100755 example/exec create mode 100644 example/main.c create mode 100644 example/rules.py diff --git a/bcgen b/bcgen index c7d1a7f..aeb5f56 100755 --- a/bcgen +++ b/bcgen @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import sys +import pathlib def check_fmt(fmt): assert(len(fmt) == 6) @@ -86,6 +87,9 @@ class BCGen: self.r = r self.f = f + # make sure gen dir exists + pathlib.Path('gen').mkdir(exist_ok=True) + # clear out files with open('gen/body.inc', 'w') as inc: pass diff --git a/bcode.c b/bcode.c index b4f4231..1b0cba2 100644 --- a/bcode.c +++ b/bcode.c @@ -41,7 +41,7 @@ static void append(struct compile_state *cs, enum bcode_insn label, breg_t imm) #define IMM s.imm[pc].g #define DIMM s.imm[pc].f -#define NEXT_INSN goto *s.op[pc++] +#define NEXT_INSN goto *s.op[++pc] #define JUMP(i) goto *s.op[pc = (i)] static gbreg_t _run(struct compile_state *cs, bool init) @@ -62,6 +62,7 @@ static gbreg_t _run(struct compile_state *cs, bool init) const struct run_state s = cs->s; size_t pc = 0; JUMP(pc); + #include "gen/body.inc" end: /* we assume there's always at least one general register */ @@ -76,13 +77,33 @@ gbreg_t run(struct compile_state *cs) void init(struct compile_state *cs) { cs->labels = NULL; - cs->s.imm = NULL; - cs->s.op = NULL; - cs->size = 0; + cs->size = 16; + + cs->s.imm = malloc(cs->size * sizeof(*cs->s.imm)); + assert(cs->s.imm); + + cs->s.op = malloc(cs->size * sizeof(*cs->s.op)); + assert(cs->s.op); + cs->pc = 0; _run(cs, true); } +void end(struct compile_state *cs) +{ + PUSH_OP(END); +} + +breg_t label(struct compile_state *cs) +{ + return (breg_t){.g = cs->pc}; +} + +void patch(struct compile_state *cs, breloc_t reloc, breg_t imm) +{ + cs->s.imm[reloc] = imm; +} + void destroy(struct compile_state *cs) { free(cs->s.op); diff --git a/bcode.h b/bcode.h index e25d32a..730b8e7 100644 --- a/bcode.h +++ b/bcode.h @@ -28,7 +28,10 @@ struct compile_state { gbreg_t run(struct compile_state *cs); void init(struct compile_state *cs); +void end(struct compile_state *cs); void destroy(struct compile_state *cs); + +breg_t label(struct compile_state *cs); void patch(struct compile_state *cs, breloc_t reloc, breg_t imm); #endif /* BCGEN_BCODE_H */ diff --git a/example/Makefile b/example/Makefile new file mode 100644 index 0000000..66c96a0 --- /dev/null +++ b/example/Makefile @@ -0,0 +1,17 @@ +CFLAGS = -Wall -Wextra -g -O2 + +all: exec + +exec: bcode.o main.o + $(CC) $(CFLAGS) $^ -o $@ + +bcode.o: ../bcode.c + $(CC) $(CFLAGS) -c $^ -o $@ + +../bcode.c: rules.py + cd .. && ./bcgen example/rules.py + touch ../bcode.c # just to get make to wake up + +.PHONY: clean +clean: + rm -rf *.o exec diff --git a/example/exec b/example/exec new file mode 100755 index 0000000..2189325 Binary files /dev/null and b/example/exec differ diff --git a/example/main.c b/example/main.c new file mode 100644 index 0000000..7ca152b --- /dev/null +++ b/example/main.c @@ -0,0 +1,25 @@ +#include +#include "../bcode.h" + +int main() +{ + struct compile_state cs; + init(&cs); + + select_movi(&cs, 2, 0); // i + select_movi(&cs, 1, 1000000000); // limit + select_movi(&cs, 0, 0); // total + + breg_t l = label(&cs); // top + select_addr(&cs, 0, 0, 2); // add iter to total + select_addi(&cs, 2, 2, 1); + breloc_t r = select_bltr(&cs, 2, 1, 0); // 0 is placeholder value, + // should maybe add in an + // UNDEFINED macro or something + end(&cs); + + patch(&cs, r, l); + + printf("%llu\n", (unsigned long long)run(&cs)); + destroy(&cs); +} diff --git a/example/rules.py b/example/rules.py new file mode 100644 index 0000000..9c8d62e --- /dev/null +++ b/example/rules.py @@ -0,0 +1,5 @@ +g = BCGen(r = 7, f = 0) +g.rule('addr', '_RRR__', 'R0 = R1 + R2;') +g.rule('addi', '_RR__I', 'R0 = R1 + IMM;') +g.rule('movi', '_R___I', 'R0 = IMM;') +g.rule('bltr', 'rRR__I', 'if (R0 < R1) JUMP(IMM);') -- cgit v1.3