diff options
| author | 2025-10-23 10:14:11 +0200 | |
|---|---|---|
| committer | 2025-10-23 10:14:11 +0200 | |
| commit | 37643338d176c7612bddef054ae46c8cba8e352b (patch) | |
| tree | 5789e49292bddf1fef57d5fcb3d1585bfef0b43c /amd64/isel.c | |
| parent | 6149bc3a40e55ec6525aed42c9f2b2d480f20969 (diff) | |
amd64: load/store from abs address constants; movabs
Diffstat (limited to 'amd64/isel.c')
| -rw-r--r-- | amd64/isel.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/amd64/isel.c b/amd64/isel.c index 65ccfb7..6041faf 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -71,12 +71,13 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) *r = ZEROREF; else *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, con->cls, ZEROREF)); - } else if (kisflt(con->cls) || con->cls == KI8) { - /* float immediates & >32b immediates are loaded from memory */ + } else if (con->cls >= KI8) { + /* float immediates & 64bit immediates are loaded from memory */ uchar data[8]; uint siz = cls2siz[con->cls]; - if (con->cls == KI4) wr32le(data, con->i); - else if (con->cls != KF4) wr64le(data, con->i); + if (con->cls <= KPTR && in_range(ins->op, Ocopy, Omove)) /* in this case we can use movabs */ + return; + if (con->cls != KF4) wr64le(data, con->i); else { union { float f; int i; } pun = { con->f }; wr32le(data, pun.i); @@ -259,6 +260,18 @@ addarg4addrp(union ref r) } static void +loadstoreaddr(struct block *blk, union ref *r, int *curi) +{ + if (isimm32(*r)) { + *r = mkaddr((struct addr){.base = *r}); + } else if (!fuseaddr(r, blk, curi) && r->t != RTMP && r->t != RREG) { + *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, *r)); + } else { + picfixsym(r, blk, curi); + } +} + +static void sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) { uint siz, alignlog2; @@ -392,14 +405,10 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) break; case Oloads1: case Oloadu1: case Oloads2: case Oloadu2: case Oloads4: case Oloadu4: case Oloadi8: case Oloadf4: case Oloadf8: - if (!fuseaddr(&ins->l, blk, curi) && ins->l.t != RTMP && ins->l.t != RREG) - ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->l)); - picfixsym(&ins->l, blk, curi); + loadstoreaddr(blk, &ins->l, curi); break; case Ostore1: case Ostore2: case Ostore4: case Ostore8: - if (!fuseaddr(&ins->l, blk, curi) && ins->l.t != RTMP && ins->l.t != RREG) - ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->l)); - picfixsym(&ins->l, blk, curi); + loadstoreaddr(blk, &ins->l, curi); if (isaddrcon(ins->r)) ins->r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->r)); else |