;'Egyptological' multiplier. XY_Lo and XY_Hi hold result of X*Y. (procedure fz_mul_egyptian ((x (fz :in)) (y (fz :in)) (xy_lo (fz :out)) (xy_hi (fz :out))) ((l (indices :constant) (length x)) ;Register holding running product (xy (fz 1 (+ (length x) (length y)))) ;X-Slide (xs (fz 1 (+ (length x) (length y))))) ;Product register begins empty (fz_clear xy) ;X-Slide initially equals X: (set (slice xs 1 (length x)) x) (set (slice xs (1+ (length x)) (last xs)) ((:others . 0))) ;For each word of Y: (for (i (range y)) ;Current word of Y ((w (word) (nth i y)) ;Current cut of XY and XS. Stay ahead by a word to handle carry. (cut (indices :constant) (+ l i)) (xyc (fz :renames (slice xy 1 cut))) (xsc (fz :renames (slice xs 1 cut)))) (for (b (nrange 1 bitness)) ;If current Y bit is 1, X-Slide Cut is added into XY Cut (fz_add_gated :x xyc :y xsc :sum xyc :gate (and w 1)) ;Crank the next bit of Y into the bottom position of W (set w (shift_right w 1)) ;X-Slide := X-Slide * 2 (fz_shiftleft xsc xsc 1))) ;Write out the Product's lower and upper FZs: (set xy_lo (slice xy 1 (length xy_lo))) (set xy_hi (slice xy (1+ (length xy_lo)) (last xy))))