kit

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

commit cedc6e279cc8d9847ee4fa43c9d9010b7ec1b6bb
parent 5a0e24dcba8784c652d4be3e3b6640564fcf52b4
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 16 Jun 2026 22:38:01 -0700

arm32: atomic addr via pointer reg; toy @target_arch arm32; test applicability

- arm_atomic_addr_reg: use the pointer's own register when the address already is
  one (the -O1 case) instead of always materializing into LR — LR may hold an
  atomic value operand the optimizer staged there, so the old code emitted e.g.
  'strex r4, lr, [lr]' storing the base instead of the desired value.
- toy_target_code: map KIT_ARCH_ARM_32 -> 5 (the .arm32 selector) so
  @target_arch() switches resolve on arm32; add the .arm32 arm to
  47_target_arch_switch.
- 145_baremetal_privileged_aa64: add a .arm32.skip (aarch64-only DAIF/wfe/sev,
  no M-profile lowering).

Diffstat:
Mlang/toy/expr.c | 2++
Msrc/arch/arm32/native.c | 15++++++++++++---
Atest/toy/cases/145_baremetal_privileged_aa64.arm32.skip | 1+
Mtest/toy/cases/47_target_arch_switch.toy | 3+++
4 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/lang/toy/expr.c b/lang/toy/expr.c @@ -536,6 +536,8 @@ int toy_target_code(ToyParser* p) { return 3; case KIT_ARCH_RV32: return 6; + case KIT_ARCH_ARM_32: + return 5; /* matches the `.arm32` dot-constant selector */ case KIT_ARCH_WASM: return 7; default: diff --git a/src/arch/arm32/native.c b/src/arch/arm32/native.c @@ -2187,9 +2187,18 @@ static int arm_order_release(KitCgMemOrder o) { * may be a frame slot or a register; load_addr lands the pointer in lr, which * the LDREX/STREX sequence then uses as the base. */ static u32 arm_atomic_addr_reg(Arm32NativeTarget* a, NativeAddr addr) { - NativeLoc dst = - native_loc_reg(builtin_id(KIT_CG_BUILTIN_I32), NATIVE_REG_INT, ARM_TMP); - arm_load_addr(&a->base, dst, addr); + /* Use the pointer's own register when the address already is one (the -O1 + * case: the optimizer collapses &x into a register distinct from the atomic + * value operands). Materializing into LR would collide with a value operand + * the optimizer staged in LR (an emit scratch). Otherwise (a FRAME/GLOBAL + * address, e.g. -O0) materialize into LR, which holds no operand there. */ + if (addr.base_kind == NATIVE_ADDR_BASE_REG && addr.offset == 0 && + addr.index_kind == NATIVE_ADDR_INDEX_NONE) + return addr.base.reg & 0xfu; + arm_load_addr(&a->base, + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I32), NATIVE_REG_INT, + ARM_TMP), + addr); return ARM_TMP; } diff --git a/test/toy/cases/145_baremetal_privileged_aa64.arm32.skip b/test/toy/cases/145_baremetal_privileged_aa64.arm32.skip @@ -0,0 +1 @@ +aarch64-only: exercises DAIF irq-mask + wfe/sev intrinsics that have no M-profile (PRIMASK/WFE differ) lowering; the case is gated to aarch64 by name. diff --git a/test/toy/cases/47_target_arch_switch.toy b/test/toy/cases/47_target_arch_switch.toy @@ -12,6 +12,9 @@ fn __user_main(): i64 { .rv32 { 40 } + .arm32 { + 40 + } .wasm { 40 }