diff options
| author | 2026-02-22 19:05:52 +0100 | |
|---|---|---|
| committer | 2026-02-22 19:05:52 +0100 | |
| commit | c13e1ec500a8a7ce6d41f0610ee1e71da50bb3b7 (patch) | |
| tree | 2a7050320918656c5d9521f258d8e1703039a35d /x86_64 | |
| parent | 975d76cfc99fcf797ebe0ac254dd3252405bd778 (diff) | |
driver: recognize shared libraries; & backend: misc fixes for PIC isel edgecases
Diffstat (limited to 'x86_64')
| -rw-r--r-- | x86_64/emit.c | 2 | ||||
| -rw-r--r-- | x86_64/isel.c | 10 |
2 files changed, 7 insertions, 5 deletions
diff --git a/x86_64/emit.c b/x86_64/emit.c index 0d7b77a..e54b7dd 100644 --- a/x86_64/emit.c +++ b/x86_64/emit.c @@ -880,7 +880,7 @@ gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct ope /* dst = 0 -> xor dst, dst; but only if it is ok to clobber flags */ Xxor(pcode, kisint(cls) ? KI32 : cls, dst, dst); } else if (isaddrcon(val,0)) { - if ((ccopt.pic || (contab.p[val.i].flag & SFUNC)) && !(contab.p[val.i].flag & SLOCAL)) { + if ((ccopt.pic || (contab.p[val.i].flag & SFUNC)) && (contab.p[val.i].flag & (SLOCAL|SFUNC)) != (SLOCAL|SFUNC)) { GOTLoad: /* for mov reg, [rip(sym@GOTPCREL)] */ Xmov(pcode, cls, dst, mkoper(OSYMGOT, .con = val.i, .cindex = NOINDEX)); diff --git a/x86_64/isel.c b/x86_64/isel.c index 7f82984..c3857c7 100644 --- a/x86_64/isel.c +++ b/x86_64/isel.c @@ -90,8 +90,8 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) } if (docopy) *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, con->cls, *r)); - } else if (op != Omove && con->issym && ins && r == &ins->r) { - *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, mkaddr((struct addr){*r}))); + } else if (op != Omove && (con->issym || (con->isdat && !con->deref)) && ins && r == &ins->r) { + *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, *r)); } else if (in_range(op, Odiv, Ourem) && kisint(ins->cls)) goto DivImm; } else if (r->t == RICON && in_range(op, Odiv, Ourem) && kisint(ins->cls) && r == &ins->r) { @@ -107,6 +107,8 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) *ins = adr; else *r = insertinstr(blk, (*curi)++, adr); + } else if (r->bits == UNDREF.bits && ins->op != Ocopy) { + *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, *r)); } picfixsym(r, blk, curi); } @@ -387,7 +389,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) case Ointrin: break; case Oshl: case Osar: case Oslr: - if (!iscon(ins->r)) { + if (!isintcon(ins->r)) { /* shift amount register is always CL */ insertinstr(blk, (*curi)++, mkinstr(Omove, KI32, mkref(RREG, RCX), ins->r)); ins->r = mkref(RREG, RCX); @@ -396,7 +398,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) case Oequ: case Oneq: case Olth: case Ogth: case Olte: case Ogte: case Oulth: case Ougth: case Oulte: case Ougte: - if (iscon(ins->l)) { + if (iscon(ins->l) && !iscon(ins->r)) { /* lth imm, x -> gth x, imm */ if (!in_range(ins->op, Oequ, Oneq)) ins->op = ((op - Olth) ^ 1) + Olth; |