commit bc320ed9645db020921f11869a38e2e951c8db9d
parent 0980ffb0ad7001c3752a5c02e8e003f5cef1f36c
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 7 May 2026 18:34:53 -0700
rt/Makefile
Diffstat:
8 files changed, 214 insertions(+), 225 deletions(-)
diff --git a/rt/Makefile b/rt/Makefile
@@ -0,0 +1,206 @@
+CC = clang
+AR = llvm-ar
+OUT = build
+
+COMMON_CFLAGS = -ffreestanding -fno-builtin -std=c11 -Wpedantic -Wall -Wextra -Werror
+LIB_INCS = -Ilib/include/common -Ilib/impl
+
+VARIANTS = \
+ x86_64-linux \
+ x86_64-apple-darwin \
+ aarch64-linux \
+ aarch64-apple-darwin \
+ riscv64-elf \
+ riscv64-elf-save-restore \
+ x86_64-pc-windows \
+ i386-linux \
+ wasm32 \
+ riscv32-elf \
+ riscv32-elf-save-restore \
+ arm-eabi-thumb2 \
+ arm-eabi-thumb1
+
+.PHONY: all-targets $(VARIANTS)
+all-targets: $(VARIANTS)
+
+$(VARIANTS):
+ $(MAKE) VARIANT=$@ OUT=build/$@ all
+
+# ---------- variant feature flags --------------------------------------------
+# Select a named variant with VARIANT=, or override individual flags directly.
+#
+# TARGET — clang target triple (required)
+# ABI — lp64 | ilp32 | llp64
+# INT128 — 0 | 1
+# CORO — x86_64 | x86_64_win | i386 | aarch64 |
+# arm32 | arm32_thumb1 | riscv32 | riscv64 | (empty = none)
+# LDBL128 — 0 | 1 (long double = binary128; only aarch64-linux)
+# SAVE_RESTORE — 0 | 1 (RISC-V save-restore routines)
+# AEABI — thumb2 | thumb1 | (empty = none)
+# ARCH_FLAGS — extra target-specific flags (e.g. -mabi=lp64 -march=rv64imafd)
+
+VARIANT ?= aarch64-apple-darwin
+
+ifeq ($(VARIANT),x86_64-linux)
+ TARGET = x86_64-linux-gnu
+ ABI = lp64
+ INT128 = 1
+ CORO = x86_64
+endif
+ifeq ($(VARIANT),x86_64-apple-darwin)
+ TARGET = x86_64-apple-darwin
+ ABI = lp64
+ INT128 = 1
+ CORO = x86_64
+endif
+ifeq ($(VARIANT),aarch64-linux)
+ TARGET = aarch64-linux-gnu
+ ABI = lp64
+ INT128 = 1
+ CORO = aarch64
+ LDBL128 = 1
+endif
+ifeq ($(VARIANT),aarch64-apple-darwin)
+ TARGET = aarch64-apple-darwin
+ ABI = lp64
+ INT128 = 1
+ CORO = aarch64
+endif
+ifeq ($(VARIANT),riscv64-elf)
+ TARGET = riscv64-unknown-elf
+ ABI = lp64
+ INT128 = 1
+ CORO = riscv64
+ ARCH_FLAGS = -mabi=lp64 -march=rv64imafd
+endif
+ifeq ($(VARIANT),riscv64-elf-save-restore)
+ TARGET = riscv64-unknown-elf
+ ABI = lp64
+ INT128 = 1
+ CORO = riscv64
+ SAVE_RESTORE = 1
+ ARCH_FLAGS = -mabi=lp64 -march=rv64imafd
+endif
+ifeq ($(VARIANT),x86_64-pc-windows)
+ TARGET = x86_64-pc-windows-msvc
+ ABI = llp64
+ INT128 = 1
+ CORO = x86_64_win
+endif
+ifeq ($(VARIANT),i386-linux)
+ TARGET = i386-linux-gnu
+ ABI = ilp32
+ INT128 = 0
+ CORO = i386
+endif
+ifeq ($(VARIANT),wasm32)
+ TARGET = wasm32-unknown-unknown
+ ABI = ilp32
+ INT128 = 0
+endif
+ifeq ($(VARIANT),riscv32-elf)
+ TARGET = riscv32-unknown-elf
+ ABI = ilp32
+ INT128 = 0
+ CORO = riscv32
+ ARCH_FLAGS = -mabi=ilp32 -march=rv32imafd
+endif
+ifeq ($(VARIANT),riscv32-elf-save-restore)
+ TARGET = riscv32-unknown-elf
+ ABI = ilp32
+ INT128 = 0
+ CORO = riscv32
+ SAVE_RESTORE = 1
+ ARCH_FLAGS = -mabi=ilp32 -march=rv32imafd
+endif
+ifeq ($(VARIANT),arm-eabi-thumb2)
+ TARGET = arm-none-eabi
+ ABI = ilp32
+ INT128 = 0
+ CORO = arm32
+ AEABI = thumb2
+endif
+ifeq ($(VARIANT),arm-eabi-thumb1)
+ TARGET = arm-none-eabi
+ ABI = ilp32
+ INT128 = 0
+ CORO = arm32_thumb1
+ AEABI = thumb1
+endif
+
+# defaults for unset flags
+ABI ?= lp64
+INT128 ?= 1
+CORO ?=
+LDBL128 ?= 0
+SAVE_RESTORE ?= 0
+AEABI ?=
+ARCH_FLAGS ?=
+
+# ---------- sources derived from features ------------------------------------
+SRCS = lib/int/int.c lib/fp/fp.c lib/mem/mem.c lib/atomic/atomic_freestanding.c
+
+ifeq ($(ABI),lp64)
+ SRCS += lib/int64/int64.c
+ ABI_INC = -Ilib/include/lp64_le
+endif
+ifeq ($(ABI),llp64)
+ SRCS += lib/int64/int64.c
+ ABI_INC = -Ilib/include/llp64_le
+endif
+ifeq ($(ABI),ilp32)
+ SRCS += lib/int32/int32.c
+ ABI_INC = -Ilib/include/ilp32_le
+endif
+
+ifeq ($(LDBL128),1)
+ SRCS += lib/fp_tf/fp_tf.c lib/fp_ti/fp_ti.c
+ LDBL128_FLAGS = -Ilib/include/lp64_le_ldbl128 \
+ -include lib/include/lp64_le_ldbl128/tf_supplement.h
+endif
+
+ifneq ($(CORO),)
+ SRCS += lib/coro/$(CORO).c lib/coro/coro.c
+ CORO_INC = -Iinclude
+endif
+
+ifeq ($(SAVE_RESTORE),1)
+ ifeq ($(ABI),lp64)
+ SRCS += lib/riscv/rv64.S
+ else
+ SRCS += lib/riscv/rv32.S
+ endif
+ ARCH_FLAGS += -msave-restore
+endif
+
+ifeq ($(AEABI),thumb2)
+ SRCS += lib/arm/aeabi_thumb2.S lib/arm/aeabi.c
+ ARCH_FLAGS += -march=armv7-a -mthumb -mfloat-abi=soft
+endif
+ifeq ($(AEABI),thumb1)
+ SRCS += lib/arm/aeabi_thumb1.S lib/arm/aeabi.c
+ ARCH_FLAGS += -march=armv6-m -mthumb -mfloat-abi=soft
+endif
+
+# ---------- compiler flags from features -------------------------------------
+CFLAGS = $(COMMON_CFLAGS) $(LIB_INCS)
+CFLAGS += --target=$(TARGET) -DHAS_INT128=$(INT128)
+CFLAGS += $(ABI_INC) $(ARCH_FLAGS) $(LDBL128_FLAGS) $(CORO_INC)
+
+# ---------- rules -------------------------------------------------------------
+OBJS = $(patsubst lib/%,$(OUT)/%.o,$(SRCS))
+
+.PHONY: all clean
+
+all: $(OUT)/libcfree_rt.a
+
+$(OBJS): $(OUT)/%.o: lib/%
+ @mkdir -p $(dir $@)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OUT)/libcfree_rt.a: $(OBJS)
+ @mkdir -p $(dir $@)
+ $(AR) rcs $@ $^
+
+clean:
+ rm -rf $(OUT)
diff --git a/rt/lib/atomic/atomic_common.inc b/rt/lib/atomic/atomic_common.inc
@@ -84,6 +84,9 @@ bool __atomic_is_lock_free_c(size_t size, void *ptr) {
return false;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Watomic-alignment"
+
void __atomic_load_c(int size, void *src, void *dest, int model) {
#define LOCK_FREE_ACTION(type) \
*((type *)dest) = __atomic_load_n((type *)src, model); \
@@ -236,3 +239,5 @@ OPTIMISED_CASES
#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW_NAND(n, lockfree, type)
OPTIMISED_CASES
#undef OPTIMISED_CASE
+
+#pragma clang diagnostic pop
diff --git a/rt/lib/atomic/atomic_freestanding.c b/rt/lib/atomic/atomic_freestanding.c
@@ -20,6 +20,8 @@ static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1;
typedef _Atomic(uintptr_t) Lock;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Watomic-alignment"
static inline void unlock(Lock *l) {
__atomic_store_n((uintptr_t *)l, 0, __ATOMIC_RELEASE);
}
@@ -30,6 +32,7 @@ static inline void lock(Lock *l) {
__ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
old = 0;
}
+#pragma clang diagnostic pop
static Lock locks[SPINLOCK_COUNT];
diff --git a/rt/lib/build.sh b/rt/lib/build.sh
@@ -1,206 +0,0 @@
-#!/bin/sh
-#
-# build2.sh — POSIX sh port of build.sh. Same behavior, no arrays, no
-# pipefail, no local. Source/flag lists are space-separated strings;
-# unquoted expansion does the splitting.
-
-set -u
-
-cd "$(dirname "$0")" || exit 1
-
-CC=${CC:-clang}
-AR=${AR:-llvm-ar}
-OUT=${OUT:-/tmp/cfree_rt_build}
-
-COMMON_FLAGS="-c -ffreestanding -fno-builtin -Wall -Wextra -Iinclude/common -Iimpl"
-
-mkdir -p "$OUT"
-OK=0
-FAIL=0
-FAILED_VARIANTS=""
-
-#-------------------------------------------------------------------------------
-# build_variant <name> <extra-cc-flags> <sources>
-#-------------------------------------------------------------------------------
-build_variant() {
- name=$1
- flags=$2
- sources=$3
-
- out="$OUT/$name"
- mkdir -p "$out"
- log="$out/build.log"
- : >"$log"
-
- objs=""
- nfail=0
- total=0
- for src in $sources; do
- total=$((total+1))
- obj="$out/$(echo "$src" | tr / _).o"
- if $CC $COMMON_FLAGS $flags -o "$obj" "$src" >>"$log" 2>&1; then
- objs="$objs $obj"
- else
- nfail=$((nfail+1))
- echo "FAIL: $src" >>"$log"
- fi
- done
-
- if [ $nfail -ne 0 ]; then
- printf " %-32s FAIL (%d/%d sources failed; see %s)\n" \
- "$name" "$nfail" "$total" "$log"
- FAIL=$((FAIL+1))
- FAILED_VARIANTS="$FAILED_VARIANTS $name"
- return
- fi
-
- if command -v "$AR" >/dev/null 2>&1; then
- archive="$OUT/libcfree_rt-$name.a"
- if $AR rcs "$archive" $objs 2>>"$log"; then
- printf " %-32s OK (%d objs → %s)\n" \
- "$name" "$total" "$(basename "$archive")"
- else
- printf " %-32s OK (%d objs; %s failed to archive)\n" \
- "$name" "$total" "$AR"
- fi
- else
- printf " %-32s OK (%d objs; %s not found, no archive)\n" \
- "$name" "$total" "$AR"
- fi
- OK=$((OK+1))
-}
-
-#-------------------------------------------------------------------------------
-# Source sets — one master .c (and/or .S) per feature flag. Each master
-# #include's its per-op snippets in dependency order; the per-op files
-# are NOT compiled directly.
-#-------------------------------------------------------------------------------
-INT_C="int/int.c"
-INT32_C="int32/int32.c"
-INT64_C="int64/int64.c"
-FP_C="fp/fp.c"
-FP_TF_C="fp_tf/fp_tf.c"
-FP_TI_C="fp_ti/fp_ti.c"
-MEM_C="mem/mem.c"
-ATOMIC_C="atomic/atomic_freestanding.c"
-
-# ARM AEABI: one master .S per ISA mode (Thumb2 vs Thumb1) plus one
-# ISA-agnostic .c (drsub + frsub).
-ARM_AEABI_THUMB2="arm/aeabi_thumb2.S arm/aeabi.c"
-ARM_AEABI_THUMB1="arm/aeabi_thumb1.S arm/aeabi.c"
-
-# RISC-V save/restore: one master .S per xlen.
-RV32_SR="riscv/rv32.S"
-RV64_SR="riscv/rv64.S"
-
-# Coro + setjmp/longjmp:
-# coro/coro.c -- arch-agnostic asymmetric layer (coro_init,
-# coro_resume, coro_yield, coro_self).
-# coro/<arch>.c -- per-arch primitives (setjmp / longjmp /
-# __cfree_coro_ctx_init / __cfree_coro_switch /
-# __cfree_coro_trampoline).
-# Every variant that ships coro picks one <arch>.c plus the common file.
-CORO_COMMON="coro/coro.c"
-CORO_X86_64="coro/x86_64.c"
-CORO_X86_64_WIN="coro/x86_64_win.c"
-CORO_I386="coro/i386.c"
-CORO_AARCH64="coro/aarch64.c"
-CORO_ARM32="coro/arm32.c"
-CORO_ARM32_THUMB1="coro/arm32_thumb1.c"
-CORO_RV32="coro/riscv32.c"
-CORO_RV64="coro/riscv64.c"
-
-#-------------------------------------------------------------------------------
-# Variants
-#-------------------------------------------------------------------------------
-echo "Building libcfree_rt for every supported (target, mode) tuple"
-echo " CC=$CC, AR=$AR, OUT=$OUT"
-echo
-
-# ---- LP64 little-endian ------------------------------------------------------
-LP64_BASE="$INT_C $INT64_C $FP_C $MEM_C $ATOMIC_C"
-
-# Coro impl needs cfree's own headers (setjmp.h, cfree/coro.h).
-CORO_INC="-I../include"
-
-build_variant x86_64-linux \
- "--target=x86_64-linux-gnu -Iinclude/lp64_le -DHAS_INT128=1 $CORO_INC" \
- "$LP64_BASE $CORO_X86_64 $CORO_COMMON"
-
-build_variant x86_64-apple-darwin \
- "--target=x86_64-apple-darwin -Iinclude/lp64_le -DHAS_INT128=1 $CORO_INC" \
- "$LP64_BASE $CORO_X86_64 $CORO_COMMON"
-
-# aarch64-linux: long double is binary128; needs fp_tf + fp_ti and the
-# tf_supplement.h pre-include.
-build_variant aarch64-linux \
- "--target=aarch64-linux-gnu \
- -Iinclude/lp64_le_ldbl128 -Iinclude/lp64_le -DHAS_INT128=1 \
- -include include/lp64_le_ldbl128/tf_supplement.h $CORO_INC" \
- "$INT_C $INT64_C $FP_C $FP_TF_C $FP_TI_C $MEM_C $ATOMIC_C $CORO_AARCH64 $CORO_COMMON"
-
-build_variant aarch64-apple-darwin \
- "--target=aarch64-apple-darwin -Iinclude/lp64_le -DHAS_INT128=1 $CORO_INC" \
- "$LP64_BASE $CORO_AARCH64 $CORO_COMMON"
-
-build_variant riscv64-elf \
- "--target=riscv64-unknown-elf -mabi=lp64 -march=rv64imafd \
- -Iinclude/lp64_le -DHAS_INT128=1 $CORO_INC" \
- "$LP64_BASE $CORO_RV64 $CORO_COMMON"
-
-build_variant riscv64-elf-save-restore \
- "--target=riscv64-unknown-elf -mabi=lp64 -march=rv64imafd -msave-restore \
- -Iinclude/lp64_le -DHAS_INT128=1 $CORO_INC" \
- "$LP64_BASE $RV64_SR $CORO_RV64 $CORO_COMMON"
-
-# ---- LLP64 little-endian (Win64) --------------------------------------------
-build_variant x86_64-pc-windows \
- "--target=x86_64-pc-windows-msvc -Iinclude/llp64_le -DHAS_INT128=1 $CORO_INC" \
- "$INT_C $INT64_C $FP_C $MEM_C $ATOMIC_C $CORO_X86_64_WIN $CORO_COMMON"
-
-# ---- ILP32 little-endian -----------------------------------------------------
-ILP32_BASE="$INT_C $INT32_C $FP_C $MEM_C $ATOMIC_C"
-
-build_variant i386-linux \
- "--target=i386-linux-gnu -Iinclude/ilp32_le -DHAS_INT128=0 $CORO_INC" \
- "$ILP32_BASE $CORO_I386 $CORO_COMMON"
-
-# wasm32: no setjmp/coro impl yet -- Emscripten fibers / sjlj are a
-# separate runtime model that hasn't been ported to cfree.
-build_variant wasm32 \
- "--target=wasm32-unknown-unknown -Iinclude/ilp32_le -DHAS_INT128=0" \
- "$ILP32_BASE"
-
-build_variant riscv32-elf \
- "--target=riscv32-unknown-elf -mabi=ilp32 -march=rv32imafd \
- -Iinclude/ilp32_le -DHAS_INT128=0 $CORO_INC" \
- "$ILP32_BASE $CORO_RV32 $CORO_COMMON"
-
-build_variant riscv32-elf-save-restore \
- "--target=riscv32-unknown-elf -mabi=ilp32 -march=rv32imafd -msave-restore \
- -Iinclude/ilp32_le -DHAS_INT128=0 $CORO_INC" \
- "$ILP32_BASE $RV32_SR $CORO_RV32 $CORO_COMMON"
-
-build_variant arm-eabi-thumb2 \
- "--target=arm-none-eabi -march=armv7-a -mthumb -mfloat-abi=soft \
- -Iinclude/ilp32_le -DHAS_INT128=0 $CORO_INC" \
- "$ILP32_BASE $ARM_AEABI_THUMB2 $CORO_ARM32 $CORO_COMMON"
-
-# arm-eabi-thumb1 (Cortex-M0/M0+, ARMv6-M): Thumb-1 ISA, no IT blocks,
-# data-processing ops restricted to r0-r7, no VFP. Coro impl is a
-# separate file from arm32.c since the asm sequences don't share.
-build_variant arm-eabi-thumb1 \
- "--target=arm-none-eabi -march=armv6-m -mthumb -mfloat-abi=soft \
- -Iinclude/ilp32_le -DHAS_INT128=0 $CORO_INC" \
- "$ILP32_BASE $ARM_AEABI_THUMB1 $CORO_ARM32_THUMB1 $CORO_COMMON"
-
-#-------------------------------------------------------------------------------
-echo
-echo "Summary: $OK ok, $FAIL failed"
-if [ $FAIL -ne 0 ]; then
- echo "Failed variants:"
- for v in $FAILED_VARIANTS; do
- echo " - $v ($OUT/$v/build.log)"
- done
- exit 1
-fi
diff --git a/rt/lib/include/ilp32_le/int_lib.h b/rt/lib/include/ilp32_le/int_lib.h
@@ -64,11 +64,6 @@ typedef union { su_int u; float f; } float_bits;
typedef union { udwords u; double f; } double_bits;
typedef struct { udwords low; udwords high; } uqwords;
-typedef float _Complex Fcomplex;
-typedef double _Complex Dcomplex;
-typedef long double _Complex Lcomplex;
-#define COMPLEX_REAL(x) __real__(x)
-#define COMPLEX_IMAGINARY(x) __imag__(x)
#endif // INT_TYPES_H
#include "int_util.h"
diff --git a/rt/lib/include/llp64_le/int_lib.h b/rt/lib/include/llp64_le/int_lib.h
@@ -79,11 +79,6 @@ typedef union { su_int u; float f; } float_bits;
typedef union { udwords u; double f; } double_bits;
typedef struct { udwords low; udwords high; } uqwords;
-typedef float _Complex Fcomplex;
-typedef double _Complex Dcomplex;
-typedef long double _Complex Lcomplex;
-#define COMPLEX_REAL(x) __real__(x)
-#define COMPLEX_IMAGINARY(x) __imag__(x)
#endif // INT_TYPES_H
#include "int_util.h"
diff --git a/rt/lib/include/lp64_le/int_lib.h b/rt/lib/include/lp64_le/int_lib.h
@@ -86,11 +86,6 @@ typedef struct { udwords low; udwords high; } uqwords;
// include/lp64_le_ldbl128/tf_supplement.h when compiling lib/fp_tf/. Not
// available in this base header to keep it free of feature ifdefs.
-typedef float _Complex Fcomplex;
-typedef double _Complex Dcomplex;
-typedef long double _Complex Lcomplex;
-#define COMPLEX_REAL(x) __real__(x)
-#define COMPLEX_IMAGINARY(x) __imag__(x)
#endif // INT_TYPES_H
#include "int_util.h"
diff --git a/rt/lib/include/lp64_le_ldbl128/tf_supplement.h b/rt/lib/include/lp64_le_ldbl128/tf_supplement.h
@@ -24,9 +24,5 @@ typedef long double tf_float;
typedef union { uqwords u; tf_float f; } tf_bits;
-typedef Lcomplex Qcomplex;
-#define CRT_HAS_NATIVE_COMPLEX_F128
-#define COMPLEXTF_REAL(x) __real__(x)
-#define COMPLEXTF_IMAGINARY(x) __imag__(x)
#endif