/* umul.h -- unsigned multiply fixing UM* under D-3 constraints. * * DECOMPOSITION.md section 4 first said of UM* (since rewritten to be exact over * the full range; see test_foundation.c): "NEEDS REVISION: written for the carry-keeping * +* that D-3 rejected. With plain F18 +* the carry out of T is lost, so this * is only correct when the partial sums never overflow T (operands below 2^31). * A full-range UM* needs a correction step; to be rewritten and proven on the * golden model." * * D-3 states: "Plain F18 semantics. The carry out of T is not kept." * The +* defined in the F18 shifts T:A right; the add is T <- T+S when bit 0 * of A was set, but any carry out of that addition is discarded (not shifted * into the high part). That means UM* as written only works for inputs whose * partial products don't generate a carry beyond T's width during the loop. * * We need a correct full-range unsigned multiply (u1*u2 -> ulo, uhi) that is * correct for all cell-width values of u1,u2, expressed in terms of the v4 * primitives or at least specified precisely for the golden model. Since * we're building the golden model in C first, the canonical implementation is * the width-correct C multiplication split into high/low halves at V4_CELL_BITS. * This header provides both: a reference C implementation (for verification) * and a documented form that matches D-3's +* constraint. */ #ifndef V4_UMUL_H #define V4_UMUL_H #include "v4/cell.h" /* Unsigned multiply: (u1, u2) -> (ulo, uhi). Full range, width-correct. */ void v4_umul(v4_ucell u1, v4_ucell u2, v4_ucell *ulo, v4_ucell *uhi); #endif /* V4_UMUL_H */