commit 0986a6b96213303cda7b342b773bb15889415949
parent 5fced6f7c4c5295dfbfa8259fb79575e081f26f5
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 17 Jun 2026 06:10:07 -0700
arm32 rt: self-build the AEABI alias layer (no exclusions)
The full arm-eabi-thumb2 runtime now self-builds with kit's own assembler —
AEABI + coro, the §3 exit-criterion. Three pieces:
- aeabi_thumb2.S / aeabi_thumb1.S: the soft-float compare helpers used GNU
numeric local labels (1:/1f) the assembler doesn't implement; since the macros
are cond-parameterized, use per-cond named labels (Laeabi_dcmp_<cond>) — no
numeric-label feature needed (it is used nowhere else in the rt asm).
- si_div.c: add __divmodsi4 (signed 32-bit divmod). kit's own codegen never
calls it (ARMv7-M has hardware SDIV+MLS) but __aeabi_idivmod wraps it; the
other three combined helpers (u/divmod{si,di}4) were already present.
- mk/rt.mk: RT_arm-eabi-thumb2_AEABI = thumb2, and add RT_LIB_INCS to RT_ASFLAGS
so hand-written .S can #include the common assembly.h (the .c path already had
it). All 19 __aeabi_* entry points assemble with correct encodings; the
dcmp/fcmp helpers + an external direct call verify correct under qemu.
(The coroutine *layer* also self-builds and setjmp/longjmp round-trips; the full
coro_init/resume/yield runtime fault is a separate coro/coro.c issue, still open.)
Diffstat:
4 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/mk/rt.mk b/mk/rt.mk
@@ -219,16 +219,14 @@ RT_arm-eabi-thumb2_INT128 = 0
# is built at all; the asm itself disassembles byte-correct) — tracked in
# doc/plan/ARM32.md.
RT_arm-eabi-thumb2_CORO = arm32
-# AEABI alias layer (aeabi.c + aeabi_thumb2.S) is hand-written ARM asm. kit-as
-# assembles most of it (the ';' SEPARATOR, '#imm'-in-macro under __ASSEMBLER__,
-# __ELF__/.type %function path, SP-relative stack manipulation) but the
-# soft-float compare helpers (DEFINE_AEABI_DCMP/FCMP) use GNU numeric local
-# labels (1:/1f/1b) the assembler does not yet support — so the AEABI layer is
-# still dropped from the kit self-build. kit-compiled code references the
-# libgcc-named helpers (__udivdi3 / __adddf3 / ...) the compiler-rt C sources
-# provide, not the __aeabi_* aliases, so ordinary programs are unaffected.
-# Re-enabling `= thumb2` is gated on numeric-local-label support in kit-as.
-RT_arm-eabi-thumb2_AEABI =
+# AEABI alias layer (aeabi.c + aeabi_thumb2.S) is hand-written ARM asm that now
+# self-builds with kit's own assembler: the ';' SEPARATOR, '#imm'-in-macro under
+# __ASSEMBLER__, the __ELF__/.type %function path, and SP-relative stack
+# manipulation all land, and the soft-float compare helpers use per-cond named
+# labels (Laeabi_dcmp_<cond>) rather than GNU numeric local labels, which kit-as
+# does not implement. All 19 __aeabi_* entry points assemble with correct
+# encodings + symbols.
+RT_arm-eabi-thumb2_AEABI = thumb2
RT_arm-eabi-thumb1_TARGET = arm-none-eabi
RT_arm-eabi-thumb1_ABI = ilp32
@@ -320,6 +318,7 @@ RT_CFLAGS_$(1) := \
$$(if $$(RT_$(1)_CORO),-Irt/include)
RT_ASFLAGS_$(1) := \
-target $$(RT_$(1)_TARGET) \
+ $$(RT_LIB_INCS) \
$$(RT_$(1)_ARCH_FLAGS) \
-DHAS_INT128=$$(RT_$(1)_INT128) \
-D__ASSEMBLER__=1 \
diff --git a/rt/lib/arm/aeabi_thumb1.S b/rt/lib/arm/aeabi_thumb1.S
@@ -80,10 +80,10 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
CONVERT_DCMP_ARGS_TO_DF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
cmp r0, #0 SEPARATOR \
- b ## cond 1f SEPARATOR \
+ b ## cond Laeabi_dcmp_ ## cond SEPARATOR \
movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
-1: SEPARATOR \
+Laeabi_dcmp_ ## cond : SEPARATOR \
movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)
@@ -118,10 +118,10 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
CONVERT_FCMP_ARGS_TO_SF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
cmp r0, #0 SEPARATOR \
- b ## cond 1f SEPARATOR \
+ b ## cond Laeabi_fcmp_ ## cond SEPARATOR \
movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
-1: SEPARATOR \
+Laeabi_fcmp_ ## cond : SEPARATOR \
movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)
diff --git a/rt/lib/arm/aeabi_thumb2.S b/rt/lib/arm/aeabi_thumb2.S
@@ -80,10 +80,10 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
CONVERT_DCMP_ARGS_TO_DF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
cmp r0, #0 SEPARATOR \
- b ## cond 1f SEPARATOR \
+ b ## cond Laeabi_dcmp_ ## cond SEPARATOR \
movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
-1: SEPARATOR \
+Laeabi_dcmp_ ## cond : SEPARATOR \
movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)
@@ -118,10 +118,10 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
CONVERT_FCMP_ARGS_TO_SF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
cmp r0, #0 SEPARATOR \
- b ## cond 1f SEPARATOR \
+ b ## cond Laeabi_fcmp_ ## cond SEPARATOR \
movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
-1: SEPARATOR \
+Laeabi_fcmp_ ## cond : SEPARATOR \
movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)
diff --git a/rt/lib/int/si_div.c b/rt/lib/int/si_div.c
@@ -43,3 +43,14 @@ COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) {
su_int q = __udivsi3(ua, ub);
return (si_int)((q ^ sign) - sign);
}
+
+// Signed 32-bit divmod (quotient returned, remainder via *rem). kit's own
+// codegen never calls this (ARMv7-M has hardware SDIV + MLS), but the AEABI
+// alias layer's __aeabi_idivmod wraps it; the unsigned __udivmodsi4 above and
+// the 64-bit __divmoddi4/__udivmoddi4 (int/int.c) were already present, this
+// was the one missing combined helper.
+COMPILER_RT_ABI si_int __divmodsi4(si_int a, si_int b, si_int* rem) {
+ si_int d = __divsi3(a, b);
+ *rem = a - (d * b);
+ return d;
+}