/* -*-c-*-
*
- * $Id: mpx.h,v 1.3 1999/11/13 01:51:29 mdw Exp $
+ * $Id: mpx.h,v 1.5 1999/11/20 22:23:27 mdw Exp $
*
* Low level multiprecision arithmetic
*
/*----- Revision history --------------------------------------------------*
*
* $Log: mpx.h,v $
+ * Revision 1.5 1999/11/20 22:23:27 mdw
+ * Add function versions of some low-level macros with wider use.
+ *
+ * Revision 1.4 1999/11/17 18:04:43 mdw
+ * Add two's complement support. Fix a bug in MPX_UMLAN.
+ *
* Revision 1.3 1999/11/13 01:51:29 mdw
* Minor interface changes. Should be stable now.
*
/*----- Unsigned arithmetic -----------------------------------------------*/
+/* --- @mpx_2c@ --- *
+ *
+ * Arguments: @mpw *dv, *dvl@ = destination vector
+ * @const mpw *v, *vl@ = source vector
+ *
+ * Returns: ---
+ *
+ * Use: Calculates the two's complement of @v@.
+ */
+
+extern void mpx_2c(mpw */*dv*/, mpw */*dvl*/,
+ const mpw */*v*/, const mpw */*vl*/);
+
/* --- @mpx_ucmp@ --- *
*
* Arguments: @const mpw *av, *avl@ = first argument vector base and limit
const mpw */*av*/, const mpw */*avl*/,
const mpw */*bv*/, const mpw */*bvl*/);
-/* --- @MPX_UADDN@ --- *
+/* --- @mpx_uaddn@ --- *
*
- * Arguments: @dv, dvl@ = source and destination vector base and limit
- * @n@ = other addend
+ * Arguments: @mpw *dv, *dvl@ = source and destination base and limit
+ * @mpw n@ = other addend
+ *
+ * Returns: ---
*
* Use: Adds a small integer to a multiprecision number.
*/
} \
} while (0)
+extern void mpx_uaddn(mpw */*dv*/, mpw */*dvl*/, mpw /*n*/);
+
/* --- @mpx_usub@ --- *
*
* Arguments: @mpw *dv, *dvl@ = destination vector base and limit
const mpw */*av*/, const mpw */*avl*/,
const mpw */*bv*/, const mpw */*bvl*/);
-/* --- @MPX_USUBN@ --- *
+/* --- @mpx_usubn@ --- *
+ *
+ * Arguments: @mpw *dv, *dvl@ = source and destination base and limit
+ * @n@ = subtrahend
*
- * Arguments: @@dv, dvl@ = destination vector base and limit
- * @n@ = other addend
+ * Returns: ---
*
* Use: Subtracts a small integer from a multiprecision number.
*/
} \
} while (0)
+extern void mpx_usubn(mpw */*dv*/, mpw */*dvl*/, mpw /*n*/);
+
/* --- @mpx_umul@ --- *
*
* Arguments: @mpw *dv, *dvl@ = destination vector base and limit
const mpw */*av*/, const mpw */*avl*/,
const mpw */*bv*/, const mpw */*bvl*/);
-/* --- @MPX_UMULN@ --- *
+/* --- @mpx_umuln@ --- *
*
- * Arguments: @dv, dvl@ = destination vector base and limit
- * @av, avl@ = multiplicand vector base and limit
- * @m@ = multiplier
+ * Arguments: @mpw *dv, *dvl@ = destination vector base and limit
+ * @const mpw *av, *avl@ = multiplicand vector base and limit
+ * @mpw m@ = multiplier
+ *
+ * Returns: ---
*
* Use: Multiplies a multiprecision integer by a single-word value.
* The destination and source may be equal. The destination
} \
} while (0)
-/* --- @MPX_UMLAN@ --- *
+extern void mpx_umuln(mpw */*dv*/, mpw */*dvl*/,
+ const mpw */*av*/, const mpw */*avl*/, mpw m);
+
+/* --- @mpx_umlan@ --- *
*
- * Arguments: @dv, dvl@ = destination/accumulator vector base and limit
- * @av, avl@ = multiplicand vector base and limit
- * @m@ = multiplier
+ * Arguments: @mpw *dv, *dvl@ = destination/accumulator base and limit
+ * @const mpw *av, *avl@ = multiplicand vector base and limit
+ * @mpw m@ = multiplier
+ *
+ * Returns: ---
*
* Use: Multiplies a multiprecision integer by a single-word value
* and adds the result to an accumulator.
#define MPX_UMLAN(dv, dvl, av, avl, m) do { \
mpw *_dv = (dv), *_dvl = (dvl); \
const mpw *_av = (av), *_avl = (avl); \
- mpw _c = 0; \
+ mpw _cc = 0; \
mpd _m = (m); \
\
while (_av < _avl) { \
mpd _x; \
if (_dv >= _dvl) \
break; \
- _x = (mpd)*_dv + (mpd)_m * (mpd)*_av++ + _c; \
+ _x = (mpd)*_dv + (mpd)_m * (mpd)*_av++ + _cc; \
*_dv++ = MPW(_x); \
- _c = _x >> MPW_BITS; \
+ _cc = _x >> MPW_BITS; \
} \
- MPX_UADDN(_dv, _dvl, _c); \
+ MPX_UADDN(_dv, _dvl, _cc); \
} while (0)
+extern void mpx_umlan(mpw */*dv*/, mpw */*dvl*/,
+ const mpw */*av*/, const mpw */*avl*/, mpw m);
+
/* --- @mpx_usqr@ --- *
*
* Arguments: @mpw *dv, *dvl@ = destination vector base and limit
* requiring the dividend to be in the result position but it
* does make some sense really. The remainder must have
* headroom for at least two extra words. The scratch space
- * must be at least two words larger than twice the size of the
- * divisor.
+ * must be at least one word larger than the divisor.
*/
extern void mpx_udiv(mpw */*qv*/, mpw */*qvl*/, mpw */*rv*/, mpw */*rvl*/,