aboutsummaryrefslogtreecommitdiffhomepage
path: root/x86_64
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-25 13:28:56 +0100
committerlemon <lsof@mailbox.org>2025-12-25 13:28:56 +0100
commita6c2f8a9177eeae64b83e4aeafe46dbe310b3861 (patch)
treed7d4ad2a189170a5ca56a9b46f3571fb12d72bb4 /x86_64
parent882ea80770120e4f94e98e46ef824cafc9ccfe1f (diff)
avoid GOT relocations in unnecessary instances
Also change xcon to have a flagset for symbols (whether it's a function, locally defined; later: thread local, etc).
Diffstat (limited to 'x86_64')
-rw-r--r--x86_64/emit.c12
-rw-r--r--x86_64/isel.c2
2 files changed, 6 insertions, 8 deletions
diff --git a/x86_64/emit.c b/x86_64/emit.c
index 6f989f6..6e48965 100644
--- a/x86_64/emit.c
+++ b/x86_64/emit.c
@@ -336,12 +336,11 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o
int disp = mem.disp - 4 - offs[en->operenc];
internstr sym = xcon2sym(mem.con);
B(/*mod 0*/ (reg & 7) << 3 | RBP);
- if (objhassym(sym, &addr) == Stext) {
+ if (objhassym(sym, &addr) == Stext && mem.t != OSYMGOT) {
I32(addr - (*pcode - objout.textbegin) + disp);
} else {
enum relockind r = REL_PCREL32;
- if (mem.t == OSYMGOT)
- r = (rex ? REL_GOTPCRELX_REX : REL_GOTPCRELX);
+ if (mem.t == OSYMGOT) r = rex ? REL_GOTPCRELX_REX : REL_GOTPCRELX;
objreloc(xcon2sym(mem.con), r, Stext, *pcode - objout.textbegin, disp);
I32(0);
}
@@ -870,8 +869,8 @@ gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct ope
}
/* normal (not 2-address) case */
Lea:
- if (isaddrcon(addr->base,0) && (ccopt.pic || conht[addr->base.i].isfunc)
- && !objhassym(xcon2sym(addr->base.i), NULL)) {
+ if (isaddrcon(addr->base,0) && (ccopt.pic || (conht[addr->base.i].flag & SFUNC))
+ && !(conht[addr->base.i].flag & SLOCAL)) {
assert(!addr->disp && !addr->index.bits);
val = addr->base;
goto GOTLoad;
@@ -881,8 +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 || conht[val.i].isfunc)
- && !objhassym(xcon2sym(val.i), NULL)) {
+ if ((ccopt.pic || (conht[val.i].flag & SFUNC)) && !(conht[val.i].flag & SLOCAL)) {
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 9c99608..40d8db4 100644
--- a/x86_64/isel.c
+++ b/x86_64/isel.c
@@ -305,7 +305,7 @@ fuseaddr(union ref *r, struct block *blk, int *curi)
if (r->t != RSTACK && r->t != RTMP) return 0;
if (!aadd(&addr, blk, curi, *r)) return 0;
- if (isaddrcon(addr.base,0) && (ccopt.pic || (ccopt.pie && addr.index.bits) || conht[addr.base.i].isfunc)) {
+ if (isaddrcon(addr.base,0) && (ccopt.pic || (ccopt.pie && addr.index.bits) || (conht[addr.base.i].flag & SFUNC))) {
/* pic needs to load from GOT */
/* pie cannot encode RIP-relative address with index register */
/* first load symbol address into a temp register */