1 /*- 2 * Copyright (c) 2018-2024 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 46 typedef int8_t s8q_t; 47 typedef uint8_t u8q_t; 48 typedef int16_t s16q_t; 49 typedef uint16_t u16q_t; 50 typedef int32_t s32q_t; 51 typedef uint32_t u32q_t; 52 typedef int64_t s64q_t; 53 typedef uint64_t u64q_t; 54 /* typedef int128_t s128q_t; Not yet */ 55 /* typedef uint128_t u128q_t; Not yet */ 56 typedef s64q_t smaxq_t; 57 typedef 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 (0) or not 382 * (EOVERFLOW). If 'b' has fewer integer and/or fractional bits than 'a', 383 * the integer and fractional values stored in 'a' must fit in the available 384 * number of integer and fractional bits in 'b'. 385 */ 386 #define Q_QCANREPQ(a, b) (( \ 387 (!Q_LTZ(a) || Q_SIGNED(b)) \ 388 && ( Q_NIBITS(a) <= Q_NIBITS(b) \ 389 || 0 == (Q_GIABSVAL(a) & (~Q_TC(a, 0) << Q_NIBITS(b)))) \ 390 && ( Q_NFBITS(a) <= Q_NFBITS(b) \ 391 || 0 == (Q_GFABSVAL(a) & ~(~Q_TC(a, 0) << (Q_NFBITS(a) - Q_NFBITS(b))))) \ 392 ) ? 0 : EOVERFLOW) 393 394 /* Test if raw integer value 'i' can be represented by 'q' (T) or not (F). */ 395 #define Q_QCANREPI(q, i) \ 396 ((((Q_LTZ(i) && Q_SIGNED(q)) || !Q_LTZ(i)) && \ 397 Q_ABS(i) <= Q_TC(i, Q_IMAXVAL(q))) ? 0 : EOVERFLOW) 398 399 /* 400 * Returns a Q variable debug format string with appropriate modifiers and 401 * padding relevant to the underlying Q data type. 402 */ 403 #define Q_DEBUGFMT_(prefmt, postfmt, mod, hexpad) \ 404 prefmt \ 405 /* Var name + address. */ \ 406 "\"%s\"@%p" \ 407 /* Data type. */ \ 408 "\n\ttype=%c%dq_t, " \ 409 /* Qm.n notation; 'm' = # int bits, 'n' = # frac bits. */ \ 410 "Qm.n=Q%d.%d, " \ 411 /* Radix point shift relative to the underlying data type's LSB. */ \ 412 "rpshft=%d, " \ 413 /* Min/max integer values which can be represented. */ \ 414 "imin=0x%0" #mod "x, " \ 415 "imax=0x%0" #mod "x" \ 416 /* Raw hex dump of all bits. */ \ 417 "\n\tqraw=0x%0" #hexpad #mod "x" \ 418 /* Bit masks for int/frac/ctrl bits. */ \ 419 "\n\timask=0x%0" #hexpad #mod "x, " \ 420 "fmask=0x%0" #hexpad #mod "x, " \ 421 "cmask=0x%0" #hexpad #mod "x, " \ 422 "ifmask=0x%0" #hexpad #mod "x" \ 423 /* Hex dump of masked int bits; 'iraw' includes shift */ \ 424 "\n\tiraw=0x%0" #hexpad #mod "x, " \ 425 "iabsval=0x%" #mod "x, " \ 426 "ival=0x%" #mod "x" \ 427 /* Hex dump of masked frac bits; 'fraw' includes shift */ \ 428 "\n\tfraw=0x%0" #hexpad #mod "x, " \ 429 "fabsval=0x%" #mod "x, " \ 430 "fval=0x%" #mod "x" \ 431 "%s" \ 432 postfmt 433 434 #define Q_DEBUGFMT(q, prefmt, postfmt) \ 435 sizeof(q) == 8 ? Q_DEBUGFMT_(prefmt, postfmt, j, 16) : \ 436 sizeof(q) == 4 ? Q_DEBUGFMT_(prefmt, postfmt, , 8) : \ 437 sizeof(q) == 2 ? Q_DEBUGFMT_(prefmt, postfmt, h, 4) : \ 438 sizeof(q) == 1 ? Q_DEBUGFMT_(prefmt, postfmt, hh, 2) : \ 439 prefmt "\"%s\"@%p: invalid" postfmt \ 440 441 /* 442 * Returns a format string and data suitable for printf-like rendering 443 * e.g. Print to console with a trailing newline: printf(Q_DEBUG(q, "", "\n")); 444 */ 445 #define Q_DEBUG(q, prefmt, postfmt, incfmt) \ 446 Q_DEBUGFMT(q, prefmt, postfmt) \ 447 , #q \ 448 , &(q) \ 449 , Q_SIGNED(q) ? 's' : 'u' \ 450 , Q_NTBITS(q) \ 451 , Q_NIBITS(q) \ 452 , Q_NFBITS(q) \ 453 , Q_RPSHFT(q) \ 454 , Q_IMINVAL(q) \ 455 , Q_IMAXVAL(q) \ 456 , (q) \ 457 , Q_IRAWMASK(q) \ 458 , Q_FRAWMASK(q) \ 459 , Q_TC(q, Q_CRAWMASK(q)) \ 460 , Q_IFRAWMASK(q) \ 461 , Q_GIRAW(q) \ 462 , Q_GIABSVAL(q) \ 463 , Q_GIVAL(q) \ 464 , Q_GFRAW(q) \ 465 , Q_GFABSVAL(q) \ 466 , Q_GFVAL(q) \ 467 , (incfmt) ? Q_DEBUGFMT(q, "\nfmt:", "") : "" \ 468 469 /* 470 * If precision differs, attempt to normalise to the greater precision that 471 * preserves the integer component of both 'a' and 'b'. 472 */ 473 #define Q_NORMPREC(a, b) \ 474 ({ \ 475 int _perr = 0, _relprec = Q_RELPREC(*(a), b); \ 476 if (_relprec != 0) \ 477 _perr = ERANGE; /* XXXLAS: Do precision normalisation! */\ 478 _perr; \ 479 }) 480 481 /* Clone r's control bits and int/frac value into 'l'. */ 482 #define Q_QCLONEQ(l, r) \ 483 ({ \ 484 Q_BT(*(l)) _l = Q_GCVAL(r); \ 485 int _err = Q_QCANREPQ(r, _l); \ 486 if (!_err) { \ 487 *(l) = _l; \ 488 Q_SIFVAL(*(l), Q_GIFVAL(r)); \ 489 } \ 490 _err; \ 491 }) 492 493 /* Copy r's int/frac vals into 'l', retaining 'l's precision and signedness. */ 494 #define Q_QCPYVALQ(l, r) \ 495 ({ \ 496 int _err = Q_QCANREPQ(r, *(l)); \ 497 if (!_err) \ 498 Q_SIFVALS(*(l), Q_GIVAL(r), Q_GFVAL(r)); \ 499 _err; \ 500 }) 501 502 #define Q_QADDSUBQ(a, b, eop) \ 503 ({ \ 504 int _aserr; \ 505 if ((_aserr = Q_NORMPREC(a, b))) while (0); /* NOP */ \ 506 else if ((eop) == '+') { \ 507 if (Q_IFMAXVAL(*(a)) - Q_GIFABSVAL(b) < Q_GIFVAL(*(a))) \ 508 _aserr = EOVERFLOW; /* [+/-a + +b] > max(a) */ \ 509 else \ 510 Q_SIFVAL(*(a), Q_GIFVAL(*(a)) + Q_TC(*(a), \ 511 Q_GIFABSVAL(b))); \ 512 } else { /* eop == '-' */ \ 513 if (Q_IFMINVAL(*(a)) + Q_GIFABSVAL(b) > Q_GIFVAL(*(a))) \ 514 _aserr = EOVERFLOW; /* [+/-a - +b] < min(a) */ \ 515 else \ 516 Q_SIFVAL(*(a), Q_GIFVAL(*(a)) - Q_TC(*(a), \ 517 Q_GIFABSVAL(b))); \ 518 } \ 519 _aserr; \ 520 }) 521 #define Q_QADDQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '-' : '+')) 522 #define Q_QSUBQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '+' : '-')) 523 524 #define Q_QDIVQ(a, b) \ 525 ({ \ 526 int _err; \ 527 if ((_err = Q_NORMPREC(a, b))) while (0); /* NOP */ \ 528 else if (Q_GIFABSVAL(b) == 0 || (!Q_SIGNED(*(a)) && Q_LTZ(b))) \ 529 _err = EINVAL; /* Divide by zero or cannot represent. */\ 530 /* XXXLAS: Handle overflow. */ \ 531 else if (Q_GIFABSVAL(*(a)) != 0) { /* Result expected. */ \ 532 Q_SIFVAL(*(a), \ 533 ((Q_GIVAL(*(a)) << Q_NFBITS(*(a))) / Q_GIFVAL(b)) + \ 534 (Q_GFVAL(b) == 0 ? 0 : \ 535 ((Q_GFVAL(*(a)) << Q_NFBITS(*(a))) / Q_GFVAL(b)))); \ 536 } \ 537 _err; \ 538 }) 539 540 #define Q_QMULQ(a, b) \ 541 ({ \ 542 int _mulerr; \ 543 if ((_mulerr = Q_NORMPREC(a, b))) while (0); /* NOP */ \ 544 else if (!Q_SIGNED(*(a)) && Q_LTZ(b)) \ 545 _mulerr = EINVAL; \ 546 else if (Q_GIFABSVAL(b) != 0 && \ 547 Q_IFMAXVAL(*(a)) / Q_GIFABSVAL(b) < Q_GIFABSVAL(*(a))) \ 548 _mulerr = EOVERFLOW; \ 549 else \ 550 Q_SIFVAL(*(a), (Q_GIFVAL(*(a)) * Q_GIFVAL(b)) >> \ 551 Q_NFBITS(*(a))); \ 552 _mulerr; \ 553 }) 554 555 #define Q_QCPYVALI(q, i) \ 556 ({ \ 557 int _err = Q_QCANREPI(*(q), i); \ 558 if (!_err) \ 559 Q_SIFVAL(*(q), Q_SHL(*(q), i)); \ 560 _err; \ 561 }) 562 563 #define Q_QADDSUBI(q, i, eop) \ 564 ({ \ 565 int _aserr = 0; \ 566 if (Q_NTBITS(*(q)) < (uint32_t)flsll(Q_ABS(i))) \ 567 _aserr = EOVERFLOW; /* i cannot fit in q's type. */ \ 568 else if ((eop) == '+') { \ 569 if (Q_IMAXVAL(*(q)) - Q_TC(*(q), Q_ABS(i)) < \ 570 Q_GIVAL(*(q))) \ 571 _aserr = EOVERFLOW; /* [+/-q + +i] > max(q) */ \ 572 else \ 573 Q_SIFVAL(*(q), Q_GIFVAL(*(q)) + \ 574 Q_SHL(*(q), Q_ABS(i))); \ 575 } else { /* eop == '-' */ \ 576 if (Q_IMINVAL(*(q)) + Q_ABS(i) > Q_GIVAL(*(q))) \ 577 _aserr = EOVERFLOW; /* [+/-q - +i] < min(q) */ \ 578 else \ 579 Q_SIFVAL(*(q), Q_GIFVAL(*(q)) - \ 580 Q_SHL(*(q), Q_ABS(i))); \ 581 } \ 582 _aserr; \ 583 }) 584 #define Q_QADDI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '-' : '+')) 585 #define Q_QSUBI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '+' : '-')) 586 587 #define Q_QDIVI(q, i) \ 588 ({ \ 589 int _diverr = 0; \ 590 if ((i) == 0 || (!Q_SIGNED(*(q)) && Q_LTZ(i))) \ 591 _diverr = EINVAL; /* Divide by zero or cannot represent. */\ 592 else if (Q_GIFABSVAL(*(q)) != 0) { /* Result expected. */ \ 593 Q_SIFVAL(*(q), Q_GIFVAL(*(q)) / Q_TC(*(q), i)); \ 594 if (Q_GIFABSVAL(*(q)) == 0) \ 595 _diverr = ERANGE; /* q underflow. */ \ 596 } \ 597 _diverr; \ 598 }) 599 600 #define Q_QMULI(q, i) \ 601 ({ \ 602 int _mulerr = 0; \ 603 if (!Q_SIGNED(*(q)) && Q_LTZ(i)) \ 604 _mulerr = EINVAL; /* Cannot represent. */ \ 605 else if ((i) != 0 && Q_IFMAXVAL(*(q)) / Q_TC(*(q), Q_ABS(i)) < \ 606 Q_GIFABSVAL(*(q))) \ 607 _mulerr = EOVERFLOW; \ 608 else \ 609 Q_SIFVAL(*(q), Q_GIFVAL(*(q)) * Q_TC(*(q), i)); \ 610 _mulerr; \ 611 }) 612 613 #define Q_QFRACI(q, in, id) \ 614 ({ \ 615 uint64_t _tmp; \ 616 int _err = 0; \ 617 if ((id) == 0) \ 618 _err = EINVAL; /* Divide by zero. */ \ 619 else if ((in) == 0) \ 620 Q_SIFVAL(*(q), in); \ 621 else if ((_tmp = Q_ABS(in)) > (UINT64_MAX >> Q_RPSHFT(*(q)))) \ 622 _err = EOVERFLOW; /* _tmp overflow. */ \ 623 else { \ 624 _tmp = Q_SHL(*(q), _tmp) / Q_ABS(id); \ 625 if (Q_QCANREPI(*(q), _tmp & Q_IFVALIMASK(*(q)))) \ 626 _err = EOVERFLOW; /* q overflow. */ \ 627 else { \ 628 Q_SIFVAL(*(q), _tmp); \ 629 Q_SSIGN(*(q), (Q_LTZ(in) && !Q_LTZ(id)) || \ 630 (!Q_LTZ(in) && Q_LTZ(id))); \ 631 if (_tmp == 0) \ 632 _err = ERANGE; /* q underflow. */ \ 633 } \ 634 } \ 635 _err; \ 636 }) 637 638 #endif /* _SYS_QMATH_H_ */ 639