X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/373641eaacc86b56715a2ebf0b603fce25c16051..7b0d1a63587f3cb1ae3bb8b248bbb1b82bdca7bd:/math/fgoldi.h diff --git a/math/fgoldi.h b/math/fgoldi.h index b05fd77e..6e351079 100644 --- a/math/fgoldi.h +++ b/math/fgoldi.h @@ -55,6 +55,13 @@ typedef union { # define FGOLDI_IMPL 12 #endif +#if FGOLDI_IMPL == 28 + typedef int32 fgoldi_piece; +#endif +#if FGOLDI_IMPL == 12 + typedef int16 fgoldi_piece; +#endif + /*----- Functions provided ------------------------------------------------*/ /* --- @fgoldi_load@ --- * @@ -127,6 +134,52 @@ extern void fgoldi_add(fgoldi */*z*/, extern void fgoldi_sub(fgoldi */*z*/, const fgoldi */*x*/, const fgoldi */*y*/); +/* --- @fgoldi_neg@ --- * + * + * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) + * @const fgoldi *x@ = an operand + * + * Returns: --- + * + * Use: Set @z = -x@. + */ + +extern void fgoldi_neg(fgoldi */*z*/, const fgoldi */*x*/); + +/* --- @fgoldi_pick2@ --- * + * + * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) + * @const fgoldi *x, *y@ = two operands + * @uint32 m@ = a mask + * + * Returns: --- + * + * Use: If @m@ is zero, set @z = y@; if @m@ is all-bits-set, then set + * @z = x@. If @m@ has some other value, then scramble @z@ in + * an unhelpful way. + */ + +extern void fgoldi_pick2(fgoldi */*z*/, + const fgoldi */*x*/, const fgoldi */*y*/, + uint32 /*m*/); + +/* --- @fgoldi_pickn@ --- * + * + * Arguments: @fgoldi *z@ = where to put the result + * @const fgoldi *v@ = a table of entries + * @size_t n@ = the number of entries in @v@ + * @size_t i@ = an index + * + * Returns: --- + * + * Use: If @0 <= i < n < 32@ then set @z = v[i]@. If @n >= 32@ then + * do something unhelpful; otherwise, if @i >= n@ then set @z@ + * to zero. + */ + +extern void fgoldi_pickn(fgoldi */*z*/, + const fgoldi */*v*/, size_t /*n*/, size_t /*i*/); + /* --- @fgoldi_condswap@ --- * * * Arguments: @fgoldi *x, *y@ = two operands @@ -141,6 +194,21 @@ extern void fgoldi_sub(fgoldi */*z*/, extern void fgoldi_condswap(fgoldi */*x*/, fgoldi */*y*/, uint32 /*m*/); +/* --- @fgoldi_condneg@ --- * + * + * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) + * @const fgoldi *x@ = an operand + * @uint32 m@ = a mask + * + * Returns: --- + * + * Use: If @m@ is zero, set @z = x@; if @m@ is all-bits-set, then set + * @z = -x@. If @m@ has some other value then scramble @z@ in + * an unhelpful way. + */ + +extern void fgoldi_condneg(fgoldi */*z*/, const fgoldi */*x*/, uint32 /*m*/); + /* --- @fgoldi_mulconst@ --- * * * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) @@ -193,6 +261,22 @@ extern void fgoldi_sqr(fgoldi */*z*/, const fgoldi */*x*/); extern void fgoldi_inv(fgoldi */*z*/, const fgoldi */*x*/); +/* --- @fgoldi_quosqrt@ --- * + * + * Arguments: @fgoldi *z@ = where to put the result (may alias @x@ or @y@) + * @const fgoldi *x, *y@ = two operands + * + * Returns: Zero if successful, @-1@ if %$x/y$% is not a square. + * + * Use: Stores in @z@ the one of the square roots %$\pm\sqrt{x/y}$%. + * If %$x = y = 0% then the result is zero; if %$y = 0$% but %$x + * \ne 0$% then the operation fails. If you wanted a specific + * square root then you'll have to pick it yourself. + */ + +extern int fgoldi_quosqrt(fgoldi */*z*/, + const fgoldi */*x*/, const fgoldi */*y*/); + /*----- That's all, folks -------------------------------------------------*/ #ifdef __cplusplus