diff options
| author | 2025-10-17 13:01:02 +0200 | |
|---|---|---|
| committer | 2025-10-17 13:01:02 +0200 | |
| commit | ed58941c2c5dc62d7c5703d4be205626f9c3389b (patch) | |
| tree | f279c8a3cf3526404046f4e5f8d124724f03360b /amd64 | |
| parent | d051c17c70c86b3c9bbc0a0761203d97e8c662d0 (diff) | |
codegen bugfix
Diffstat (limited to 'amd64')
| -rw-r--r-- | amd64/emit.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index b38141b..505735c 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -113,6 +113,8 @@ mkimmdatregoper(union ref r) return ref2oper(r); } +static int rbpoff; + static struct oper mkmemoper(union ref r) { @@ -124,6 +126,7 @@ mkmemoper(union ref r) } else if (r.t == RADDR) { const struct addr *addr = &addrht[r.i]; struct oper mem; + if (addr->base.t == RTMP && ioper(addr->base.i).t == OMEM) { mem = ioper(addr->base.i); if (addr->index.bits) addmemoper(&mem, mkregoper(addr->index)); @@ -337,11 +340,15 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o } I32(0); } else { - if (!usebp && mem.base == RBP) { - /* if RBP isn't being set up (leaf functions with no stack allocations), - * access thru RSP (function arguments in the stack) */ - mem.base = RSP; - mem.disp -= 8; + if (mem.base == RBP) { + if (!usebp) { + /* if RBP isn't being set up (leaf functions with no stack allocations), + * access thru RSP (function arguments in the stack) */ + mem.base = RSP; + mem.disp -= 8; + } else { + mem.disp += rbpoff; + } } if (mem.index == NOINDEX && mem.shift == 0) sib = 0; @@ -1150,6 +1157,7 @@ emitbin(struct function *fn) ++npush; } saverestore = calleesave(&npush, pcode, fn); + if (usebp) rbpoff = -(npush - 1)*8; /* ensure stack is 16-byte aligned for function calls */ if (!fn->isleaf && ((fn->stksiz + npush*8) & 0xF) != 0x8) { |