Annotation of hatari/src/cpu/softfloat/softfloat-macros.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU float support macros
        !             3:  *
        !             4:  * The code in this source file is derived from release 2a of the SoftFloat
        !             5:  * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
        !             6:  * some later contributions) are provided under that license, as detailed below.
        !             7:  * It has subsequently been modified by contributors to the QEMU Project,
        !             8:  * so some portions are provided under:
        !             9:  *  the SoftFloat-2a license
        !            10:  *  the BSD license
        !            11:  *  GPL-v2-or-later
        !            12:  *
        !            13:  * Any future contributions to this file after December 1st 2014 will be
        !            14:  * taken to be licensed under the Softfloat-2a license unless specifically
        !            15:  * indicated otherwise.
        !            16:  */
        !            17: 
        !            18: /*
        !            19: ===============================================================================
        !            20: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
        !            21: Arithmetic Package, Release 2a.
        !            22: 
        !            23: Written by John R. Hauser.  This work was made possible in part by the
        !            24: International Computer Science Institute, located at Suite 600, 1947 Center
        !            25: Street, Berkeley, California 94704.  Funding was partially provided by the
        !            26: National Science Foundation under grant MIP-9311980.  The original version
        !            27: of this code was written as part of a project to build a fixed-point vector
        !            28: processor in collaboration with the University of California at Berkeley,
        !            29: overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
        !            30: is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
        !            31: arithmetic/SoftFloat.html'.
        !            32: 
        !            33: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
        !            34: has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
        !            35: TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
        !            36: PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
        !            37: AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
        !            38: 
        !            39: Derivative works are acceptable, even for commercial purposes, so long as
        !            40: (1) they include prominent notice that the work is derivative, and (2) they
        !            41: include prominent notice akin to these four paragraphs for those parts of
        !            42: this code that are retained.
        !            43: 
        !            44: ===============================================================================
        !            45: */
        !            46: 
        !            47: /* BSD licensing:
        !            48:  * Copyright (c) 2006, Fabrice Bellard
        !            49:  * All rights reserved.
        !            50:  *
        !            51:  * Redistribution and use in source and binary forms, with or without
        !            52:  * modification, are permitted provided that the following conditions are met:
        !            53:  *
        !            54:  * 1. Redistributions of source code must retain the above copyright notice,
        !            55:  * this list of conditions and the following disclaimer.
        !            56:  *
        !            57:  * 2. Redistributions in binary form must reproduce the above copyright notice,
        !            58:  * this list of conditions and the following disclaimer in the documentation
        !            59:  * and/or other materials provided with the distribution.
        !            60:  *
        !            61:  * 3. Neither the name of the copyright holder nor the names of its contributors
        !            62:  * may be used to endorse or promote products derived from this software without
        !            63:  * specific prior written permission.
        !            64:  *
        !            65:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        !            66:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            67:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            68:  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
        !            69:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            70:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            71:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            72:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            73:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            74:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            75:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            76:  */
        !            77: 
        !            78: /* Portions of this work are licensed under the terms of the GNU GPL,
        !            79:  * version 2 or later. See the COPYING file in the top-level directory.
        !            80:  */
        !            81: 
        !            82: /*----------------------------------------------------------------------------
        !            83: | This macro tests for minimum version of the GNU C compiler.
        !            84: *----------------------------------------------------------------------------*/
        !            85: #if defined(__GNUC__) && defined(__GNUC_MINOR__)
        !            86: # define SOFTFLOAT_GNUC_PREREQ(maj, min) \
        !            87:          ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
        !            88: #else
        !            89: # define SOFTFLOAT_GNUC_PREREQ(maj, min) 0
        !            90: #endif
        !            91: 
        !            92: 
        !            93: /*----------------------------------------------------------------------------
        !            94: | Shifts `a' right by the number of bits given in `count'.  If any nonzero
        !            95: | bits are shifted off, they are ``jammed'' into the least significant bit of
        !            96: | the result by setting the least significant bit to 1.  The value of `count'
        !            97: | can be arbitrarily large; in particular, if `count' is greater than 32, the
        !            98: | result will be either 0 or 1, depending on whether `a' is zero or nonzero.
        !            99: | The result is stored in the location pointed to by `zPtr'.
        !           100: *----------------------------------------------------------------------------*/
        !           101: 
        !           102: static inline void shift32RightJamming(uint32_t a, int count, uint32_t *zPtr)
        !           103: {
        !           104:     uint32_t z;
        !           105: 
        !           106:     if ( count == 0 ) {
        !           107:         z = a;
        !           108:     }
        !           109:     else if ( count < 32 ) {
        !           110:         z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
        !           111:     }
        !           112:     else {
        !           113:         z = ( a != 0 );
        !           114:     }
        !           115:     *zPtr = z;
        !           116: 
        !           117: }
        !           118: 
        !           119: /*----------------------------------------------------------------------------
        !           120: | Shifts `a' right by the number of bits given in `count'.  If any nonzero
        !           121: | bits are shifted off, they are ``jammed'' into the least significant bit of
        !           122: | the result by setting the least significant bit to 1.  The value of `count'
        !           123: | can be arbitrarily large; in particular, if `count' is greater than 64, the
        !           124: | result will be either 0 or 1, depending on whether `a' is zero or nonzero.
        !           125: | The result is stored in the location pointed to by `zPtr'.
        !           126: *----------------------------------------------------------------------------*/
        !           127: 
        !           128: static inline void shift64RightJamming(uint64_t a, int count, uint64_t *zPtr)
        !           129: {
        !           130:     uint64_t z;
        !           131: 
        !           132:     if ( count == 0 ) {
        !           133:         z = a;
        !           134:     }
        !           135:     else if ( count < 64 ) {
        !           136:         z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
        !           137:     }
        !           138:     else {
        !           139:         z = ( a != 0 );
        !           140:     }
        !           141:     *zPtr = z;
        !           142: 
        !           143: }
        !           144: 
        !           145: /*----------------------------------------------------------------------------
        !           146: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
        !           147: | _plus_ the number of bits given in `count'.  The shifted result is at most
        !           148: | 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'.  The
        !           149: | bits shifted off form a second 64-bit result as follows:  The _last_ bit
        !           150: | shifted off is the most-significant bit of the extra result, and the other
        !           151: | 63 bits of the extra result are all zero if and only if _all_but_the_last_
        !           152: | bits shifted off were all zero.  This extra result is stored in the location
        !           153: | pointed to by `z1Ptr'.  The value of `count' can be arbitrarily large.
        !           154: |     (This routine makes more sense if `a0' and `a1' are considered to form a
        !           155: | fixed-point value with binary point between `a0' and `a1'.  This fixed-point
        !           156: | value is shifted right by the number of bits given in `count', and the
        !           157: | integer part of the result is returned at the location pointed to by
        !           158: | `z0Ptr'.  The fractional part of the result may be slightly corrupted as
        !           159: | described above, and is returned at the location pointed to by `z1Ptr'.)
        !           160: *----------------------------------------------------------------------------*/
        !           161: 
        !           162: static inline void
        !           163:  shift64ExtraRightJamming(
        !           164:      uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr)
        !           165: {
        !           166:     uint64_t z0, z1;
        !           167:     int8_t negCount = ( - count ) & 63;
        !           168: 
        !           169:     if ( count == 0 ) {
        !           170:         z1 = a1;
        !           171:         z0 = a0;
        !           172:     }
        !           173:     else if ( count < 64 ) {
        !           174:         z1 = ( a0<<negCount ) | ( a1 != 0 );
        !           175:         z0 = a0>>count;
        !           176:     }
        !           177:     else {
        !           178:         if ( count == 64 ) {
        !           179:             z1 = a0 | ( a1 != 0 );
        !           180:         }
        !           181:         else {
        !           182:             z1 = ( ( a0 | a1 ) != 0 );
        !           183:         }
        !           184:         z0 = 0;
        !           185:     }
        !           186:     *z1Ptr = z1;
        !           187:     *z0Ptr = z0;
        !           188: 
        !           189: }
        !           190: 
        !           191: /*----------------------------------------------------------------------------
        !           192: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
        !           193: | number of bits given in `count'.  Any bits shifted off are lost.  The value
        !           194: | of `count' can be arbitrarily large; in particular, if `count' is greater
        !           195: | than 128, the result will be 0.  The result is broken into two 64-bit pieces
        !           196: | which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           197: *----------------------------------------------------------------------------*/
        !           198: 
        !           199: static inline void
        !           200:  shift128Right(
        !           201:      uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr)
        !           202: {
        !           203:     uint64_t z0, z1;
        !           204:     int8_t negCount = ( - count ) & 63;
        !           205: 
        !           206:     if ( count == 0 ) {
        !           207:         z1 = a1;
        !           208:         z0 = a0;
        !           209:     }
        !           210:     else if ( count < 64 ) {
        !           211:         z1 = ( a0<<negCount ) | ( a1>>count );
        !           212:         z0 = a0>>count;
        !           213:     }
        !           214:     else {
        !           215:         z1 = (count < 128) ? (a0 >> (count & 63)) : 0;
        !           216:         z0 = 0;
        !           217:     }
        !           218:     *z1Ptr = z1;
        !           219:     *z0Ptr = z0;
        !           220: 
        !           221: }
        !           222: 
        !           223: /*----------------------------------------------------------------------------
        !           224: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
        !           225: | number of bits given in `count'.  If any nonzero bits are shifted off, they
        !           226: | are ``jammed'' into the least significant bit of the result by setting the
        !           227: | least significant bit to 1.  The value of `count' can be arbitrarily large;
        !           228: | in particular, if `count' is greater than 128, the result will be either
        !           229: | 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
        !           230: | nonzero.  The result is broken into two 64-bit pieces which are stored at
        !           231: | the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           232: *----------------------------------------------------------------------------*/
        !           233: 
        !           234: static inline void
        !           235:  shift128RightJamming(
        !           236:      uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr)
        !           237: {
        !           238:     uint64_t z0, z1;
        !           239:     int8_t negCount = ( - count ) & 63;
        !           240: 
        !           241:     if ( count == 0 ) {
        !           242:         z1 = a1;
        !           243:         z0 = a0;
        !           244:     }
        !           245:     else if ( count < 64 ) {
        !           246:         z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
        !           247:         z0 = a0>>count;
        !           248:     }
        !           249:     else {
        !           250:         if ( count == 64 ) {
        !           251:             z1 = a0 | ( a1 != 0 );
        !           252:         }
        !           253:         else if ( count < 128 ) {
        !           254:             z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
        !           255:         }
        !           256:         else {
        !           257:             z1 = ( ( a0 | a1 ) != 0 );
        !           258:         }
        !           259:         z0 = 0;
        !           260:     }
        !           261:     *z1Ptr = z1;
        !           262:     *z0Ptr = z0;
        !           263: 
        !           264: }
        !           265: 
        !           266: /*----------------------------------------------------------------------------
        !           267: | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
        !           268: | by 64 _plus_ the number of bits given in `count'.  The shifted result is
        !           269: | at most 128 nonzero bits; these are broken into two 64-bit pieces which are
        !           270: | stored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
        !           271: | off form a third 64-bit result as follows:  The _last_ bit shifted off is
        !           272: | the most-significant bit of the extra result, and the other 63 bits of the
        !           273: | extra result are all zero if and only if _all_but_the_last_ bits shifted off
        !           274: | were all zero.  This extra result is stored in the location pointed to by
        !           275: | `z2Ptr'.  The value of `count' can be arbitrarily large.
        !           276: |     (This routine makes more sense if `a0', `a1', and `a2' are considered
        !           277: | to form a fixed-point value with binary point between `a1' and `a2'.  This
        !           278: | fixed-point value is shifted right by the number of bits given in `count',
        !           279: | and the integer part of the result is returned at the locations pointed to
        !           280: | by `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
        !           281: | corrupted as described above, and is returned at the location pointed to by
        !           282: | `z2Ptr'.)
        !           283: *----------------------------------------------------------------------------*/
        !           284: 
        !           285: static inline void
        !           286:  shift128ExtraRightJamming(
        !           287:      uint64_t a0,
        !           288:      uint64_t a1,
        !           289:      uint64_t a2,
        !           290:      int count,
        !           291:      uint64_t *z0Ptr,
        !           292:      uint64_t *z1Ptr,
        !           293:      uint64_t *z2Ptr
        !           294:  )
        !           295: {
        !           296:     uint64_t z0, z1, z2;
        !           297:     int8_t negCount = ( - count ) & 63;
        !           298: 
        !           299:     if ( count == 0 ) {
        !           300:         z2 = a2;
        !           301:         z1 = a1;
        !           302:         z0 = a0;
        !           303:     }
        !           304:     else {
        !           305:         if ( count < 64 ) {
        !           306:             z2 = a1<<negCount;
        !           307:             z1 = ( a0<<negCount ) | ( a1>>count );
        !           308:             z0 = a0>>count;
        !           309:         }
        !           310:         else {
        !           311:             if ( count == 64 ) {
        !           312:                 z2 = a1;
        !           313:                 z1 = a0;
        !           314:             }
        !           315:             else {
        !           316:                 a2 |= a1;
        !           317:                 if ( count < 128 ) {
        !           318:                     z2 = a0<<negCount;
        !           319:                     z1 = a0>>( count & 63 );
        !           320:                 }
        !           321:                 else {
        !           322:                     z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
        !           323:                     z1 = 0;
        !           324:                 }
        !           325:             }
        !           326:             z0 = 0;
        !           327:         }
        !           328:         z2 |= ( a2 != 0 );
        !           329:     }
        !           330:     *z2Ptr = z2;
        !           331:     *z1Ptr = z1;
        !           332:     *z0Ptr = z0;
        !           333: 
        !           334: }
        !           335: 
        !           336: /*----------------------------------------------------------------------------
        !           337: | Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
        !           338: | number of bits given in `count'.  Any bits shifted off are lost.  The value
        !           339: | of `count' must be less than 64.  The result is broken into two 64-bit
        !           340: | pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           341: *----------------------------------------------------------------------------*/
        !           342: 
        !           343: static inline void
        !           344:  shortShift128Left(
        !           345:      uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr)
        !           346: {
        !           347: 
        !           348:     *z1Ptr = a1<<count;
        !           349:     *z0Ptr =
        !           350:         ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
        !           351: 
        !           352: }
        !           353: 
        !           354: /*----------------------------------------------------------------------------
        !           355: | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
        !           356: | by the number of bits given in `count'.  Any bits shifted off are lost.
        !           357: | The value of `count' must be less than 64.  The result is broken into three
        !           358: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
        !           359: | `z1Ptr', and `z2Ptr'.
        !           360: *----------------------------------------------------------------------------*/
        !           361: 
        !           362: static inline void
        !           363:  shortShift192Left(
        !           364:      uint64_t a0,
        !           365:      uint64_t a1,
        !           366:      uint64_t a2,
        !           367:      int count,
        !           368:      uint64_t *z0Ptr,
        !           369:      uint64_t *z1Ptr,
        !           370:      uint64_t *z2Ptr
        !           371:  )
        !           372: {
        !           373:     uint64_t z0, z1, z2;
        !           374:     int8_t negCount;
        !           375: 
        !           376:     z2 = a2<<count;
        !           377:     z1 = a1<<count;
        !           378:     z0 = a0<<count;
        !           379:     if ( 0 < count ) {
        !           380:         negCount = ( ( - count ) & 63 );
        !           381:         z1 |= a2>>negCount;
        !           382:         z0 |= a1>>negCount;
        !           383:     }
        !           384:     *z2Ptr = z2;
        !           385:     *z1Ptr = z1;
        !           386:     *z0Ptr = z0;
        !           387: 
        !           388: }
        !           389: 
        !           390: /*----------------------------------------------------------------------------
        !           391: | Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
        !           392: | value formed by concatenating `b0' and `b1'.  Addition is modulo 2^128, so
        !           393: | any carry out is lost.  The result is broken into two 64-bit pieces which
        !           394: | are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           395: *----------------------------------------------------------------------------*/
        !           396: 
        !           397: static inline void
        !           398:  add128(
        !           399:      uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr )
        !           400: {
        !           401:     uint64_t z1;
        !           402: 
        !           403:     z1 = a1 + b1;
        !           404:     *z1Ptr = z1;
        !           405:     *z0Ptr = a0 + b0 + ( z1 < a1 );
        !           406: 
        !           407: }
        !           408: 
        !           409: /*----------------------------------------------------------------------------
        !           410: | Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
        !           411: | 192-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
        !           412: | modulo 2^192, so any carry out is lost.  The result is broken into three
        !           413: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
        !           414: | `z1Ptr', and `z2Ptr'.
        !           415: *----------------------------------------------------------------------------*/
        !           416: 
        !           417: static inline void
        !           418:  add192(
        !           419:      uint64_t a0,
        !           420:      uint64_t a1,
        !           421:      uint64_t a2,
        !           422:      uint64_t b0,
        !           423:      uint64_t b1,
        !           424:      uint64_t b2,
        !           425:      uint64_t *z0Ptr,
        !           426:      uint64_t *z1Ptr,
        !           427:      uint64_t *z2Ptr
        !           428:  )
        !           429: {
        !           430:     uint64_t z0, z1, z2;
        !           431:     uint8_t carry0, carry1;
        !           432: 
        !           433:     z2 = a2 + b2;
        !           434:     carry1 = ( z2 < a2 );
        !           435:     z1 = a1 + b1;
        !           436:     carry0 = ( z1 < a1 );
        !           437:     z0 = a0 + b0;
        !           438:     z1 += carry1;
        !           439:     z0 += ( z1 < carry1 );
        !           440:     z0 += carry0;
        !           441:     *z2Ptr = z2;
        !           442:     *z1Ptr = z1;
        !           443:     *z0Ptr = z0;
        !           444: 
        !           445: }
        !           446: 
        !           447: /*----------------------------------------------------------------------------
        !           448: | Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
        !           449: | 128-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
        !           450: | 2^128, so any borrow out (carry out) is lost.  The result is broken into two
        !           451: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
        !           452: | `z1Ptr'.
        !           453: *----------------------------------------------------------------------------*/
        !           454: 
        !           455: static inline void
        !           456:  sub128(
        !           457:      uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr )
        !           458: {
        !           459: 
        !           460:     *z1Ptr = a1 - b1;
        !           461:     *z0Ptr = a0 - b0 - ( a1 < b1 );
        !           462: 
        !           463: }
        !           464: 
        !           465: /*----------------------------------------------------------------------------
        !           466: | Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
        !           467: | from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
        !           468: | Subtraction is modulo 2^192, so any borrow out (carry out) is lost.  The
        !           469: | result is broken into three 64-bit pieces which are stored at the locations
        !           470: | pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
        !           471: *----------------------------------------------------------------------------*/
        !           472: 
        !           473: static inline void
        !           474:  sub192(
        !           475:      uint64_t a0,
        !           476:      uint64_t a1,
        !           477:      uint64_t a2,
        !           478:      uint64_t b0,
        !           479:      uint64_t b1,
        !           480:      uint64_t b2,
        !           481:      uint64_t *z0Ptr,
        !           482:      uint64_t *z1Ptr,
        !           483:      uint64_t *z2Ptr
        !           484:  )
        !           485: {
        !           486:     uint64_t z0, z1, z2;
        !           487:     uint8_t borrow0, borrow1;
        !           488: 
        !           489:     z2 = a2 - b2;
        !           490:     borrow1 = ( a2 < b2 );
        !           491:     z1 = a1 - b1;
        !           492:     borrow0 = ( a1 < b1 );
        !           493:     z0 = a0 - b0;
        !           494:     z0 -= ( z1 < borrow1 );
        !           495:     z1 -= borrow1;
        !           496:     z0 -= borrow0;
        !           497:     *z2Ptr = z2;
        !           498:     *z1Ptr = z1;
        !           499:     *z0Ptr = z0;
        !           500: 
        !           501: }
        !           502: 
        !           503: /*----------------------------------------------------------------------------
        !           504: | Multiplies `a' by `b' to obtain a 128-bit product.  The product is broken
        !           505: | into two 64-bit pieces which are stored at the locations pointed to by
        !           506: | `z0Ptr' and `z1Ptr'.
        !           507: *----------------------------------------------------------------------------*/
        !           508: 
        !           509: static inline void mul64To128( uint64_t a, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr )
        !           510: {
        !           511:     uint32_t aHigh, aLow, bHigh, bLow;
        !           512:     uint64_t z0, zMiddleA, zMiddleB, z1;
        !           513: 
        !           514:     aLow = a;
        !           515:     aHigh = a>>32;
        !           516:     bLow = b;
        !           517:     bHigh = b>>32;
        !           518:     z1 = ( (uint64_t) aLow ) * bLow;
        !           519:     zMiddleA = ( (uint64_t) aLow ) * bHigh;
        !           520:     zMiddleB = ( (uint64_t) aHigh ) * bLow;
        !           521:     z0 = ( (uint64_t) aHigh ) * bHigh;
        !           522:     zMiddleA += zMiddleB;
        !           523:     z0 += ( ( (uint64_t) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
        !           524:     zMiddleA <<= 32;
        !           525:     z1 += zMiddleA;
        !           526:     z0 += ( z1 < zMiddleA );
        !           527:     *z1Ptr = z1;
        !           528:     *z0Ptr = z0;
        !           529: 
        !           530: }
        !           531: 
        !           532: /*----------------------------------------------------------------------------
        !           533: | Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
        !           534: | `b' to obtain a 192-bit product.  The product is broken into three 64-bit
        !           535: | pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
        !           536: | `z2Ptr'.
        !           537: *----------------------------------------------------------------------------*/
        !           538: 
        !           539: static inline void
        !           540:  mul128By64To192(
        !           541:      uint64_t a0,
        !           542:      uint64_t a1,
        !           543:      uint64_t b,
        !           544:      uint64_t *z0Ptr,
        !           545:      uint64_t *z1Ptr,
        !           546:      uint64_t *z2Ptr
        !           547:  )
        !           548: {
        !           549:     uint64_t z0, z1, z2, more1;
        !           550: 
        !           551:     mul64To128( a1, b, &z1, &z2 );
        !           552:     mul64To128( a0, b, &z0, &more1 );
        !           553:     add128( z0, more1, 0, z1, &z0, &z1 );
        !           554:     *z2Ptr = z2;
        !           555:     *z1Ptr = z1;
        !           556:     *z0Ptr = z0;
        !           557: 
        !           558: }
        !           559: 
        !           560: /*----------------------------------------------------------------------------
        !           561: | Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
        !           562: | 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
        !           563: | product.  The product is broken into four 64-bit pieces which are stored at
        !           564: | the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
        !           565: *----------------------------------------------------------------------------*/
        !           566: 
        !           567: static inline void
        !           568:  mul128To256(
        !           569:      uint64_t a0,
        !           570:      uint64_t a1,
        !           571:      uint64_t b0,
        !           572:      uint64_t b1,
        !           573:      uint64_t *z0Ptr,
        !           574:      uint64_t *z1Ptr,
        !           575:      uint64_t *z2Ptr,
        !           576:      uint64_t *z3Ptr
        !           577:  )
        !           578: {
        !           579:     uint64_t z0, z1, z2, z3;
        !           580:     uint64_t more1, more2;
        !           581: 
        !           582:     mul64To128( a1, b1, &z2, &z3 );
        !           583:     mul64To128( a1, b0, &z1, &more2 );
        !           584:     add128( z1, more2, 0, z2, &z1, &z2 );
        !           585:     mul64To128( a0, b0, &z0, &more1 );
        !           586:     add128( z0, more1, 0, z1, &z0, &z1 );
        !           587:     mul64To128( a0, b1, &more1, &more2 );
        !           588:     add128( more1, more2, 0, z2, &more1, &z2 );
        !           589:     add128( z0, z1, 0, more1, &z0, &z1 );
        !           590:     *z3Ptr = z3;
        !           591:     *z2Ptr = z2;
        !           592:     *z1Ptr = z1;
        !           593:     *z0Ptr = z0;
        !           594: 
        !           595: }
        !           596: 
        !           597: /*----------------------------------------------------------------------------
        !           598: | Returns an approximation to the 64-bit integer quotient obtained by dividing
        !           599: | `b' into the 128-bit value formed by concatenating `a0' and `a1'.  The
        !           600: | divisor `b' must be at least 2^63.  If q is the exact quotient truncated
        !           601: | toward zero, the approximation returned lies between q and q + 2 inclusive.
        !           602: | If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
        !           603: | unsigned integer is returned.
        !           604: *----------------------------------------------------------------------------*/
        !           605: 
        !           606: static inline uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b )
        !           607: {
        !           608:     uint64_t b0, b1;
        !           609:     uint64_t rem0, rem1, term0, term1;
        !           610:     uint64_t z;
        !           611: 
        !           612:     if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
        !           613:     b0 = b>>32;
        !           614:     z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
        !           615:     mul64To128( b, z, &term0, &term1 );
        !           616:     sub128( a0, a1, term0, term1, &rem0, &rem1 );
        !           617:     while ( ( (int64_t) rem0 ) < 0 ) {
        !           618:         z -= LIT64( 0x100000000 );
        !           619:         b1 = b<<32;
        !           620:         add128( rem0, rem1, b0, b1, &rem0, &rem1 );
        !           621:     }
        !           622:     rem0 = ( rem0<<32 ) | ( rem1>>32 );
        !           623:     z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
        !           624:     return z;
        !           625: 
        !           626: }
        !           627: 
        !           628: /*----------------------------------------------------------------------------
        !           629: | Returns an approximation to the square root of the 32-bit significand given
        !           630: | by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
        !           631: | `aExp' (the least significant bit) is 1, the integer returned approximates
        !           632: | 2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
        !           633: | is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
        !           634: | case, the approximation returned lies strictly within +/-2 of the exact
        !           635: | value.
        !           636: *----------------------------------------------------------------------------*/
        !           637: 
        !           638: static inline uint32_t estimateSqrt32(int aExp, uint32_t a)
        !           639: {
        !           640:     static const uint16_t sqrtOddAdjustments[] = {
        !           641:         0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
        !           642:         0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
        !           643:     };
        !           644:     static const uint16_t sqrtEvenAdjustments[] = {
        !           645:         0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
        !           646:         0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
        !           647:     };
        !           648:     int8_t index;
        !           649:     uint32_t z;
        !           650: 
        !           651:     index = ( a>>27 ) & 15;
        !           652:     if ( aExp & 1 ) {
        !           653:         z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ (int)index ];
        !           654:         z = ( ( a / z )<<14 ) + ( z<<15 );
        !           655:         a >>= 1;
        !           656:     }
        !           657:     else {
        !           658:         z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ (int)index ];
        !           659:         z = a / z + z;
        !           660:         z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
        !           661:         if ( z <= a ) return (uint32_t) ( ( (int32_t) a )>>1 );
        !           662:     }
        !           663:     return ( (uint32_t) ( ( ( (uint64_t) a )<<31 ) / z ) ) + ( z>>1 );
        !           664: 
        !           665: }
        !           666: 
        !           667: /*----------------------------------------------------------------------------
        !           668: | Returns the number of leading 0 bits before the most-significant 1 bit of
        !           669: | `a'.  If `a' is zero, 32 is returned.
        !           670: *----------------------------------------------------------------------------*/
        !           671: 
        !           672: static inline int8_t countLeadingZeros32( uint32_t a )
        !           673: {
        !           674: #if SOFTFLOAT_GNUC_PREREQ(3, 4)
        !           675:     if (a) {
        !           676:         return __builtin_clz(a);
        !           677:     } else {
        !           678:         return 32;
        !           679:     }
        !           680: #else
        !           681:     static const int8_t countLeadingZerosHigh[] = {
        !           682:         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
        !           683:         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        !           684:         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        !           685:         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        !           686:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           687:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           688:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           689:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           690:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           691:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           692:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           693:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           694:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           695:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           696:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           697:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        !           698:     };
        !           699:     int8_t shiftCount;
        !           700: 
        !           701:     shiftCount = 0;
        !           702:     if ( a < 0x10000 ) {
        !           703:         shiftCount += 16;
        !           704:         a <<= 16;
        !           705:     }
        !           706:     if ( a < 0x1000000 ) {
        !           707:         shiftCount += 8;
        !           708:         a <<= 8;
        !           709:     }
        !           710:     shiftCount += countLeadingZerosHigh[ a>>24 ];
        !           711:     return shiftCount;
        !           712: #endif
        !           713: }
        !           714: 
        !           715: /*----------------------------------------------------------------------------
        !           716: | Returns the number of leading 0 bits before the most-significant 1 bit of
        !           717: | `a'.  If `a' is zero, 64 is returned.
        !           718: *----------------------------------------------------------------------------*/
        !           719: 
        !           720: static inline int8_t countLeadingZeros64( uint64_t a )
        !           721: {
        !           722: #if SOFTFLOAT_GNUC_PREREQ(3, 4)
        !           723:     if (a) {
        !           724:         return __builtin_clzll(a);
        !           725:     } else {
        !           726:         return 64;
        !           727:     }
        !           728: #else
        !           729:     int8_t shiftCount;
        !           730: 
        !           731:     shiftCount = 0;
        !           732:     if ( a < ( (uint64_t) 1 )<<32 ) {
        !           733:         shiftCount += 32;
        !           734:     }
        !           735:     else {
        !           736:         a >>= 32;
        !           737:     }
        !           738:     shiftCount += countLeadingZeros32( a );
        !           739:     return shiftCount;
        !           740: #endif
        !           741: }
        !           742: 
        !           743: /*----------------------------------------------------------------------------
        !           744: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
        !           745: | is equal to the 128-bit value formed by concatenating `b0' and `b1'.
        !           746: | Otherwise, returns 0.
        !           747: *----------------------------------------------------------------------------*/
        !           748: 
        !           749: static inline flag eq128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 )
        !           750: {
        !           751: 
        !           752:     return ( a0 == b0 ) && ( a1 == b1 );
        !           753: 
        !           754: }
        !           755: 
        !           756: /*----------------------------------------------------------------------------
        !           757: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
        !           758: | than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
        !           759: | Otherwise, returns 0.
        !           760: *----------------------------------------------------------------------------*/
        !           761: 
        !           762: static inline flag le128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 )
        !           763: {
        !           764: 
        !           765:     return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
        !           766: 
        !           767: }
        !           768: 
        !           769: /*----------------------------------------------------------------------------
        !           770: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
        !           771: | than the 128-bit value formed by concatenating `b0' and `b1'.  Otherwise,
        !           772: | returns 0.
        !           773: *----------------------------------------------------------------------------*/
        !           774: 
        !           775: static inline flag lt128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 )
        !           776: {
        !           777: 
        !           778:     return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
        !           779: 
        !           780: }
        !           781: 
        !           782: /*----------------------------------------------------------------------------
        !           783: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
        !           784: | not equal to the 128-bit value formed by concatenating `b0' and `b1'.
        !           785: | Otherwise, returns 0.
        !           786: *----------------------------------------------------------------------------*/
        !           787: 
        !           788: static inline flag ne128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 )
        !           789: {
        !           790: 
        !           791:     return ( a0 != b0 ) || ( a1 != b1 );
        !           792: 
        !           793: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.