mirror of
git://c9x.me/qbe.git
synced 2026-05-26 15:34:41 +00:00
Compare commits
4 Commits
fee64f4341
...
6abea36b9b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6abea36b9b | ||
|
|
b8b95a99df | ||
|
|
a9796317aa | ||
|
|
5ac78c67c9 |
46
amd64/emit.c
46
amd64/emit.c
@ -195,13 +195,13 @@ emitcon(Con *con, E *e)
|
|||||||
case CAddr:
|
case CAddr:
|
||||||
l = str(con->sym.id);
|
l = str(con->sym.id);
|
||||||
p = l[0] == '"' ? "" : T.assym;
|
p = l[0] == '"' ? "" : T.assym;
|
||||||
if (con->sym.type & SThr) {
|
if (con->sym.type == SThr) {
|
||||||
if (T.apple)
|
assert(!T.apple);
|
||||||
fprintf(e->f, "%s%s@TLVP", p, l);
|
fprintf(e->f, "%%fs:%s%s@tpoff", p, l);
|
||||||
else
|
} else {
|
||||||
fprintf(e->f, "%%fs:%s%s@tpoff", p, l);
|
assert(con->sym.type == SGlo);
|
||||||
} else
|
|
||||||
fprintf(e->f, "%s%s", p, l);
|
fprintf(e->f, "%s%s", p, l);
|
||||||
|
}
|
||||||
if (con->bits.i)
|
if (con->bits.i)
|
||||||
fprintf(e->f, "%+"PRId64, con->bits.i);
|
fprintf(e->f, "%+"PRId64, con->bits.i);
|
||||||
break;
|
break;
|
||||||
@ -380,7 +380,7 @@ Next:
|
|||||||
off = e->fn->con[ref.val];
|
off = e->fn->con[ref.val];
|
||||||
emitcon(&off, e);
|
emitcon(&off, e);
|
||||||
if (off.type == CAddr)
|
if (off.type == CAddr)
|
||||||
if (off.sym.type != SThr || T.apple)
|
if (off.sym.type != SThr)
|
||||||
fprintf(e->f, "(%%rip)");
|
fprintf(e->f, "(%%rip)");
|
||||||
break;
|
break;
|
||||||
case RTmp:
|
case RTmp:
|
||||||
@ -532,14 +532,21 @@ emitins(Ins i, E *e)
|
|||||||
emitf("mov%k %0, %=", &i, e);
|
emitf("mov%k %0, %=", &i, e);
|
||||||
break;
|
break;
|
||||||
case Oaddr:
|
case Oaddr:
|
||||||
if (!T.apple
|
if (rtype(i.arg[0]) != RCon)
|
||||||
&& rtype(i.arg[0]) == RCon
|
goto Table;
|
||||||
&& e->fn->con[i.arg[0].val].sym.type == SThr) {
|
assert(isreg(i.to));
|
||||||
|
con = &e->fn->con[i.arg[0].val];
|
||||||
|
sym = str(con->sym.id);
|
||||||
|
if (T.apple && (con->sym.type & SThr)) {
|
||||||
|
fprintf(e->f,
|
||||||
|
"\tmovq %s%s@TLVP(%%rip), %%%s\n",
|
||||||
|
sym[0] == '"' ? "" : T.assym, sym,
|
||||||
|
regtoa(i.to.val, SLong));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!T.apple && con->sym.type == SThr) {
|
||||||
/* derive the symbol address from the TCB
|
/* derive the symbol address from the TCB
|
||||||
* address at offset 0 of %fs */
|
* address at offset 0 of %fs */
|
||||||
assert(isreg(i.to));
|
|
||||||
con = &e->fn->con[i.arg[0].val];
|
|
||||||
sym = str(con->sym.id);
|
|
||||||
emitf("movq %%fs:0, %L=", &i, e);
|
emitf("movq %%fs:0, %L=", &i, e);
|
||||||
fprintf(e->f, "\tleaq %s%s@tpoff",
|
fprintf(e->f, "\tleaq %s%s@tpoff",
|
||||||
sym[0] == '"' ? "" : T.assym, sym);
|
sym[0] == '"' ? "" : T.assym, sym);
|
||||||
@ -551,14 +558,9 @@ emitins(Ins i, E *e)
|
|||||||
regtoa(i.to.val, SLong));
|
regtoa(i.to.val, SLong));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!T.apple
|
if (!T.apple && con->sym.type == SExtThr) {
|
||||||
&& rtype(i.arg[0]) == RCon
|
|
||||||
&& e->fn->con[i.arg[0].val].sym.type == SExtThr) {
|
|
||||||
/* initial-exec TLS: load offset from
|
/* initial-exec TLS: load offset from
|
||||||
* GOT, add to thread-base register */
|
* GOT, add to thread-base register */
|
||||||
assert(isreg(i.to));
|
|
||||||
con = &e->fn->con[i.arg[0].val];
|
|
||||||
sym = str(con->sym.id);
|
|
||||||
assert(!con->bits.i);
|
assert(!con->bits.i);
|
||||||
emitf("movq %%fs:0, %L=", &i, e);
|
emitf("movq %%fs:0, %L=", &i, e);
|
||||||
fprintf(e->f,
|
fprintf(e->f,
|
||||||
@ -567,12 +569,8 @@ emitins(Ins i, E *e)
|
|||||||
regtoa(i.to.val, SLong));
|
regtoa(i.to.val, SLong));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rtype(i.arg[0]) == RCon
|
if (con->sym.type == SExt) {
|
||||||
&& e->fn->con[i.arg[0].val].sym.type == SExt) {
|
|
||||||
/* load address from the GOT */
|
/* load address from the GOT */
|
||||||
assert(isreg(i.to));
|
|
||||||
con = &e->fn->con[i.arg[0].val];
|
|
||||||
sym = str(con->sym.id);
|
|
||||||
assert(!con->bits.i);
|
assert(!con->bits.i);
|
||||||
fprintf(e->f,
|
fprintf(e->f,
|
||||||
"\tmovq %s%s@gotpcrel(%%rip), %%%s\n",
|
"\tmovq %s%s@gotpcrel(%%rip), %%%s\n",
|
||||||
|
|||||||
@ -143,10 +143,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
|
|||||||
cc = *c;
|
cc = *c;
|
||||||
cc.bits.i = 0;
|
cc.bits.i = 0;
|
||||||
r3 = newcon(&cc, fn);
|
r3 = newcon(&cc, fn);
|
||||||
if (T.apple && (c->sym.type & SThr))
|
emit(Oaddr, Kl, r2, r3, R);
|
||||||
emit(Oload, Kl, r2, r3, R);
|
|
||||||
else
|
|
||||||
emit(Oaddr, Kl, r2, r3, R);
|
|
||||||
if (rtype(r0) == RMem) {
|
if (rtype(r0) == RMem) {
|
||||||
m = &fn->mem[r0.val];
|
m = &fn->mem[r0.val];
|
||||||
m->offset.type = CUndef;
|
m->offset.type = CUndef;
|
||||||
|
|||||||
@ -278,6 +278,10 @@ loadaddr(Con *c, char *rn, E *e)
|
|||||||
s = "\tadrp\tR, SO\n"
|
s = "\tadrp\tR, SO\n"
|
||||||
"\tadd\tR, R, #:lo12:SO\n";
|
"\tadd\tR, R, #:lo12:SO\n";
|
||||||
break;
|
break;
|
||||||
|
case SExtThr:
|
||||||
|
if (!T.apple)
|
||||||
|
die("extern thread unavailable on arm64");
|
||||||
|
/* fall through */
|
||||||
case SThr:
|
case SThr:
|
||||||
if (T.apple)
|
if (T.apple)
|
||||||
s = "\tadrp\tR, S@tlvppage\n"
|
s = "\tadrp\tR, S@tlvppage\n"
|
||||||
@ -295,9 +299,6 @@ loadaddr(Con *c, char *rn, E *e)
|
|||||||
s = "\tadrp\tR, :got:SO\n"
|
s = "\tadrp\tR, :got:SO\n"
|
||||||
"\tldr\tR, [R, #:got_lo12:SO]\n";
|
"\tldr\tR, [R, #:got_lo12:SO]\n";
|
||||||
break;
|
break;
|
||||||
case SExtThr:
|
|
||||||
die("extern thread not yet implemented on arm64");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l = str(c->sym.id);
|
l = str(c->sym.id);
|
||||||
|
|||||||
@ -80,7 +80,7 @@ fixarg(Ref *pr, int k, int phi, Fn *fn)
|
|||||||
c = &fn->con[r0.val];
|
c = &fn->con[r0.val];
|
||||||
if (T.apple
|
if (T.apple
|
||||||
&& c->type == CAddr
|
&& c->type == CAddr
|
||||||
&& c->sym.type == SThr) {
|
&& (c->sym.type & SThr)) {
|
||||||
r1 = newtmp("isel", Kl, fn);
|
r1 = newtmp("isel", Kl, fn);
|
||||||
*pr = r1;
|
*pr = r1;
|
||||||
if (c->bits.i) {
|
if (c->bits.i) {
|
||||||
|
|||||||
@ -250,7 +250,7 @@ loadaddr(Con *c, char *rn, FILE *f)
|
|||||||
fputc('\n', f);
|
fputc('\n', f);
|
||||||
break;
|
break;
|
||||||
case SExtThr:
|
case SExtThr:
|
||||||
die("extern thread not yet implemented on rv64");
|
die("extern thread unavailable on rv64");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(f, "\tla %s, ", rn);
|
fprintf(f, "\tla %s, ", rn);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user