diff --git a/pkg/bits/bits.mpcl b/pkg/bits/bits.mpcl new file mode 100644 index 00000000..41036603 --- /dev/null +++ b/pkg/bits/bits.mpcl @@ -0,0 +1,17 @@ +// -*- go -*- + +package bits + +// Add returns the sum with carry of x, y and carry: sum = x + y + carry. +// The carry input must be 0 or 1; otherwise the behavior is undefined. +// The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Add(x, y, carry uint) (sum, carryOut uint) { + sum = x + y + carry + // The sum will overflow if both top bits are set (x & y) or if one of them + // is (x | y), and a carry from the lower place happened. If such a carry + // happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum). + carryOut = ((x & y) | ((x | y) &^ sum)) >> (size(carry)-1) + return +}