Compare commits

..

No commits in common. "f36c06c3ee8d8bb4c381904996f230e741be43c9" and "6abea36b9b3e9eedf0b69a71769ec80f2b074b68" have entirely different histories.

5 changed files with 45 additions and 41 deletions

13
all.h
View File

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

View File

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

View File

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

25
parse.c
View File

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

View File

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