From cf06ce159d149b625a4eee2fdf2be0d54ccca49d Mon Sep 17 00:00:00 2001 From: Richard McCormack Date: Wed, 7 Jan 2026 06:23:46 -0500 Subject: Modify amd64 fixarg to fix calling constant addresses 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. --- amd64/isel.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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 -- cgit v1.2.3