1/*-
  2 * Copyright (c) 2018 Netflix, Inc.
  3 * All rights reserved.
  4 *
  5 * Redistribution and use in source and binary forms, with or without
  6 * modification, are permitted provided that the following conditions
  7 * are met:
  8 * 1. Redistributions of source code must retain the above copyright
  9 *    notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 *    notice, this list of conditions and the following disclaimer in the
 12 *    documentation and/or other materials provided with the distribution.
 13 *
 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 24 * SUCH DAMAGE.
 25 */
 26
 27/*
 28 * Data types and APIs for fixed-point math based on the "Q" number format.
 29 *
 30 * Author: Lawrence Stewart <lstewart@netflix.com>
 31 *
 32 * The 3 LSBs of all base data types are reserved for embedded control data:
 33 *   bits 1-2 specify the radix point shift index i.e. 00,01,10,11 == 1,2,3,4
 34 *   bit 3 specifies the radix point shift index multiplier as 2 (0) or 16 (1)
 35 *
 36 * This scheme can therefore represent Q numbers with [2,4,6,8,16,32,48,64] bits
 37 * of precision after the binary radix point. The number of bits available for
 38 * the integral component depends on the underlying storage type chosen.
 39 */
 40
 41#ifndef	_SYS_QMATH_H_
 42#define	_SYS_QMATH_H_
 43
 44#include <machine/_stdint.h>
 45
 46typedef int8_t		s8q_t;
 47typedef uint8_t		u8q_t;
 48typedef int16_t		s16q_t;
 49typedef uint16_t	u16q_t;
 50typedef int32_t		s32q_t;
 51typedef uint32_t	u32q_t;
 52typedef int64_t		s64q_t;
 53typedef uint64_t	u64q_t;
 54/* typedef int128_t	s128q_t; Not yet */
 55/* typedef uint128_t	u128q_t; Not yet */
 56typedef	s64q_t		smaxq_t;
 57typedef	u64q_t		umaxq_t;
 58
 59#if defined(__GNUC__) && !defined(__clang__)
 60/* Ancient GCC hack to de-const, remove when GCC4 is removed. */
 61#define	Q_BT(q)		__typeof(1 * q)
 62#else
 63/* The underlying base type of 'q'. */
 64#define	Q_BT(q)		__typeof(q)
 65#endif
 66
 67/* Type-cast variable 'v' to the same underlying type as 'q'. */
 68#define	Q_TC(q, v)	((__typeof(q))(v))
 69
 70/* Number of total bits associated with the data type underlying 'q'. */
 71#define	Q_NTBITS(q)	((uint32_t)(sizeof(q) << 3))
 72
 73/* Number of LSBs reserved for control data. */
 74#define	Q_NCBITS	((uint32_t)3)
 75
 76/* Number of control-encoded bits reserved for fractional component data. */
 77#define	Q_NFCBITS(q) \
 78    ((uint32_t)(((Q_GCRAW(q) & 0x3) + 1) << ((Q_GCRAW(q) & 0x4) ? 4 : 1)))
 79
 80/* Min/max number of bits that can be reserved for fractional component data. */
 81#define	Q_MINNFBITS(q)	((uint32_t)(2))
 82#define	Q_MAXNFBITS(q)	((uint32_t)(Q_NTBITS(q) - Q_SIGNED(q) - Q_NCBITS))
 83
 84/*
 85 * Number of bits actually reserved for fractional component data. This can be
 86 * less than the value returned by Q_NFCBITS() as we treat any excess
 87 * control-encoded number of bits for the underlying data type as meaning all
 88 * available bits are reserved for fractional component data i.e. zero int bits.
 89 */
 90#define	Q_NFBITS(q) \
 91    (Q_NFCBITS(q) > Q_MAXNFBITS(q) ? Q_MAXNFBITS(q) : Q_NFCBITS(q))
 92
 93/* Number of bits available for integer component data. */
 94#define	Q_NIBITS(q)	((uint32_t)(Q_NTBITS(q) - Q_RPSHFT(q) - Q_SIGNED(q)))
 95
 96/* The radix point offset relative to the LSB. */
 97#define	Q_RPSHFT(q)	(Q_NCBITS + Q_NFBITS(q))
 98
 99/* The sign bit offset relative to the LSB. */
100#define	Q_SIGNSHFT(q)	(Q_NTBITS(q) - 1)
101
102/* Set the sign bit to 0 ('isneg' is F) or 1 ('isneg' is T). */
103#define	Q_SSIGN(q, isneg) \
104    ((q) = ((Q_SIGNED(q) && (isneg)) ?	(q) | (1ULL << Q_SIGNSHFT(q)) : \
105					(q) & ~(1ULL << Q_SIGNSHFT(q))))
106
107/* Manipulate the 'q' bits holding control/sign data. */
108#define	Q_CRAWMASK(q)	0x7ULL
109#define	Q_SRAWMASK(q)	(1ULL << Q_SIGNSHFT(q))
110#define	Q_GCRAW(q)	((q) & Q_CRAWMASK(q))
111#define	Q_GCVAL(q)	Q_GCRAW(q)
112#define	Q_SCVAL(q, cv)	((q) = ((q) & ~Q_CRAWMASK(q)) | (cv))
113
114/* Manipulate the 'q' bits holding combined integer/fractional data. */
115#define	Q_IFRAWMASK(q) \
116    Q_TC(q, Q_SIGNED(q) ? ~(Q_SRAWMASK(q) | Q_CRAWMASK(q)) : ~Q_CRAWMASK(q))
117#define	Q_IFMAXVAL(q)	Q_TC(q, Q_IFRAWMASK(q) >> Q_NCBITS)
118#define	Q_IFMINVAL(q)	Q_TC(q, Q_SIGNED(q) ? -Q_IFMAXVAL(q) : 0)
119#define	Q_IFVALIMASK(q)	Q_TC(q, ~Q_IFVALFMASK(q))
120#define	Q_IFVALFMASK(q)	Q_TC(q, (1ULL << Q_NFBITS(q)) - 1)
121#define	Q_GIFRAW(q)	Q_TC(q, (q) & Q_IFRAWMASK(q))
122#define	Q_GIFABSVAL(q)	Q_TC(q, Q_GIFRAW(q) >> Q_NCBITS)
123#define	Q_GIFVAL(q)	Q_TC(q, Q_LTZ(q) ? -Q_GIFABSVAL(q) : Q_GIFABSVAL(q))
124#define	Q_SIFVAL(q, ifv) \
125    ((q) = ((q) & (~(Q_SRAWMASK(q) | Q_IFRAWMASK(q)))) | \
126    (Q_TC(q, Q_ABS(ifv)) << Q_NCBITS) | \
127    (Q_LTZ(ifv) ? 1ULL << Q_SIGNSHFT(q) : 0))
128#define	Q_SIFVALS(q, iv, fv) \
129    ((q) = ((q) & (~(Q_SRAWMASK(q) | Q_IFRAWMASK(q)))) | \
130    (Q_TC(q, Q_ABS(iv)) << Q_RPSHFT(q)) | \
131    (Q_TC(q, Q_ABS(fv)) << Q_NCBITS) | \
132    (Q_LTZ(iv) || Q_LTZ(fv) ? 1ULL << Q_SIGNSHFT(q) : 0))
133
134/* Manipulate the 'q' bits holding integer data. */
135#define	Q_IRAWMASK(q)	Q_TC(q, Q_IFRAWMASK(q) & ~Q_FRAWMASK(q))
136#define	Q_IMAXVAL(q)	Q_TC(q, Q_IRAWMASK(q) >> Q_RPSHFT(q))
137#define	Q_IMINVAL(q)	Q_TC(q, Q_SIGNED(q) ? -Q_IMAXVAL(q) : 0)
138#define	Q_GIRAW(q)	Q_TC(q, (q) & Q_IRAWMASK(q))
139#define	Q_GIABSVAL(q)	Q_TC(q, Q_GIRAW(q) >> Q_RPSHFT(q))
140#define	Q_GIVAL(q)	Q_TC(q, Q_LTZ(q) ? -Q_GIABSVAL(q) : Q_GIABSVAL(q))
141#define	Q_SIVAL(q, iv) \
142    ((q) = ((q) & ~(Q_SRAWMASK(q) | Q_IRAWMASK(q))) | \
143    (Q_TC(q, Q_ABS(iv)) << Q_RPSHFT(q)) | \
144    (Q_LTZ(iv) ? 1ULL << Q_SIGNSHFT(q) : 0))
145
146/* Manipulate the 'q' bits holding fractional data. */
147#define	Q_FRAWMASK(q)	Q_TC(q, ((1ULL << Q_NFBITS(q)) - 1) << Q_NCBITS)
148#define	Q_FMAXVAL(q)	Q_TC(q, Q_FRAWMASK(q) >> Q_NCBITS)
149#define	Q_GFRAW(q)	Q_TC(q, (q) & Q_FRAWMASK(q))
150#define	Q_GFABSVAL(q)	Q_TC(q, Q_GFRAW(q) >> Q_NCBITS)
151#define	Q_GFVAL(q)	Q_TC(q, Q_LTZ(q) ? -Q_GFABSVAL(q) : Q_GFABSVAL(q))
152#define	Q_SFVAL(q, fv) \
153    ((q) = ((q) & ~(Q_SRAWMASK(q) | Q_FRAWMASK(q))) | \
154    (Q_TC(q, Q_ABS(fv)) << Q_NCBITS) | \
155    (Q_LTZ(fv) ? 1ULL << Q_SIGNSHFT(q) : 0))
156
157/*
158 * Calculate the number of bits required per 'base' digit, rounding up or down
159 * for non power-of-two bases.
160 */
161#define	Q_BITSPERBASEDOWN(base) (flsll(base) - 1)
162#define	Q_BITSPERBASEUP(base) (flsll(base) - (__builtin_popcountll(base) == 1))
163#define	Q_BITSPERBASE(base, rnd) Q_BITSPERBASE##rnd(base)
164
165/*
166 * Upper bound number of digits required to render 'nbits' worth of integer
167 * component bits with numeric base 'base'. Overestimates for power-of-two
168 * bases.
169 */
170#define	Q_NIBITS2NCHARS(nbits, base)					\
171({									\
172 	int _bitsperbase = Q_BITSPERBASE(base, DOWN);			\
173	(((nbits) + _bitsperbase - 1) / _bitsperbase);			\
174})
175
176#define	Q_NFBITS2NCHARS(nbits, base) (nbits)
177
178/*
179 * Maximum number of chars required to render 'q' as a C-string of base 'base'.
180 * Includes space for sign, radix point and NUL-terminator.
181 */
182#define	Q_MAXSTRLEN(q, base) \
183    (2 + Q_NIBITS2NCHARS(Q_NIBITS(q), base) + \
184    Q_NFBITS2NCHARS(Q_NFBITS(q), base) + Q_SIGNED(q))
185
186/* Yield the next char from integer bits. */
187#define	Q_IBITS2CH(q, bits, base)					\
188({									\
189    __typeof(bits) _tmp = (bits) / (base);				\
190    int _idx = (bits) - (_tmp * (base));				\
191    (bits) = _tmp;							\
192    "0123456789abcdef"[_idx];						\
193})
194
195/* Yield the next char from fractional bits. */
196#define	Q_FBITS2CH(q, bits, base)					\
197({									\
198    int _carry = 0, _idx, _nfbits = Q_NFBITS(q), _shift = 0;		\
199    /*									\
200     * Normalise enough MSBs to yield the next digit, multiply by the	\
201     * base, and truncate residual fractional bits post multiplication.	\
202     */									\
203    if (_nfbits > Q_BITSPERBASEUP(base)) {				\
204        /* Break multiplication into two steps to ensure no overflow. */\
205        _shift = _nfbits >> 1;						\
206        _carry = (((bits) & ((1ULL << _shift) - 1)) * (base)) >> _shift;\
207    }									\
208    _idx = ((((bits) >> _shift) * (base)) + _carry) >> (_nfbits - _shift);\
209    (bits) *= (base); /* With _idx computed, no overflow concern. */	\
210    (bits) &= (1ULL << _nfbits) - 1; /* Exclude residual int bits. */	\
211    "0123456789abcdef"[_idx];						\
212})
213
214/*
215 * Render the C-string representation of 'q' into 's'. Returns a pointer to the
216 * final '\0' to allow for easy calculation of the rendered length and easy
217 * appending to the C-string.
218 */
219#define	Q_TOSTR(q, prec, base, s, slen)					\
220({									\
221	char *_r, *_s = s;						\
222	int _i;								\
223	if (Q_LTZ(q) && ((ptrdiff_t)(slen)) > 0)			\
224		*_s++ = '-';						\
225	Q_BT(q) _part = Q_GIABSVAL(q);					\
226	_r = _s;							\
227	do {								\
228		/* Render integer chars in reverse order. */		\
229		if ((_s - (s)) < ((ptrdiff_t)(slen)))			\
230			*_s++ = Q_IBITS2CH(q, _part, base);		\
231		else							\
232			_r = NULL;					\
233	} while (_part > 0 && _r != NULL);				\
234	if (!((_s - (s)) < ((ptrdiff_t)(slen))))			\
235		_r = NULL;						\
236	_i = (_s - _r) >> 1; /* N digits requires int(N/2) swaps. */	\
237	while (_i-- > 0 && _r != NULL) {				\
238		/* Work from middle out to reverse integer chars. */	\
239		*_s = *(_r + _i); /* Stash LHS char temporarily. */	\
240		*(_r + _i) = *(_s - _i - 1); /* Copy RHS char to LHS. */\
241		*(_s - _i - 1) = *_s; /* Copy LHS char to RHS. */	\
242	}								\
243	_i = (prec);							\
244	if (_i != 0 && _r != NULL) {					\
245		if ((_s - (s)) < ((ptrdiff_t)(slen)))			\
246			*_s++ = '.';					\
247		else							\
248			_r = NULL;					\
249		_part = Q_GFABSVAL(q);					\
250		if (_i < 0 || _i > (int)Q_NFBITS(q))			\
251			_i = Q_NFBITS(q);				\
252		while (_i-- > 0 && _r != NULL) {			\
253			/* Render fraction chars in correct order. */	\
254			if ((_s - (s)) < ((ptrdiff_t)(slen)))		\
255				*_s++ = Q_FBITS2CH(q, _part, base);	\
256			else						\
257				_r = NULL;				\
258		}							\
259	}								\
260	if ((_s - (s)) < ((ptrdiff_t)(slen)) && _r != NULL)		\
261		*_s = '\0';						\
262	else {								\
263		_r = NULL;						\
264		if (((ptrdiff_t)(slen)) > 0)				\
265			*(s) = '\0';					\
266	}								\
267	/* Return a pointer to the '\0' or NULL on overflow. */		\
268	(_r != NULL ? _s : _r);						\
269})
270
271/* Left shift an integral value to align with the int bits of 'q'. */
272#define	Q_SHL(q, iv) \
273    (Q_LTZ(iv) ? -(int64_t)(Q_ABS(iv) << Q_NFBITS(q)) :	\
274    Q_TC(q, iv) << Q_NFBITS(q))
275
276/* Calculate the relative fractional precision between 'a' and 'b' in bits. */
277#define	Q_RELPREC(a, b)	((int)Q_NFBITS(a) - (int)Q_NFBITS(b))
278
279/*
280 * Determine control bits for the desired 'rpshft' radix point shift. Rounds up
281 * to the nearest valid shift supported by the encoding scheme.
282 */
283#define	Q_CTRLINI(rpshft) \
284    (((rpshft) <= 8) ? (((rpshft) - 1) >> 1) : (0x4 | (((rpshft) - 1) >> 4)))
285
286/*
287 * Convert decimal fractional value 'dfv' to its binary-encoded representation
288 * with 'nfbits' of binary precision. 'dfv' must be passed as a preprocessor
289 * literal to preserve leading zeroes. The returned result can be used to set a
290 * Q number's fractional bits e.g. using Q_SFVAL().
291 */
292#define	Q_DFV2BFV(dfv, nfbits)				\
293({							\
294	uint64_t _bfv = 0, _thresh = 5, _tmp = dfv;	\
295	int _i = sizeof(""#dfv) - 1;			\
296	/*						\
297	 * Compute decimal threshold to determine which \
298	 * conversion rounds will yield a binary 1.	\
299	 */						\
300	while (--_i > 0) {_thresh *= 10;}		\
301	_i = (nfbits) - 1;				\
302	while (_i >= 0) {				\
303		if (_thresh <= _tmp) {			\
304			_bfv |= 1ULL << _i;		\
305			_tmp = _tmp - _thresh;		\
306		}					\
307		_i--; _tmp <<= 1;			\
308	}						\
309	_bfv;						\
310})
311
312/*
313 * Initialise 'q' with raw integer value 'iv', decimal fractional value 'dfv',
314 * and radix point shift 'rpshft'. Must be done in two steps in case 'iv'
315 * depends on control bits being set e.g. when passing Q_INTMAX(q) as 'iv'.
316 */
317#define	Q_INI(q, iv, dfv, rpshft) \
318({ \
319    (*(q)) = Q_CTRLINI(rpshft); \
320    Q_SIFVALS(*(q), iv, Q_DFV2BFV(dfv, Q_NFBITS(*(q)))); \
321})
322
323/* Test if 'a' and 'b' fractional precision is the same (T) or not (F). */
324#define	Q_PRECEQ(a, b)	(Q_NFBITS(a) == Q_NFBITS(b))
325
326/* Test if 'n' is a signed type (T) or not (F). Works with any numeric type. */
327#define	Q_SIGNED(n)	(Q_TC(n, -1) < 0)
328
329/*
330 * Test if 'n' is negative. Works with any numeric type that uses the MSB as the
331 * sign bit, and also works with Q numbers.
332 */
333#define	Q_LTZ(n)	(Q_SIGNED(n) && ((n) & Q_SRAWMASK(n)))
334
335/*
336 * Return absolute value of 'n'. Works with any standard numeric type that uses
337 * the MSB as the sign bit, and is signed/unsigned type safe.
338 * Does not work with Q numbers; use Q_QABS() instead.
339 */
340#define	Q_ABS(n)	(Q_LTZ(n) ? -(n) : (n))
341
342/*
343 * Return an absolute value interpretation of 'q'.
344 */
345#define	Q_QABS(q)	(Q_SIGNED(q) ? (q) & ~Q_SRAWMASK(q) : (q))
346
347/* Convert 'q' to float or double representation. */
348#define	Q_Q2F(q)	((float)Q_GIFVAL(q) / (float)(1ULL << Q_NFBITS(q)))
349#define	Q_Q2D(q)	((double)Q_GIFVAL(q) / (double)(1ULL << Q_NFBITS(q)))
350
351/* Numerically compare 'a' and 'b' as whole numbers using provided operators. */
352#define	Q_QCMPQ(a, b, intcmp, fraccmp) \
353    ((Q_GIVAL(a) intcmp Q_GIVAL(b)) || \
354    ((Q_GIVAL(a) == Q_GIVAL(b)) && (Q_GFVAL(a) fraccmp Q_GFVAL(b))))
355
356/* Test if 'a' is numerically less than 'b' (T) or not (F). */
357#define	Q_QLTQ(a, b)	Q_QCMPQ(a, b, <, <)
358
359/* Test if 'a' is numerically less than or equal to 'b' (T) or not (F). */
360#define	Q_QLEQ(a, b)	Q_QCMPQ(a, b, <, <=)
361
362/* Test if 'a' is numerically greater than 'b' (T) or not (F). */
363#define	Q_QGTQ(a, b)	Q_QCMPQ(a, b, >, >)
364
365/* Test if 'a' is numerically greater than or equal to 'b' (T) or not (F). */
366#define	Q_QGEQ(a, b)	Q_QCMPQ(a, b, >, >=)
367
368/* Test if 'a' is numerically equal to 'b' (T) or not (F). */
369#define	Q_QEQ(a, b)	Q_QCMPQ(a, b, ==, ==)
370
371/* Test if 'a' is numerically not equal to 'b' (T) or not (F). */
372#define	Q_QNEQ(a, b)	Q_QCMPQ(a, b, !=, !=)
373
374/* Returns the numerically larger of 'a' and 'b'. */
375#define	Q_QMAXQ(a, b)	(Q_GT(a, b) ? (a) : (b))
376
377/* Returns the numerically smaller of 'a' and 'b'. */
378#define	Q_QMINQ(a, b)	(Q_LT(a, b) ? (a) : (b))
379
380/*
381 * Test if 'a' can be represented by 'b' with full accuracy (T) or not (F).
382 * The type casting has to be done to a's type so that any truncation caused by
383 * the casts will not affect the logic.
384 */
385#define	Q_QCANREPQ(a, b) \
386    ((((Q_LTZ(a) && Q_SIGNED(b)) || !Q_LTZ(a)) && \
387    Q_GIABSVAL(a) <= Q_TC(a, Q_IMAXVAL(b)) && \
388    Q_GFABSVAL(a) <= Q_TC(a, Q_FMAXVAL(b))) ? \
389    0 : EOVERFLOW)
390
391/* Test if raw integer value 'i' can be represented by 'q' (T) or not (F). */
392#define	Q_QCANREPI(q, i) \
393    ((((Q_LTZ(i) && Q_SIGNED(q)) || !Q_LTZ(i)) && \
394    Q_ABS(i) <= Q_TC(i, Q_IMAXVAL(q))) ? 0 : EOVERFLOW)
395
396/*
397 * Returns a Q variable debug format string with appropriate modifiers and
398 * padding relevant to the underlying Q data type.
399 */
400#define	Q_DEBUGFMT_(prefmt, postfmt, mod, hexpad)			\
401    prefmt								\
402    /* Var name + address. */						\
403    "\"%s\"@%p"								\
404    /* Data type. */							\
405    "\n\ttype=%c%dq_t, "						\
406    /* Qm.n notation; 'm' = # int bits, 'n' = # frac bits. */		\
407    "Qm.n=Q%d.%d, "							\
408    /* Radix point shift relative to the underlying data type's LSB. */	\
409    "rpshft=%d, "							\
410    /* Min/max integer values which can be represented. */		\
411    "imin=0x%0" #mod "x, "						\
412    "imax=0x%0" #mod "x"						\
413    /* Raw hex dump of all bits. */					\
414    "\n\tqraw=0x%0" #hexpad #mod "x"					\
415    /* Bit masks for int/frac/ctrl bits. */				\
416    "\n\timask=0x%0" #hexpad #mod "x, "					\
417    "fmask=0x%0" #hexpad #mod "x, "					\
418    "cmask=0x%0" #hexpad #mod "x, "					\
419    "ifmask=0x%0" #hexpad #mod "x"					\
420    /* Hex dump of masked int bits; 'iraw' includes shift */		\
421    "\n\tiraw=0x%0" #hexpad #mod "x, "					\
422    "iabsval=0x%" #mod "x, "						\
423    "ival=0x%" #mod "x"					\
424    /* Hex dump of masked frac bits; 'fraw' includes shift */		\
425    "\n\tfraw=0x%0" #hexpad #mod "x, "					\
426    "fabsval=0x%" #mod "x, "						\
427    "fval=0x%" #mod "x"							\
428    "%s"								\
429    postfmt
430
431#define	Q_DEBUGFMT(q, prefmt, postfmt)					\
432      sizeof(q) == 8 ? Q_DEBUGFMT_(prefmt, postfmt, j, 16)	:	\
433      sizeof(q) == 4 ? Q_DEBUGFMT_(prefmt, postfmt,  , 8)	:	\
434      sizeof(q) == 2 ? Q_DEBUGFMT_(prefmt, postfmt, h, 4)	:	\
435      sizeof(q) == 1 ? Q_DEBUGFMT_(prefmt, postfmt, hh, 2)	:	\
436      prefmt "\"%s\"@%p: invalid" postfmt				\
437
438/*
439 * Returns a format string and data suitable for printf-like rendering
440 * e.g. Print to console with a trailing newline: printf(Q_DEBUG(q, "", "\n"));
441 */
442#define	Q_DEBUG(q, prefmt, postfmt, incfmt)				\
443      Q_DEBUGFMT(q, prefmt, postfmt)					\
444    , #q								\
445    , &(q)								\
446    , Q_SIGNED(q) ? 's' : 'u'						\
447    , Q_NTBITS(q)							\
448    , Q_NIBITS(q)							\
449    , Q_NFBITS(q)							\
450    , Q_RPSHFT(q)							\
451    , Q_IMINVAL(q)							\
452    , Q_IMAXVAL(q)							\
453    , (q)								\
454    , Q_IRAWMASK(q)							\
455    , Q_FRAWMASK(q)							\
456    , Q_TC(q, Q_CRAWMASK(q))						\
457    , Q_IFRAWMASK(q)							\
458    , Q_GIRAW(q)							\
459    , Q_GIABSVAL(q)							\
460    , Q_GIVAL(q)							\
461    , Q_GFRAW(q)							\
462    , Q_GFABSVAL(q)							\
463    , Q_GFVAL(q)							\
464    , (incfmt) ? Q_DEBUGFMT(q, "\nfmt:", "") : ""			\
465
466/*
467 * If precision differs, attempt to normalise to the greater precision that
468 * preserves the integer component of both 'a' and 'b'.
469 */
470#define	Q_NORMPREC(a, b)						\
471({									\
472	int _perr = 0, _relprec = Q_RELPREC(*(a), b);			\
473	if (_relprec != 0)						\
474		_perr = ERANGE; /* XXXLAS: Do precision normalisation! */\
475	_perr;								\
476})
477
478/* Clone r's control bits and int/frac value into 'l'. */
479#define	Q_QCLONEQ(l, r)							\
480({									\
481	Q_BT(*(l)) _l = Q_GCVAL(r);					\
482	int _err = Q_QCANREPQ(r, _l);					\
483	if (!_err) {							\
484		*(l) = _l;						\
485		Q_SIFVAL(*(l), Q_GIFVAL(r));				\
486	}								\
487	_err;								\
488})
489
490/* Copy r's int/frac vals into 'l', retaining 'l's precision and signedness. */
491#define	Q_QCPYVALQ(l, r)						\
492({									\
493	int _err = Q_QCANREPQ(r, *(l));					\
494	if (!_err)							\
495		Q_SIFVALS(*(l), Q_GIVAL(r), Q_GFVAL(r));		\
496	_err;								\
497})
498
499#define	Q_QADDSUBQ(a, b, eop)						\
500({									\
501	int _aserr;							\
502	if ((_aserr = Q_NORMPREC(a, b))) while (0); /* NOP */		\
503	else if ((eop) == '+') {					\
504		if (Q_IFMAXVAL(*(a)) - Q_GIFABSVAL(b) < Q_GIFVAL(*(a)))	\
505			_aserr = EOVERFLOW; /* [+/-a + +b] > max(a) */	\
506		else							\
507			Q_SIFVAL(*(a), Q_GIFVAL(*(a)) + Q_TC(*(a),	\
508			    Q_GIFABSVAL(b)));				\
509	} else { /* eop == '-' */					\
510		if (Q_IFMINVAL(*(a)) + Q_GIFABSVAL(b) > Q_GIFVAL(*(a)))	\
511			_aserr = EOVERFLOW; /* [+/-a - +b] < min(a) */	\
512		else							\
513			Q_SIFVAL(*(a), Q_GIFVAL(*(a)) - Q_TC(*(a),	\
514			    Q_GIFABSVAL(b)));				\
515	}								\
516	_aserr;								\
517})
518#define	Q_QADDQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '-' : '+'))
519#define	Q_QSUBQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '+' : '-'))
520
521#define	Q_QDIVQ(a, b)							\
522({									\
523	int _err;							\
524	if ((_err = Q_NORMPREC(a, b))) while (0); /* NOP */		\
525	else if (Q_GIFABSVAL(b) == 0 || (!Q_SIGNED(*(a)) && Q_LTZ(b)))	\
526		_err = EINVAL; /* Divide by zero or cannot represent. */\
527	/* XXXLAS: Handle overflow. */					\
528	else if (Q_GIFABSVAL(*(a)) != 0) { /* Result expected. */	\
529		Q_SIFVAL(*(a),						\
530		    ((Q_GIVAL(*(a)) << Q_NFBITS(*(a))) / Q_GIFVAL(b)) +	\
531		    (Q_GFVAL(b) == 0 ? 0 :				\
532		    ((Q_GFVAL(*(a)) << Q_NFBITS(*(a))) / Q_GFVAL(b))));	\
533	}								\
534	_err;								\
535})
536
537#define	Q_QMULQ(a, b)							\
538({									\
539	int _mulerr;							\
540	if ((_mulerr = Q_NORMPREC(a, b))) while (0); /* NOP */		\
541	else if (!Q_SIGNED(*(a)) && Q_LTZ(b))				\
542		_mulerr = EINVAL;					\
543	else if (Q_GIFABSVAL(b) != 0 &&					\
544	    Q_IFMAXVAL(*(a)) / Q_GIFABSVAL(b) < Q_GIFABSVAL(*(a)))	\
545		_mulerr = EOVERFLOW;					\
546	else								\
547		Q_SIFVAL(*(a), (Q_GIFVAL(*(a)) * Q_GIFVAL(b)) >>	\
548		    Q_NFBITS(*(a)));					\
549	_mulerr;							\
550})
551
552#define	Q_QCPYVALI(q, i)						\
553({									\
554	int _err = Q_QCANREPI(*(q), i);					\
555	if (!_err)							\
556		Q_SIFVAL(*(q), Q_SHL(*(q), i));				\
557	_err;								\
558})
559
560#define	Q_QADDSUBI(q, i, eop)						\
561({									\
562	int _aserr = 0;							\
563	if (Q_NTBITS(*(q)) < (uint32_t)flsll(Q_ABS(i)))			\
564		_aserr = EOVERFLOW; /* i cannot fit in q's type. */	\
565	else if ((eop) == '+') {					\
566		if (Q_IMAXVAL(*(q)) - Q_TC(*(q), Q_ABS(i)) <		\
567		    Q_GIVAL(*(q)))					\
568			_aserr = EOVERFLOW; /* [+/-q + +i] > max(q) */	\
569		else							\
570			Q_SIFVAL(*(q), Q_GIFVAL(*(q)) +			\
571			    Q_SHL(*(q), Q_ABS(i)));			\
572	} else { /* eop == '-' */					\
573		if (Q_IMINVAL(*(q)) + Q_ABS(i) > Q_GIVAL(*(q)))		\
574			_aserr = EOVERFLOW; /* [+/-q - +i] < min(q) */	\
575		else							\
576			Q_SIFVAL(*(q), Q_GIFVAL(*(q)) -			\
577			    Q_SHL(*(q), Q_ABS(i)));			\
578	}								\
579	_aserr;								\
580})
581#define	Q_QADDI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '-' : '+'))
582#define	Q_QSUBI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '+' : '-'))
583
584#define	Q_QDIVI(q, i)							\
585({									\
586	int _diverr = 0;						\
587	if ((i) == 0 || (!Q_SIGNED(*(q)) && Q_LTZ(i)))			\
588		_diverr = EINVAL; /* Divide by zero or cannot represent. */\
589	else if (Q_GIFABSVAL(*(q)) != 0) { /* Result expected. */	\
590		Q_SIFVAL(*(q), Q_GIFVAL(*(q)) / Q_TC(*(q), i));		\
591		if (Q_GIFABSVAL(*(q)) == 0)				\
592			_diverr = ERANGE; /* q underflow. */		\
593	}								\
594	_diverr;							\
595})
596
597#define	Q_QMULI(q, i)							\
598({									\
599	int _mulerr = 0;						\
600	if (!Q_SIGNED(*(q)) && Q_LTZ(i))				\
601		_mulerr = EINVAL; /* Cannot represent. */		\
602	else if ((i) != 0 && Q_IFMAXVAL(*(q)) / Q_TC(*(q), Q_ABS(i)) <	\
603	    Q_GIFABSVAL(*(q)))						\
604		_mulerr = EOVERFLOW;					\
605	else								\
606		Q_SIFVAL(*(q), Q_GIFVAL(*(q)) * Q_TC(*(q), i));		\
607	_mulerr;							\
608})
609
610#define	Q_QFRACI(q, in, id)						\
611({									\
612	uint64_t _tmp;							\
613	int _err = 0;							\
614	if ((id) == 0)							\
615		_err = EINVAL; /* Divide by zero. */			\
616	else if ((in) == 0)						\
617		Q_SIFVAL(*(q), in);					\
618	else if ((_tmp = Q_ABS(in)) > (UINT64_MAX >> Q_RPSHFT(*(q))))	\
619		_err = EOVERFLOW; /* _tmp overflow. */			\
620	else {								\
621		_tmp = Q_SHL(*(q), _tmp) / Q_ABS(id);			\
622		if (Q_QCANREPI(*(q), _tmp & Q_IFVALIMASK(*(q))))	\
623			_err = EOVERFLOW; /* q overflow. */		\
624		else {							\
625			Q_SIFVAL(*(q), _tmp);				\
626			Q_SSIGN(*(q), (Q_LTZ(in) && !Q_LTZ(id)) ||	\
627			    (!Q_LTZ(in) && Q_LTZ(id)));			\
628			if (_tmp == 0)					\
629				_err = ERANGE; /* q underflow. */	\
630		}							\
631	}								\
632	_err;								\
633})
634
635#endif	/* _SYS_QMATH_H_ */