Compare commits

..

3 Commits

Author SHA1 Message Date
Quentin Carbonneaux
f36c06c3ee rework docs 2026-04-29 11:22:19 +02:00
Quentin Carbonneaux
8c16de02ed rv64: got-free addresses for SGlo 2026-04-29 10:54:26 +02:00
Quentin Carbonneaux
63bb04f759 more fixes 2026-04-29 10:15:11 +02:00
5 changed files with 41 additions and 45 deletions

13
all.h
View File

@ -292,16 +292,11 @@ struct Use {
};
struct Sym {
/* SGlo = 0 (direct access)
* SThr = 1 (local-exec TLS)
* SExt = 2 (GOT/PLT access)
* SExt|SThr = 3 (initial-exec TLS)
*/
enum {
SGlo = 0,
SThr = 1,
SExt = 2,
SExtThr = SExt|SThr,
SGlo = 0, /* direct access */
SThr = 1, /* local-exec TLS */
SExt = 2, /* GOT/PLT access */
SExtThr = SExt|SThr, /* initial-exec TLS */
} type;
uint32_t id;
};

View File

@ -534,12 +534,12 @@ emitins(Ins i, E *e)
case Oaddr:
if (rtype(i.arg[0]) != RCon)
goto Table;
assert(isreg(i.to));
con = &e->fn->con[i.arg[0].val];
assert(isreg(i.to) && con->type == CAddr);
sym = str(con->sym.id);
if (T.apple && (con->sym.type & SThr)) {
fprintf(e->f,
"\tmovq %s%s@TLVP(%%rip), %%%s\n",
"\tmovq %s%s@tlvp(%%rip), %%%s\n",
sym[0] == '"' ? "" : T.assym, sym,
regtoa(i.to.val, SLong));
break;

View File

@ -228,14 +228,13 @@ symbol's numeric value is resolved at runtime in the
thread-local storage.
When the `extern` keyword prefixes a symbol name, the
symbol is accessed indirectly through the Global Offset
Table (GOT). Function calls to extern symbols use the
Procedure Linkage Table (PLT). This enables PIE and
PIC code generation for symbols that are not part of
the main executable. When `extern` is combined with
`thread`, the symbol is accessed using the initial-exec
TLS model, suitable for thread-local variables defined
in shared libraries.
symbol is accessed indirectly through a table edited
by the dynamic linker (e.g., GOT/PLT). This enables
PIE/PIC code generation. When `extern` is combined
with `thread`, the symbol is accessed using the
initial-exec TLS model, suitable for thread-local
variables defined in shared objects available at
startup time (i.e., not loaded through dlopen).
Vals are used as arguments in regular, phi, and jump
instructions within function definitions. They are

29
parse.c
View File

@ -429,11 +429,10 @@ static Ref
parseref()
{
Con c;
int tok;
memset(&c, 0, sizeof c);
switch (next()) {
default:
return R;
switch ((tok = next())) {
case Ttmp:
return tmpref(tokval.str);
case Tint:
@ -450,20 +449,22 @@ parseref()
c.bits.d = tokval.fltd;
c.flt = 2;
break;
case Textern:
c.sym.type = SExt;
if (peek() == Tthread) {
next();
c.sym.type |= SThr;
default:
for (;; tok=next()) {
switch (tok) {
case Textern:
c.sym.type |= SExt;
continue;
case Tthread:
c.sym.type |= SThr;
continue;
}
break;
}
expect(Tglo);
goto Glo;
case Tthread:
c.sym.type = SThr;
expect(Tglo);
if (tok != Tglo)
return R;
/* fall through */
case Tglo:
Glo:
c.type = CAddr;
c.sym.id = intern(tokval.str);
break;

View File

@ -131,7 +131,7 @@ slot(Ref r, Fn *fn)
static void
emitaddr(Con *c, FILE *f)
{
assert(c->sym.type == SGlo || c->sym.type == SExt);
assert((c->sym.type & ~SExt) == SGlo);
fputs(str(c->sym.id), f);
if (c->bits.i)
fprintf(f, "+%"PRIi64, c->bits.i);
@ -232,6 +232,18 @@ loadaddr(Con *c, char *rn, FILE *f)
char off[32];
switch (c->sym.type) {
case SGlo:
fprintf(f, "\tlui %s, %%hi(", rn);
emitaddr(c, f);
fprintf(f, ")\n\taddi %s, %s, %%lo(", rn, rn);
emitaddr(c, f);
fputs(")\n", f);
break;
case SExt:
fprintf(f, "\tla %s, ", rn);
emitaddr(c, f);
fputc('\n', f);
break;
case SThr:
if (c->bits.i)
sprintf(off, "+%"PRIi64, c->bits.i);
@ -244,19 +256,8 @@ loadaddr(Con *c, char *rn, FILE *f)
fprintf(f, "\taddi %s, %s, %%tprel_lo(%s)%s\n",
rn, rn, str(c->sym.id), off);
break;
case SExt:
fprintf(f, "\tla %s, ", rn);
emitaddr(c, f);
fputc('\n', f);
break;
case SExtThr:
die("extern thread unavailable on rv64");
break;
default:
fprintf(f, "\tla %s, ", rn);
emitaddr(c, f);
fputc('\n', f);
break;
}
}