qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit 0d929287d77ccc3fb52ca8bd072678b5ae2c81c8
parent e493a7f23352f51acc0a1e12284ab19d7894488a
Author: Thomas Bracht Laumann Jespersen <t@laumann.xyz>
Date:   Thu, 26 Jan 2023 12:09:44 +0100

implement line number info tracking

Support "file" and "loc" directives. "file" takes a string (a file name)
assigns it a number, sets the current file to that number and records
the string for later. "loc" takes a single number and outputs location
information with a reference to the current file.

Diffstat:
Mall.h | 4+++-
Mamd64/emit.c | 3+++
Mamd64/isel.c | 1+
Marm64/emit.c | 3+++
Memit.c | 32++++++++++++++++++++++++++++++++
Mmain.c | 8+++++++-
Mops.h | 2++
Mparse.c | 20++++++++++++++++++--
Mrv64/emit.c | 3+++
Mtools/lexh.c | 6+++---
10 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/all.h b/all.h @@ -502,7 +502,7 @@ bshas(BSet *bs, uint elt) /* parse.c */ extern Op optab[NOp]; -void parse(FILE *, char *, void (Dat *), void (Fn *)); +void parse(FILE *, char *, void (char *), void (Dat *), void (Fn *)); void printfn(Fn *, FILE *); void printref(Ref, Fn *, FILE *); void err(char *, ...) __attribute__((noreturn)); @@ -568,6 +568,8 @@ void rega(Fn *); /* emit.c */ void emitfnlnk(char *, Lnk *, FILE *); void emitdat(Dat *, FILE *); +void emitdbgfile(char *, FILE *); +void emitdbgloc(uint, FILE *); int stashbits(void *, int); void elf_emitfnfin(char *, FILE *); void elf_emitfin(FILE *); diff --git a/amd64/emit.c b/amd64/emit.c @@ -547,6 +547,9 @@ emitins(Ins i, Fn *fn, FILE *f) emitcopy(i.arg[0], i.arg[1], i.cls, fn, f); emitcopy(i.arg[1], TMP(XMM0+15), i.cls, fn, f); break; + case Oloc: + emitdbgloc(i.arg[0].val, f); + break; } } diff --git a/amd64/isel.c b/amd64/isel.c @@ -392,6 +392,7 @@ sel(Ins i, ANum *an, Fn *fn) case_Oload: seladdr(&i.arg[0], an, fn); goto Emit; + case Oloc: case Ocall: case Osalloc: case Ocopy: diff --git a/arm64/emit.c b/arm64/emit.c @@ -446,6 +446,9 @@ emitins(Ins *i, E *e) if (!req(i->to, R)) emitf("mov %=, sp", i, e); break; + case Oloc: + emitdbgloc(i->arg[0].val, e->f); + break; } } diff --git a/emit.c b/emit.c @@ -207,3 +207,35 @@ macho_emitfin(FILE *f) emitfin(f, sec); } + +static uint32_t *file; +static uint nfile; +static uint curfile; + +void +emitdbgfile(char *fn, FILE *f) +{ + uint32_t id; + uint n; + + id = intern(fn); + for (n=0; n<nfile; n++) + if (file[n] == id) { + /* gas requires positive + * file numbers */ + curfile = n + 1; + return; + } + if (!file) + file = vnew(0, sizeof *file, PHeap); + vgrow(&file, ++nfile); + file[nfile-1] = id; + curfile = nfile; + fprintf(f, ".file %u %s\n", curfile, fn); +} + +void +emitdbgloc(uint loc, FILE *f) +{ + fprintf(f, "\t.loc %u %u\n", curfile, loc); +} diff --git a/main.c b/main.c @@ -107,6 +107,12 @@ func(Fn *fn) freeall(); } +static void +dbgfile(char *fn) +{ + emitdbgfile(fn, outf); +} + int main(int ac, char *av[]) { @@ -181,7 +187,7 @@ main(int ac, char *av[]) exit(1); } } - parse(inf, f, data, func); + parse(inf, f, dbgfile, data, func); fclose(inf); } while (++optind < ac); diff --git a/ops.h b/ops.h @@ -121,6 +121,8 @@ O(vastart, T(m,e,e,e, x,e,e,e), 0) X(0, 0, 0) V(0) O(copy, T(w,l,s,d, x,x,x,x), 0) X(0, 0, 1) V(0) +/* Debug */ +O(loc, T(w,l,s,d, x,x,x,x), 0) X(0, 0, 1) V(0) /****************************************/ /* INTERNAL OPERATIONS (keep nop first) */ diff --git a/parse.c b/parse.c @@ -53,6 +53,7 @@ enum Token { Tdata, Tsection, Talign, + Tfile, Tl, Tw, Tsh, @@ -110,6 +111,7 @@ static char *kwmap[Ntok] = { [Tdata] = "data", [Tsection] = "section", [Talign] = "align", + [Tfile] = "file", [Tsb] = "sb", [Tub] = "ub", [Tsh] = "sh", @@ -130,7 +132,7 @@ enum { TMask = 16383, /* for temps hash */ BMask = 8191, /* for blocks hash */ - K = 9583425, /* found using tools/lexh.c */ + K = 10525445, /* found using tools/lexh.c */ M = 23, }; @@ -655,6 +657,16 @@ parseline(PState ps) expect(Tnl); closeblk(); return PLbl; + case Oloc: + expect(Tint); + op = Oloc; + k = Kw; + r = R; + arg[0] = INT(tokval.num); + if (arg[0].val != tokval.num) + err("line number too big"); + arg[1] = R; + goto Ins; } r = tmpref(tokval.str); expect(Teq); @@ -1160,7 +1172,7 @@ parselnk(Lnk *lnk) } void -parse(FILE *f, char *path, void data(Dat *), void func(Fn *)) +parse(FILE *f, char *path, void dbgfile(char *), void data(Dat *), void func(Fn *)) { Lnk lnk; uint n; @@ -1177,6 +1189,10 @@ parse(FILE *f, char *path, void data(Dat *), void func(Fn *)) switch (parselnk(&lnk)) { default: err("top-level definition expected"); + case Tfile: + expect(Tstr); + dbgfile(tokval.str); + break; case Tfunc: func(parsefn(&lnk)); break; diff --git a/rv64/emit.c b/rv64/emit.c @@ -405,6 +405,9 @@ emitins(Ins *i, Fn *fn, FILE *f) if (!req(i->to, R)) emitf("mv %=, sp", i, fn, f); break; + case Oloc: + emitdbgloc(i->arg[0].val, f); + break; } } diff --git a/tools/lexh.c b/tools/lexh.c @@ -23,11 +23,11 @@ char *tok[] = { "ceql", "cnel", "cles", "clts", "cgts", "cges", "cnes", "ceqs", "cos", "cuos", "cled", "cltd", "cgtd", "cged", "cned", "ceqd", "cod", "cuod", - "vaarg", "vastart", "...", "env", + "vaarg", "vastart", "...", "env", "loc", "call", "phi", "jmp", "jnz", "ret", "hlt", "export", - "function", "type", "data", "section", "align", "blit", - "l", "w", "sh", "uh", "h", "sb", "ub", "b", + "function", "type", "data", "section", "align", "file", + "blit", "l", "w", "sh", "uh", "h", "sb", "ub", "b", "d", "s", "z", "loadw", "loadl", "loads", "loadd", "alloc1", "alloc2",