-
+ 7CA5191747D159092841AF1D29A5779075AB1C74F3CCAA94B187DC135D76819034CA9666AE01ABC3212D47A2BDDF06A56DAD178591646225B17E11801CDEEBAC
ffa/libffa/word_ops.adb
(0 . 0)(1 . 101)
879 ------------------------------------------------------------------------------
880 ------------------------------------------------------------------------------
881 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. --
882 -- --
883 -- (C) 2017 Stanislav Datskovskiy ( www.loper-os.org ) --
884 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html --
885 -- --
886 -- You do not have, nor can you ever acquire the right to use, copy or --
887 -- distribute this software ; Should you use this software for any purpose, --
888 -- or copy and distribute it to anyone or in any manner, you are breaking --
889 -- the laws of whatever soi-disant jurisdiction, and you promise to --
890 -- continue doing so for the indefinite future. In any case, please --
891 -- always : read and understand any software ; verify any PGP signatures --
892 -- that you use - for any purpose. --
893 -- --
894 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . --
895 ------------------------------------------------------------------------------
896 ------------------------------------------------------------------------------
897
898 with W_Shifts; use W_Shifts;
899
900 -- Fundamental Operations on Words:
901 package body Word_Ops is
902
903 -- Ada (like C) does not (portably) tell us over/underflow from arithmetic.
904 -- And there existed in the past, and apparently exist today, CPUs made
905 -- by idiots and wreckers (e.g. 'RISC-V') that do not have flags at all!
906
907 -- However, for multi-word addition, subtraction, the inner loop of
908 -- Comba's multiplication, and for a handful of other ops, we need it!
909
910 -- So we derive the Carry or Borrow at the 'eldest' binary position.
911 -- See the elementary proof (base case: 1 bit) further below:
912
913 -- Find the Carry, from an addition where it is known that A + B == S:
914 function W_Carry(A : in Word; B : in Word; S : in Word)
915 return WBool is
916 begin
917 return WBool(Shift_Right((A and B) or ((A or B) and (not S)),
918 Bitness - 1));
919 end W_Carry;
920 pragma Inline_Always(W_Carry);
921
922
923 -- Find the Borrow, from a subtraction where it is known that A - B == D:
924 function W_Borrow(A : in Word; B : in Word; D : in Word)
925 return WBool is
926 begin
927 return WBool(Shift_Right(((not A) and B) or (((not A) or B) and D),
928 Bitness - 1));
929 end W_Borrow;
930 pragma Inline_Always(W_Borrow);
931
932 -- A+B+C is the output bit of 1-bit adder; C is carry-in;
933 -- A-B-C is the output bit of 1-bit subber; C is borrow-in.
934 -- Observe that A+B+C is equal to A-B-C for all A,B,C !
935 -- +-+-+-+-----+--------------+-----+----------------+
936 -- | | 'Carry' out: | | 'Borrow' out: |
937 -- +-+-+-+-----+--------------+-----+----------------+
938 -- | | | | |(a and b) or | |(~a and b) or |
939 -- |A|B|C|A+B+C| ((a or b) and|A-B-C| ((~a or b) and |
940 -- | | | | | ~(A+B+C)) | | (A-B-C)) |
941 -- +-+-+-+-----+--------------+-----+----------------+
942 -- |0|0|0| 0 | 0 | 0 | 0 |
943 -- +-+-+-+-----+--------------+-----+----------------+
944 -- |1|0|0| 1 | 0 | 1 | 0 |
945 -- +-+-+-+-----+--------------+-----+----------------+
946 -- |0|1|0| 1 | 0 | 1 | 1 |
947 -- +-+-+-+-----+--------------+-----+----------------+
948 -- |1|1|0| 0 | 1 | 0 | 0 |
949 -- +-+-+-+-----+--------------+-----+----------------+
950 -- |0|0|1| 1 | 0 | 1 | 1 |
951 -- +-+-+-+-----+--------------+-----+----------------+
952 -- |1|0|1| 0 | 1 | 0 | 0 |
953 -- +-+-+-+-----+--------------+-----+----------------+
954 -- |0|1|1| 0 | 1 | 0 | 1 |
955 -- +-+-+-+-----+--------------+-----+----------------+
956 -- |1|1|1| 1 | 1 | 1 | 1 |
957 -- +-+-+-+-----+--------------+-----+----------------+
958 -- This base case extends to any N bit register, since
959 -- both equations depend ~strictly~ on A, B, and C.
960
961
962 -- Without any branching: if Sel == 0, return A; if Sel == 1, return B.
963 function W_Mux(A : in Word; B : in Word; Sel : in WBool) return Word is
964 begin
965 return B xor ((Sel - 1) and (A xor B));
966 end W_Mux;
967 pragma Inline_Always(W_Mux);
968
969
970 -- Exchange A and B.
971 procedure W_Swap(A : in out Word; B : in out Word) is
972 begin
973 A := A xor B;
974 B := A xor B;
975 A := A xor B;
976 end W_Swap;
977 pragma Inline_Always(W_Swap);
978
979 end Word_Ops;