add support for thread-local storage
The apple targets are not done yet.
This commit is contained in:
parent
5cea0c20ee
commit
00a30954ac
12 changed files with 145 additions and 70 deletions
63
rv64/emit.c
63
rv64/emit.c
|
@ -129,14 +129,10 @@ slot(int s, Fn *fn)
|
|||
static void
|
||||
emitaddr(Con *c, FILE *f)
|
||||
{
|
||||
char off[32], *p;
|
||||
|
||||
assert(c->rel == RelDef);
|
||||
fputs(str(c->label), f);
|
||||
if (c->bits.i)
|
||||
sprintf(off, "+%"PRIi64, c->bits.i);
|
||||
else
|
||||
off[0] = 0;
|
||||
p = c->local ? ".L" : "";
|
||||
fprintf(f, "%s%s%s", p, str(c->label), off);
|
||||
fprintf(f, "+%"PRIi64, c->bits.i);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -228,26 +224,45 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
loadaddr(Con *c, char *rn, FILE *f)
|
||||
{
|
||||
char off[32];
|
||||
|
||||
if (c->rel == RelThr) {
|
||||
if (c->bits.i)
|
||||
sprintf(off, "+%"PRIi64, c->bits.i);
|
||||
else
|
||||
off[0] = 0;
|
||||
fprintf(f, "\tlui %s, %%tprel_hi(%s)%s\n",
|
||||
rn, str(c->label), off);
|
||||
fprintf(f, "\tadd %s, %s, tp, %%tprel_add(%s)%s\n",
|
||||
rn, rn, str(c->label), off);
|
||||
fprintf(f, "\taddi %s, %s, %%tprel_lo(%s)%s\n",
|
||||
rn, rn, str(c->label), off);
|
||||
} else {
|
||||
fprintf(f, "\tla %s, ", rn);
|
||||
emitaddr(c, f);
|
||||
fputc('\n', f);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
loadcon(Con *c, int r, int k, FILE *f)
|
||||
{
|
||||
char *rn;
|
||||
int64_t n;
|
||||
int w;
|
||||
|
||||
w = KWIDE(k);
|
||||
rn = rname[r];
|
||||
switch (c->type) {
|
||||
case CAddr:
|
||||
fprintf(f, "\tla %s, ", rn);
|
||||
emitaddr(c, f);
|
||||
fputc('\n', f);
|
||||
loadaddr(c, rn, f);
|
||||
break;
|
||||
case CBits:
|
||||
n = c->bits.i;
|
||||
if (!w)
|
||||
if (!KWIDE(k))
|
||||
n = (int32_t)n;
|
||||
fprintf(f, "\tli %s, %"PRIu64"\n", rn, n);
|
||||
fprintf(f, "\tli %s, %"PRIi64"\n", rn, n);
|
||||
break;
|
||||
default:
|
||||
die("invalid constant");
|
||||
|
@ -255,12 +270,20 @@ loadcon(Con *c, int r, int k, FILE *f)
|
|||
}
|
||||
|
||||
static void
|
||||
fixslot(Ref *pr, Fn *fn, FILE *f)
|
||||
fixmem(Ref *pr, Fn *fn, FILE *f)
|
||||
{
|
||||
Ref r;
|
||||
int64_t s;
|
||||
Con *c;
|
||||
|
||||
r = *pr;
|
||||
if (rtype(r) == RCon) {
|
||||
c = &fn->con[r.val];
|
||||
if (c->type == CAddr && c->rel == RelThr) {
|
||||
loadcon(c, T6, Kl, f);
|
||||
*pr = TMP(T6);
|
||||
}
|
||||
}
|
||||
if (rtype(r) == RSlot) {
|
||||
s = slot(r.val, fn);
|
||||
if (s < -2048 || s > 2047) {
|
||||
|
@ -282,9 +305,9 @@ emitins(Ins *i, Fn *fn, FILE *f)
|
|||
switch (i->op) {
|
||||
default:
|
||||
if (isload(i->op))
|
||||
fixslot(&i->arg[0], fn, f);
|
||||
fixmem(&i->arg[0], fn, f);
|
||||
else if (isstore(i->op))
|
||||
fixslot(&i->arg[1], fn, f);
|
||||
fixmem(&i->arg[1], fn, f);
|
||||
Table:
|
||||
/* most instructions are just pulled out of
|
||||
* the table omap[], some special cases are
|
||||
|
@ -321,7 +344,7 @@ emitins(Ins *i, Fn *fn, FILE *f)
|
|||
case Ks: i->op = Ostores; break;
|
||||
case Kd: i->op = Ostored; break;
|
||||
}
|
||||
fixslot(&i->arg[1], fn, f);
|
||||
fixmem(&i->arg[1], fn, f);
|
||||
goto Table;
|
||||
}
|
||||
break;
|
||||
|
@ -333,7 +356,7 @@ emitins(Ins *i, Fn *fn, FILE *f)
|
|||
break;
|
||||
case RSlot:
|
||||
i->op = Oload;
|
||||
fixslot(&i->arg[0], fn, f);
|
||||
fixmem(&i->arg[0], fn, f);
|
||||
goto Table;
|
||||
default:
|
||||
assert(isreg(i->arg[0]));
|
||||
|
@ -415,7 +438,7 @@ rv64_emitfn(Fn *fn, FILE *f)
|
|||
Blk *b, *s;
|
||||
Ins *i;
|
||||
|
||||
emitlnk(fn->name, &fn->lnk, ".text", f);
|
||||
emitfnlnk(fn->name, &fn->lnk, f);
|
||||
|
||||
if (fn->vararg) {
|
||||
/* TODO: only need space for registers
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue