diff --git a/amd64/emit.c b/amd64/emit.c index e5edc90..897a44f 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -551,19 +551,6 @@ emitins(Ins i, E *e) regtoa(i.to.val, SLong)); break; } - if (rtype(i.arg[0]) == RCon - && e->fn->con[i.arg[0].val].sym.type == SExt) { - /* 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); - fprintf(e->f, - "\tmovq %s%s@GOTPCREL(%%rip), %%%s\n", - sym[0] == '"' ? "" : T.assym, sym, - regtoa(i.to.val, SLong)); - break; - } if (!T.apple && rtype(i.arg[0]) == RCon && e->fn->con[i.arg[0].val].sym.type == SExtThr) { @@ -580,6 +567,19 @@ emitins(Ins i, E *e) regtoa(i.to.val, SLong)); break; } + if (rtype(i.arg[0]) == RCon + && e->fn->con[i.arg[0].val].sym.type == SExt) { + /* 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); + fprintf(e->f, + "\tmovq %s%s@gotpcrel(%%rip), %%%s\n", + sym[0] == '"' ? "" : T.assym, sym, + regtoa(i.to.val, SLong)); + break; + } goto Table; case Ocall: /* calls simply have a weird syntax in AT&T @@ -592,7 +592,7 @@ emitins(Ins i, E *e) if (con->type == CAddr && (con->sym.type & SExt) && !T.apple) - fprintf(e->f, "@PLT"); + fprintf(e->f, "@plt"); fprintf(e->f, "\n"); break; case RTmp: diff --git a/amd64/isel.c b/amd64/isel.c index b4769c3..031e0a9 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -121,11 +121,8 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) emit(Oaddr, Kl, r1, SLOT(s), R); } else if (op != Ocall && hascon(r0, &c, fn) - && c->type == CAddr && (c->sym.type & SExt) - && (!T.apple || c->sym.type == SExt)) { - /* extern symbols need indirection - * through the GOT - */ + && c->type == CAddr && ((c->sym.type & SExt) + || (T.apple && c->sym.type == SThr))) { r1 = newtmp("isel", Kl, fn); if (c->bits.i) { r2 = newtmp("isel", Kl, fn); @@ -135,38 +132,21 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) emit(Oadd, Kl, r1, r2, r3); } else r2 = r1; - cc = *c; - cc.bits.i = 0; - r3 = newcon(&cc, fn); - emit(Oaddr, Kl, r2, r3, R); - if (rtype(r0) == RMem) { - m = &fn->mem[r0.val]; - m->offset.type = CUndef; - m->base = r1; - r1 = r0; + if (T.apple && (c->sym.type & SThr)) { + emit(Ocopy, Kl, r2, TMP(RAX), R); + r2 = newtmp("isel", Kl, fn); + r3 = newtmp("isel", Kl, fn); + emit(Ocall, 0, R, r3, CALL(17)); + emit(Ocopy, Kl, TMP(RDI), r2, R); + emit(Oload, Kl, r3, r2, R); } - } - else if (T.apple && hascon(r0, &c, fn) - && c->type == CAddr && (c->sym.type & SThr)) { - r1 = newtmp("isel", Kl, fn); - if (c->bits.i) { - r2 = newtmp("isel", Kl, fn); - cc = (Con){.type = CBits}; - cc.bits.i = c->bits.i; - r3 = newcon(&cc, fn); - emit(Oadd, Kl, r1, r2, r3); - } else - r2 = r1; - emit(Ocopy, Kl, r2, TMP(RAX), R); - r2 = newtmp("isel", Kl, fn); - r3 = newtmp("isel", Kl, fn); - emit(Ocall, 0, R, r3, CALL(17)); - emit(Ocopy, Kl, TMP(RDI), r2, R); - emit(Oload, Kl, r3, r2, R); cc = *c; cc.bits.i = 0; r3 = newcon(&cc, fn); - emit(Oload, Kl, r2, r3, R); + if (T.apple && (c->sym.type & SThr)) + emit(Oload, Kl, r2, r3, R); + else + emit(Oaddr, Kl, r2, r3, R); if (rtype(r0) == RMem) { m = &fn->mem[r0.val]; m->offset.type = CUndef; @@ -177,9 +157,8 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) else if (!(isstore(op) && r == &i->arg[1]) && !isload(op) && op != Ocall && rtype(r0) == RCon && fn->con[r0.val].type == CAddr) { - /* apple as does not support 32-bit - * absolute addressing, use a rip- - * relative leaq instead + /* turn address operands into + * lea/mov instructions */ r1 = newtmp("isel", Kl, fn); emit(Oaddr, Kl, r1, r0, R);