kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit a6426a10c2e6ee9f983cedd3ac1ff386a91d7430
parent ab3b7e641d72f9d11e6be706098f0e12abd26967
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 27 May 2026 11:50:11 -0700

c/cg: emit FP add/sub for ++/-- on floating operands

pcg_inc_dec always lowered ++/-- via push_int + int_binop, so an
increment of a floating lvalue (e.g. mandelbrot's `++x`/`++y` loop
counters) emitted BO_IADD into an FP register, which the aarch64
backend cannot encode ("unsupported floating binary op"). Branch on the
operand type like pcg_binop does: floating operands step by 1.0 via an
FP add/sub, pointers by pointee size, everything else by 1. Factor the
shared step emission into pcg_emit_inc_step for the pre/post branches.

Diffstat:
Mlang/c/parse/cg_adapter.c | 33+++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lang/c/parse/cg_adapter.c b/lang/c/parse/cg_adapter.c @@ -844,6 +844,23 @@ void pcg_convert(Parser* p, const Type* dst) { pcg_retag_top(p, dst); } +/* Emit "value <op> step" for an inc/dec, picking the float or integer binop + * based on the operand type. Floating operands step by 1.0 via an FP add/sub; + * pointers step by the pointee size and everything else by 1. */ +static void pcg_emit_inc_step(Parser* p, const Type* ty, BinOp op, + CfreeCgIntBinOp cg_op, const Type* step_ty, + u32 step) { + if (pcg_type_is_fp(ty)) { + BinOp fop = (op == BO_ISUB) ? BO_FSUB : BO_FADD; + cfree_cg_push_float(p->cg, 1.0, pcg_tid(p, ty)); + cfree_cg_fp_binop(p->cg, pcg_fp_binop(fop), CFREE_CG_FP_NONE); + } else { + i64 amount = (ty && ty->kind == TY_PTR) ? (i64)step : 1; + cfree_cg_push_int(p->cg, amount, pcg_tid(p, step_ty)); + cfree_cg_int_binop(p->cg, cg_op, 0); + } +} + void pcg_inc_dec(Parser* p, BinOp op, int post) { const Type* ty = pcg_top_type(p); if (!pcg_emit_enabled(p)) { @@ -899,23 +916,15 @@ void pcg_inc_dec(Parser* p, BinOp op, int post) { cfree_cg_swap(p->cg); cfree_cg_store(p->cg, r_access, zero_ea); /* ..., lv-base[, idx], old */ - if (ty && ty->kind == TY_PTR) { - cfree_cg_push_int(p->cg, step, pcg_tid(p, step_ty)); - } else { - cfree_cg_push_int(p->cg, 1, pcg_tid(p, step_ty)); - } - cfree_cg_int_binop(p->cg, cg_op, 0); /* ..., lv-base[, idx], new */ + pcg_emit_inc_step(p, ty, op, cg_op, step_ty, + step); /* ..., lv-base[, idx], new */ cfree_cg_store(p->cg, access, ea); /* [] */ cfree_cg_push_local(p->cg, tmp); cfree_cg_load(p->cg, r_access, zero_ea); /* [old] */ } else { /* Compute new, stash new, store, then re-load new as result. */ - if (ty && ty->kind == TY_PTR) { - cfree_cg_push_int(p->cg, step, pcg_tid(p, step_ty)); - } else { - cfree_cg_push_int(p->cg, 1, pcg_tid(p, step_ty)); - } - cfree_cg_int_binop(p->cg, cg_op, 0); /* ..., lv-base[, idx], new */ + pcg_emit_inc_step(p, ty, op, cg_op, step_ty, + step); /* ..., lv-base[, idx], new */ cfree_cg_dup(p->cg); /* ..., lv-base[, idx], new, new */ cfree_cg_push_local(p->cg, tmp); cfree_cg_swap(p->cg);