diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-04-15 01:35:19 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-04-15 02:01:21 +0300 |
| commit | 5a728ae106b978c6de0fa6316f37eb3b4a86a405 (patch) | |
| tree | 20c5e1f08aa4c6c84f22d6b31d0965c36a38ab94 | |
| parent | 8ce25e04620d4173748a7d7dd310351bac90eacc (diff) | |
| download | qbt-5a728ae106b978c6de0fa6316f37eb3b4a86a405.tar.gz qbt-5a728ae106b978c6de0fa6316f37eb3b4a86a405.zip | |
format
| -rw-r--r-- | include/qbt/nodes.h | 2 | ||||
| -rw-r--r-- | include/qbt/vec.h | 2 | ||||
| -rw-r--r-- | src/asm.c | 25 | ||||
| -rw-r--r-- | src/correct.c | 11 | ||||
| -rw-r--r-- | src/main.c | 8 | ||||
| -rw-r--r-- | src/nodes.c | 4 | ||||
| -rw-r--r-- | src/parser.y | 19 |
7 files changed, 57 insertions, 14 deletions
diff --git a/include/qbt/nodes.h b/include/qbt/nodes.h index d8de9fe..49cb11a 100644 --- a/include/qbt/nodes.h +++ b/include/qbt/nodes.h @@ -17,6 +17,7 @@ enum insn_type { STORE, LOAD, ALLOC, + DEALLOC, COPY, MOVE, BLIT, @@ -67,6 +68,7 @@ enum insn_flags { M(STORE) \ M(LOAD) \ M(ALLOC) \ + M(DEALLOC) \ M(COPY) \ M(MOVE) \ M(BLIT) \ diff --git a/include/qbt/vec.h b/include/qbt/vec.h index 79970a6..a712b7a 100644 --- a/include/qbt/vec.h +++ b/include/qbt/vec.h @@ -21,7 +21,7 @@ void vec_append(struct vec *v, void *n); void vec_insert(struct vec *v, void *n, size_t i); #define foreach_vec(iter, v) \ - for (size_t iter = 0, __n = vec_len(&v); iter < __n; ++iter) + for (size_t iter = 0; iter < vec_len(&v); ++iter) #define vect_at(type, v, i) \ *(type *)vec_at(&v, i) @@ -248,11 +248,9 @@ static void output_restore(struct insn n, FILE *o, struct fn *f) static void output_store(struct insn n, FILE *o) { - struct val offset = n.out; struct val b = n.in[0]; struct val t = n.in[1]; - assert(offset.class == IMM); assert(b.class == REG); assert(t.class == REG); @@ -260,7 +258,7 @@ static void output_store(struct insn n, FILE *o) if (n.vtype == I9) width = 't'; - int64_t off = offset.v; + int64_t off = n.v; fprintf(o, "st %c %s, %lli(%s)\n", width, rname(t), (long long int)off, rname(b)); } @@ -269,9 +267,7 @@ static void output_load(struct insn n, FILE *o) { struct val t = n.out; struct val b = n.in[0]; - struct val offset = n.in[1]; - assert(offset.class == IMM); assert(b.class == REG); assert(t.class == REG); @@ -279,7 +275,7 @@ static void output_load(struct insn n, FILE *o) if (n.vtype == I9) width = 't'; - int64_t off = offset.v; + int64_t off = n.v; fprintf(o, "ld %c %s, %lli(%s)\n", width, rname(t), (long long int)off, rname(b)); } @@ -295,6 +291,21 @@ static void output_lt(struct insn i, FILE *o) rname(i.out), rname(i.in[0]), rname(i.in[1])); } +static void output_alloc(struct insn i, FILE *o) +{ + assert(i.type == ALLOC); + /** @todo alignment is ignored, is that our responsibility? */ + fprintf(o, "addi sp, sp, -%lli\n", i.v); + fprintf(o, "mov %s, sp\n", rname(i.out)); +} + +static void output_dealloc(struct insn i, FILE *o) +{ + assert(i.type == DEALLOC); + /** @todo alignment is ignored */ + fprintf(o, "addi sp, sp, %lli\n", i.v); +} + static void output_insn(struct insn n, FILE *o, struct fn *f) { /* one insn directly matches one or more assembly instructions, @@ -309,6 +320,8 @@ static void output_insn(struct insn n, FILE *o, struct fn *f) case CALL: output_call(n, o); break; case STORE: output_store(n, o); break; case LOAD: output_load(n, o); break; + case ALLOC: output_alloc(n, o); break; + case DEALLOC: output_dealloc(n, o); break; case SAVE: output_save(n, o, f); break; case RESTORE: output_restore(n, o, f); break; default: fprintf(stderr, "unimplemented insn: %s\n", op_str(n.type)); diff --git a/src/correct.c b/src/correct.c index 5db40dd..8c0b249 100644 --- a/src/correct.c +++ b/src/correct.c @@ -68,6 +68,14 @@ static size_t correct_relations(struct blk *b, size_t ii, struct insn i, return ri; } +static size_t correct_store(struct blk *b, size_t ii, struct insn i, size_t ri) +{ + if (i.in[1].class == IMM) + return spill_imm(b, ii, i, 1, ri); + + return ri; +} + static size_t correct_insn(struct blk *b, size_t ii, struct insn i, size_t ri) { /* replace references with instructions */ @@ -109,6 +117,9 @@ static size_t correct_insn(struct blk *b, size_t ii, struct insn i, size_t ri) case NE: return correct_relations(b, ii, i, ri); + case STORE: + return correct_store(b, ii, i, ri); + default: } @@ -55,6 +55,12 @@ int main(int argc, char *argv[]) struct parser *p = create_parser(); parse(p, fname, buf); + int ret = 0; + if (p->failed) { + ret = -1; + goto out; + } + foreach_fn(i, p->fns) { struct fn_map m = fn_at(p->fns, i); // also handles things like register mapping etc. @@ -63,6 +69,8 @@ int main(int argc, char *argv[]) output(m.fn, stdout); } +out: destroy_parser(p); free(buf); + return ret; } diff --git a/src/nodes.c b/src/nodes.c index 07a1706..88486a4 100644 --- a/src/nodes.c +++ b/src/nodes.c @@ -188,6 +188,10 @@ void dump_insn(struct insn i) dump_val(i.in[1]); } + /* crude, but works for now */ + if (i.v) + printf(" %lli ", i.v); + if (i.flags) printf("*"); diff --git a/src/parser.y b/src/parser.y index 24a2ebe..609c777 100644 --- a/src/parser.y +++ b/src/parser.y @@ -362,15 +362,13 @@ mem_off mem : type id "<<" mem_base mem_off { - struct val t = IDTOVAL($[id]); + struct val t = IDALLOC($[id]); struct val b = IDTOVAL($[mem_base]); INSADD(LOAD, $[type], t, b, noclass(), $[mem_off]); } - | id ">>" type mem_base mem_off { - struct val t = IDTOVAL($[id]); + | arg ">>" type mem_base mem_off { struct val b = IDTOVAL($[mem_base]); - /* really not a huge fan or 'reusing' the output slot... */ - INSADD(STORE, $[type], noclass(), b, t, $[mem_off]); + INSADD(STORE, $[type], noclass(), b, $[arg], $[mem_off]); } | id "<<*" int id { struct val t = IDTOVAL($1); @@ -384,6 +382,10 @@ stack INSADD(ALLOC, $[type], t, noclass(), noclass(), $[int]); } + | "^" "^" int { + INSADD(DEALLOC, NOTYPE, noclass(), noclass(), noclass(), $[int]); + } + cond : type id "=" arg "==" arg { struct val t = IDALLOC($[id]); @@ -480,8 +482,8 @@ opt_call_rets | {} call_arg - : type arg { - INSADD(ARG, $[type], noclass(), $[arg], imm_val(parser->idx++, I27), 0); + : arg { + INSADD(ARG, NOTYPE, noclass(), $[arg], imm_val(parser->idx++, I27), 0); } call_args @@ -568,6 +570,9 @@ top unit : top unit | top + | error { + parser->failed = true; + } input : unit |
