commit a4454de9af46344e812fd44794a3250c6672d928
parent df65c98be9835c3b071228f110f27524af18a964
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Sat, 16 May 2026 09:53:31 -0700
Fix inline asm memory operand addresses
Diffstat:
| M | src/api/cg.c | | | 49 | ++++++++++++++++++++++++++----------------------- |
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/src/api/cg.c b/src/api/cg.c
@@ -2379,6 +2379,29 @@ static void api_local_const_address_taken(CfreeCg *g, CfreeCgLocal local) {
api_local_const_clear(api_local_from_handle(g, local));
}
+static Operand api_lvalue_addr(CfreeCg *g, ApiSValue *v, CfreeCgTypeId pty) {
+ CGTarget *T;
+ ApiSourceLocal *rec;
+ Reg r;
+ Operand dst;
+ api_local_const_address_taken(g, v->source_local);
+ api_ensure_reg(g, v);
+ if (!api_is_lvalue_sv(v)) {
+ compiler_panic(g->c, g->cur_loc, "CfreeCg: addr operand is not an lvalue");
+ }
+ T = g->target;
+ r = api_alloc_reg_or_spill(g, RC_INT, pty);
+ dst = api_op_reg(r, pty);
+ rec = v->source_local != CFREE_CG_LOCAL_NONE
+ ? api_local_from_handle(g, v->source_local)
+ : NULL;
+ if (rec && rec->storage.kind == CG_LOCAL_STORAGE_REG && T->local_addr)
+ T->local_addr(T, dst, &rec->desc, rec->storage);
+ else
+ T->addr_of(T, dst, v->op);
+ return dst;
+}
+
static int api_local_const_can_track(CfreeCg *g, const ApiSourceLocal *rec,
CfreeCgMemAccess access) {
u32 width;
@@ -3432,31 +3455,13 @@ void cfree_cg_indirect(CfreeCg *g) {
void cfree_cg_addr(CfreeCg *g) {
ApiSValue v;
- CGTarget *T;
CfreeCgTypeId pty;
- Reg r;
Operand dst;
- ApiSourceLocal *rec;
if (!g)
return;
- T = g->target;
v = api_pop(g);
- api_local_const_address_taken(g, v.source_local);
- api_ensure_reg(g, &v);
- if (!api_is_lvalue_sv(&v)) {
- compiler_panic(g->c, g->cur_loc, "CfreeCg: addr operand is not an lvalue");
- return;
- }
pty = cg_type_ptr_to(g->c, api_sv_type(&v));
- r = api_alloc_reg_or_spill(g, RC_INT, pty);
- dst = api_op_reg(r, pty);
- rec = v.source_local != CFREE_CG_LOCAL_NONE
- ? api_local_from_handle(g, v.source_local)
- : NULL;
- if (rec && rec->storage.kind == CG_LOCAL_STORAGE_REG && T->local_addr)
- T->local_addr(T, dst, &rec->desc, rec->storage);
- else
- T->addr_of(T, dst, v.op);
+ dst = api_lvalue_addr(g, &v, pty);
api_release(g, &v);
api_push(g, api_make_sv(dst, pty));
}
@@ -4396,10 +4401,8 @@ void cfree_cg_inline_asm(CfreeCg *g, CfreeCgInlineAsm asm_block) {
} else if (api_is_lvalue_sv(&in_svs[i])) {
CfreeCgTypeId pty =
cg_type_ptr_to(g->c, ity ? ity : builtin_id(CFREE_CG_BUILTIN_VOID));
- Reg r = api_alloc_reg_or_spill(g, RC_INT, pty);
- Operand dst = api_op_reg(r, pty);
- T->addr_of(T, dst, in_svs[i].op);
- in_svs[i].op = api_op_indirect(r, 0, ity);
+ Operand dst = api_lvalue_addr(g, &in_svs[i], pty);
+ in_svs[i].op = api_op_indirect(dst.v.reg, 0, ity);
in_svs[i].res = RES_REG;
in_ops[i] = in_svs[i].op;
} else {