qbe

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

commit 167b6dca703cf1999b50833640e9468e330820b7
parent d023bdaa6b493686f7e9be7ac200ee4ac37d351f
Author: Roberto E. Vargas Caballero <roberto.vargas@midokura.com>
Date:   Wed, 29 Jun 2022 18:09:08 +0200

Add common linkage attribute

This allows you to explicitly mark a symbol as common.

Diffstat:
Mall.h | 1+
Memit.c | 4+++-
Mparse.c | 19++++++++++++++++---
Mtools/lexh.c | 2+-
4 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/all.h b/all.h @@ -365,6 +365,7 @@ struct Lnk { char export; char thread; char align; + char common; char *sec; char *secf; }; diff --git a/emit.c b/emit.c @@ -72,7 +72,7 @@ emitdat(Dat *d, FILE *f) switch (d->type) { case DStart: - zero = 0; + zero = d->lnk->common ? -1 : 0; break; case DEnd: if (zero != -1) { @@ -83,6 +83,8 @@ emitdat(Dat *d, FILE *f) case DZ: if (zero != -1) zero += d->u.num; + else if (d->lnk->common) + fprintf(f, "\t.comm %s,%"PRId64"\n", d->name, d->u.num); else fprintf(f, "\t.fill %"PRId64",1,0\n", d->u.num); break; diff --git a/parse.c b/parse.c @@ -51,6 +51,7 @@ enum Token { Tfunc, Ttype, Tdata, + Tcommon, Tsection, Talign, Tdbgfile, @@ -109,6 +110,7 @@ static char *kwmap[Ntok] = { [Tfunc] = "function", [Ttype] = "type", [Tdata] = "data", + [Tcommon] = "common", [Tsection] = "section", [Talign] = "align", [Tdbgfile] = "dbgfile", @@ -132,7 +134,7 @@ enum { TMask = 16383, /* for temps hash */ BMask = 8191, /* for blocks hash */ - K = 9583425, /* found using tools/lexh.c */ + K = 11183273, /* found using tools/lexh.c */ M = 23, }; @@ -1072,7 +1074,7 @@ static void parsedat(void cb(Dat *), Lnk *lnk) { char name[NString] = {0}; - int t; + int t, n; Dat d; if (nextnl() != Tglo || nextnl() != Teq) @@ -1093,7 +1095,9 @@ parsedat(void cb(Dat *), Lnk *lnk) if (t != Tlbrace) err("expected data contents in { .. }"); - for (;;) { + for (n = 0;; n++) { + if (lnk->common && n > 0) + err("common can be used only with one z"); switch (nextnl()) { default: err("invalid size specifier %c in data", tokval.chr); case Trbrace: goto Done; @@ -1105,6 +1109,8 @@ parsedat(void cb(Dat *), Lnk *lnk) case Td: d.type = DL; break; case Tz: d.type = DZ; break; } + if (lnk->common && d.type != DZ) + err("common can be used only with z"); t = nextnl(); do { d.isstr = 0; @@ -1148,6 +1154,9 @@ parselnk(Lnk *lnk) case Tthread: lnk->thread = 1; break; + case Tcommon: + lnk->common = 1; + break; case Tsection: if (lnk->sec) err("only one section allowed"); @@ -1164,6 +1173,10 @@ parselnk(Lnk *lnk) err("only data may have thread linkage"); if (haslnk && t != Tdata && t != Tfunc) err("only data and function have linkage"); + if (lnk->common && lnk->sec) + err("common symbols cannot have section declarations"); + if (lnk->common && t != Tdata) + err("common symbols only can be used for data"); return t; } } diff --git a/tools/lexh.c b/tools/lexh.c @@ -26,7 +26,7 @@ char *tok[] = { "vaarg", "vastart", "...", "env", "dbgloc", "call", "phi", "jmp", "jnz", "ret", "hlt", "export", - "function", "type", "data", "section", "align", "dbgfile", + "function", "type", "data", "section", "common", "align", "dbgfile", "blit", "l", "w", "sh", "uh", "h", "sb", "ub", "b", "d", "s", "z", "loadw", "loadl", "loads", "loadd", "alloc1", "alloc2",