diff options
| author | Richard McCormack <[email protected]> | 2026-01-07 06:23:46 -0500 |
|---|---|---|
| committer | Quentin Carbonneaux <[email protected]> | 2026-01-13 21:24:31 +0100 |
| commit | cf06ce159d149b625a4eee2fdf2be0d54ccca49d (patch) | |
| tree | 47a245a725044b716f37555e86292ba7dd4c3169 /amd64/isel.c | |
| parent | 640c78d0dadffdaf309bc148ef02075676200657 (diff) | |
On x86_64, direct calls are always PC-relative. This means that
in order to call an absolute address, the call must be indirect.
To accomplish this, update fixarg to introduce a temporary before
emitting.
Diffstat (limited to 'amd64/isel.c')
| -rw-r--r-- | amd64/isel.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/amd64/isel.c b/amd64/isel.c index 73e0860..889c647 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -96,6 +96,14 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) a.offset.sym.id = intern(buf); fn->mem[fn->nmem-1] = a; } + else if (op == Ocall && r == &i->arg[0] + && rtype(r0) == RCon && fn->con[r0.val].type != CAddr) { + /* use a temporary register so that we + * produce an indirect call + */ + r1 = newtmp("isel", Kl, fn); + emit(Ocopy, Kl, r1, r0, R); + } else if (op != Ocopy && k == Kl && noimm(r0, fn)) { /* load constants that do not fit in * a 32bit signed integer into a |
