lib/math: port math::checked (overflow + saturating arithmetic)
Port Hare's math::checked to lib/math/checked/ as a two-file module
mirroring the upstream split:
- checked.ww (ref/hare/math/checked/checked.ha): add*/sub*/mul*
returning (result, overflow) with wrapping semantics — addi/addu/
subi/subu 8-64 and muli/mulu 8-32 (22 fns).
- saturating.ww (ref/hare/math/checked/saturating.ha): sat_* clamping
to the type's range on overflow — sat_addi/addu/subi 8-64 and
sat_muli/mulu 8-32 (18 fns).
checked_test.ww drives the verbatim Hare @test vectors (crash-trick
idiom) via cross-module tuple-return destructure for the overflow fns;
wrapped by test/wcc/969_checked_run.c. Both stages emit byte-identical
asm; make test-unit green.
Three ww adaptations vs Hare, all forced by language differences, none
behavioral (documented at the sites):
- no if-as-expression -> `return if (c) X else Y` becomes if-stmt.
- no implicit integer promotion -> the mul overflow compares use an
explicit widening cast.
- sub-word arithmetic truncates only on store to a typed lvalue, so
unsigned overflow tests force the wrap through a typed `res`.
Deferred as faithful Hare-subsets (Hare splits per type; no inlining):
- size-typed *z variants: no `size` type yet (#85).
- int/uint native-width variants: ww int/uint are 64-bit, a silent
overflow-boundary width divergence.
- 64-bit muls (muli64/mulu64/powi64, sat_muli64/sat_mulu64) and the
muli/mulu dispatchers: need math::mulu64 (128-bit product).
- sat_subu8/16/32/64: need types::U*_MIN, not yet in lib/types.
Saturating sat_* reference the types limits at RUNTIME (conditional
return, not a const-initializer), which resolves cross-module today
(#88 is const-fold-only). subi64's I64_MAX/I64_MIN boundary @test vector
is omitted while #89 is open (its I64_MIN literal miscompiles on
wwstage); the saturating I64_MIN assertions use the types.I64_MIN
def-ref, which is byte-id clean.
This commit is contained in:
5
Makefile
5
Makefile
@@ -325,6 +325,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_adler32_run $(BIN)/test_crc16_run \
|
||||
$(BIN)/test_crc32_run $(BIN)/test_crc64_run \
|
||||
$(BIN)/test_siphash_run \
|
||||
$(BIN)/test_checked_run \
|
||||
$(BIN)/test_bufio_run $(BIN)/test_random_run
|
||||
|
||||
$(BIN)/test_smoke: test/wcc/000_smoke.c $(LIB)/libwcc.a | $(BIN)
|
||||
@@ -1048,6 +1049,10 @@ $(BIN)/test_random_run: test/wcc/999_random_run.c $(BIN)/ww $(BIN)/w6c \
|
||||
$(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_checked_run: test/wcc/969_checked_run.c $(BIN)/ww $(BIN)/w6c \
|
||||
$(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
sizelint:
|
||||
@sh tools/sizelint
|
||||
|
||||
|
||||
Reference in New Issue
Block a user