nooc

nooc programming language compiler
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit a4dd029ba2d03e7d014958eff03de5d2ba407f08
parent b43ef1072891fa694565d481c467d57769884946
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Mon, 10 Jan 2022 23:01:03 -0600

move backend specific stuff to ir.c

This means main.c doesn't have to know about backends at all.

Diffstat:
Mir.c | 22+++++++++++++++++++---
Mir.h | 12+++++++++---
Mmain.c | 16++--------------
Mnooc.h | 5-----
Mx64.c | 11++++++-----
5 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/ir.c b/ir.c @@ -3,6 +3,7 @@ #include <stddef.h> #include <stdint.h> #include <stdio.h> +#include <stdlib.h> #include <strings.h> #include "array.h" @@ -316,18 +317,24 @@ genblock(struct iproc *out, struct block *block) } } -void -genproc(struct iproc *out, struct proc *proc) +size_t +genproc(struct decl *decl, struct proc *proc) { tmpi = labeli = curi = 1; regs = targ.reserved; struct instr ins; struct type *type; + struct iproc iproc = { + .s = decl->s, + .addr = decl->w.addr, + }; + + struct iproc *out = &iproc; // for macros to work, a bit hacky blockpush(&proc->block); // put a blank interval, since tmpi starts at 1 - array_add((&out->intervals), interval); + array_add((&iproc.intervals), interval); size_t i = 0; for (size_t j = 0; j < proc->in.len; j++, i++) { @@ -367,5 +374,14 @@ genproc(struct iproc *out, struct proc *proc) } } + size_t len = targ.emitproc(NULL, out); + void *buf = xcalloc(1, len); // FIXME: unnecessary + len = targ.emitproc(buf, out); + array_push((&toplevel.text), buf, len); + free(buf); + array_add((&toplevel.code), iproc); + blockpop(); + + return len; } diff --git a/ir.h b/ir.h @@ -39,9 +39,9 @@ struct interval { struct iproc { size_t len; size_t cap; - uint64_t addr; struct instr *data; - struct slice s; + uint64_t addr; // FIXME: 'addr' and 's' are only necessary because syscalls are intrinsics. + struct slice s; // Once syscalls are moved out, we can just use the decl fields and have a pointer to the declaration. struct { size_t len; size_t cap; @@ -61,4 +61,10 @@ struct toplevel { uint64_t entry; }; -void genproc(struct iproc *out, struct proc *proc); +size_t genproc(struct decl *decl, struct proc *proc); + +struct target { + uint32_t reserved; + size_t (*emitsyscall)(char *buf, uint8_t paramcount); + size_t (*emitproc)(char *buf, struct iproc *proc); +}; diff --git a/main.c b/main.c @@ -13,7 +13,6 @@ #include "nooc.h" #include "ir.h" #include "util.h" -#include "x64.h" #include "elf.h" #include "lex.h" #include "parse.h" @@ -134,7 +133,6 @@ gentoplevel(struct toplevel *toplevel, struct block *block) decl_alloc(block, decl); - // FIXME: clean this whole thing up if (expr->class == C_PROC) { if (slice_cmplit(&decl->s, "main") == 0) { toplevel->entry = curaddr; @@ -142,18 +140,8 @@ gentoplevel(struct toplevel *toplevel, struct block *block) assert(expr->kind = EXPR_PROC); blockpush(&expr->d.proc.block); typecheck(&expr->d.proc.block); - iproc = (struct iproc){ 0 }; - iproc.s = decl->s; - iproc.addr = curaddr; - genproc(&iproc, &(expr->d.proc)); - array_add((&toplevel->code), iproc); - len = emitproc(NULL, &iproc); - void *buf = xcalloc(1, len); // FIXME: unnecessary - len = emitproc(buf, &iproc); - curaddr += len; - array_push((&toplevel->text), buf, len); - free(buf); - + decl->w.addr = curaddr; + curaddr += genproc(decl, &expr->d.proc); blockpop(); } else { evalexpr(decl); diff --git a/nooc.h b/nooc.h @@ -248,8 +248,3 @@ struct exprs { size_t len; struct expr *data; }; - -struct target { - uint32_t reserved; - size_t (*emitsyscall)(char *buf, uint8_t paramcount); -}; diff --git a/x64.c b/x64.c @@ -602,11 +602,6 @@ emitsyscall(char *buf, uint8_t paramcount) return total; } -const struct target x64_target = { - .reserved = (1 << RSP) | (1 << RBP) | (1 << R12) | (1 << R13), - .emitsyscall = emitsyscall -}; - size_t emitblock(char *buf, struct iproc *proc, struct instr *start, struct instr *end, uint64_t end_label) { @@ -754,3 +749,9 @@ emitproc(char *buf, struct iproc *proc) { return emitblock(buf, proc, NULL, NULL, 0); } + +const struct target x64_target = { + .reserved = (1 << RSP) | (1 << RBP) | (1 << R12) | (1 << R13), + .emitsyscall = emitsyscall, + .emitproc = emitproc +};