Annotation of qemu/fpu/softfloat-macros.h, revision 1.1

1.1     ! root        1: 
        !             2: /*============================================================================
        !             3: 
        !             4: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
        !             5: Arithmetic Package, Release 2b.
        !             6: 
        !             7: Written by John R. Hauser.  This work was made possible in part by the
        !             8: International Computer Science Institute, located at Suite 600, 1947 Center
        !             9: Street, Berkeley, California 94704.  Funding was partially provided by the
        !            10: National Science Foundation under grant MIP-9311980.  The original version
        !            11: of this code was written as part of a project to build a fixed-point vector
        !            12: processor in collaboration with the University of California at Berkeley,
        !            13: overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
        !            14: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
        !            15: arithmetic/SoftFloat.html'.
        !            16: 
        !            17: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
        !            18: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
        !            19: RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
        !            20: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
        !            21: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
        !            22: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
        !            23: INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
        !            24: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
        !            25: 
        !            26: Derivative works are acceptable, even for commercial purposes, so long as
        !            27: (1) the source code for the derivative work includes prominent notice that
        !            28: the work is derivative, and (2) the source code includes prominent notice with
        !            29: these four paragraphs for those parts of this code that are retained.
        !            30: 
        !            31: =============================================================================*/
        !            32: 
        !            33: /*----------------------------------------------------------------------------
        !            34: | Shifts `a' right by the number of bits given in `count'.  If any nonzero
        !            35: | bits are shifted off, they are ``jammed'' into the least significant bit of
        !            36: | the result by setting the least significant bit to 1.  The value of `count'
        !            37: | can be arbitrarily large; in particular, if `count' is greater than 32, the
        !            38: | result will be either 0 or 1, depending on whether `a' is zero or nonzero.
        !            39: | The result is stored in the location pointed to by `zPtr'.
        !            40: *----------------------------------------------------------------------------*/
        !            41: 
        !            42: INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
        !            43: {
        !            44:     bits32 z;
        !            45: 
        !            46:     if ( count == 0 ) {
        !            47:         z = a;
        !            48:     }
        !            49:     else if ( count < 32 ) {
        !            50:         z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
        !            51:     }
        !            52:     else {
        !            53:         z = ( a != 0 );
        !            54:     }
        !            55:     *zPtr = z;
        !            56: 
        !            57: }
        !            58: 
        !            59: /*----------------------------------------------------------------------------
        !            60: | Shifts `a' right by the number of bits given in `count'.  If any nonzero
        !            61: | bits are shifted off, they are ``jammed'' into the least significant bit of
        !            62: | the result by setting the least significant bit to 1.  The value of `count'
        !            63: | can be arbitrarily large; in particular, if `count' is greater than 64, the
        !            64: | result will be either 0 or 1, depending on whether `a' is zero or nonzero.
        !            65: | The result is stored in the location pointed to by `zPtr'.
        !            66: *----------------------------------------------------------------------------*/
        !            67: 
        !            68: INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
        !            69: {
        !            70:     bits64 z;
        !            71: 
        !            72:     if ( count == 0 ) {
        !            73:         z = a;
        !            74:     }
        !            75:     else if ( count < 64 ) {
        !            76:         z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
        !            77:     }
        !            78:     else {
        !            79:         z = ( a != 0 );
        !            80:     }
        !            81:     *zPtr = z;
        !            82: 
        !            83: }
        !            84: 
        !            85: /*----------------------------------------------------------------------------
        !            86: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
        !            87: | _plus_ the number of bits given in `count'.  The shifted result is at most
        !            88: | 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'.  The
        !            89: | bits shifted off form a second 64-bit result as follows:  The _last_ bit
        !            90: | shifted off is the most-significant bit of the extra result, and the other
        !            91: | 63 bits of the extra result are all zero if and only if _all_but_the_last_
        !            92: | bits shifted off were all zero.  This extra result is stored in the location
        !            93: | pointed to by `z1Ptr'.  The value of `count' can be arbitrarily large.
        !            94: |     (This routine makes more sense if `a0' and `a1' are considered to form
        !            95: | a fixed-point value with binary point between `a0' and `a1'.  This fixed-
        !            96: | point value is shifted right by the number of bits given in `count', and
        !            97: | the integer part of the result is returned at the location pointed to by
        !            98: | `z0Ptr'.  The fractional part of the result may be slightly corrupted as
        !            99: | described above, and is returned at the location pointed to by `z1Ptr'.)
        !           100: *----------------------------------------------------------------------------*/
        !           101: 
        !           102: INLINE void
        !           103:  shift64ExtraRightJamming(
        !           104:      bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
        !           105: {
        !           106:     bits64 z0, z1;
        !           107:     int8 negCount = ( - count ) & 63;
        !           108: 
        !           109:     if ( count == 0 ) {
        !           110:         z1 = a1;
        !           111:         z0 = a0;
        !           112:     }
        !           113:     else if ( count < 64 ) {
        !           114:         z1 = ( a0<<negCount ) | ( a1 != 0 );
        !           115:         z0 = a0>>count;
        !           116:     }
        !           117:     else {
        !           118:         if ( count == 64 ) {
        !           119:             z1 = a0 | ( a1 != 0 );
        !           120:         }
        !           121:         else {
        !           122:             z1 = ( ( a0 | a1 ) != 0 );
        !           123:         }
        !           124:         z0 = 0;
        !           125:     }
        !           126:     *z1Ptr = z1;
        !           127:     *z0Ptr = z0;
        !           128: 
        !           129: }
        !           130: 
        !           131: /*----------------------------------------------------------------------------
        !           132: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
        !           133: | number of bits given in `count'.  Any bits shifted off are lost.  The value
        !           134: | of `count' can be arbitrarily large; in particular, if `count' is greater
        !           135: | than 128, the result will be 0.  The result is broken into two 64-bit pieces
        !           136: | which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           137: *----------------------------------------------------------------------------*/
        !           138: 
        !           139: INLINE void
        !           140:  shift128Right(
        !           141:      bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
        !           142: {
        !           143:     bits64 z0, z1;
        !           144:     int8 negCount = ( - count ) & 63;
        !           145: 
        !           146:     if ( count == 0 ) {
        !           147:         z1 = a1;
        !           148:         z0 = a0;
        !           149:     }
        !           150:     else if ( count < 64 ) {
        !           151:         z1 = ( a0<<negCount ) | ( a1>>count );
        !           152:         z0 = a0>>count;
        !           153:     }
        !           154:     else {
        !           155:         z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
        !           156:         z0 = 0;
        !           157:     }
        !           158:     *z1Ptr = z1;
        !           159:     *z0Ptr = z0;
        !           160: 
        !           161: }
        !           162: 
        !           163: /*----------------------------------------------------------------------------
        !           164: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
        !           165: | number of bits given in `count'.  If any nonzero bits are shifted off, they
        !           166: | are ``jammed'' into the least significant bit of the result by setting the
        !           167: | least significant bit to 1.  The value of `count' can be arbitrarily large;
        !           168: | in particular, if `count' is greater than 128, the result will be either
        !           169: | 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
        !           170: | nonzero.  The result is broken into two 64-bit pieces which are stored at
        !           171: | the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           172: *----------------------------------------------------------------------------*/
        !           173: 
        !           174: INLINE void
        !           175:  shift128RightJamming(
        !           176:      bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
        !           177: {
        !           178:     bits64 z0, z1;
        !           179:     int8 negCount = ( - count ) & 63;
        !           180: 
        !           181:     if ( count == 0 ) {
        !           182:         z1 = a1;
        !           183:         z0 = a0;
        !           184:     }
        !           185:     else if ( count < 64 ) {
        !           186:         z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
        !           187:         z0 = a0>>count;
        !           188:     }
        !           189:     else {
        !           190:         if ( count == 64 ) {
        !           191:             z1 = a0 | ( a1 != 0 );
        !           192:         }
        !           193:         else if ( count < 128 ) {
        !           194:             z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
        !           195:         }
        !           196:         else {
        !           197:             z1 = ( ( a0 | a1 ) != 0 );
        !           198:         }
        !           199:         z0 = 0;
        !           200:     }
        !           201:     *z1Ptr = z1;
        !           202:     *z0Ptr = z0;
        !           203: 
        !           204: }
        !           205: 
        !           206: /*----------------------------------------------------------------------------
        !           207: | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
        !           208: | by 64 _plus_ the number of bits given in `count'.  The shifted result is
        !           209: | at most 128 nonzero bits; these are broken into two 64-bit pieces which are
        !           210: | stored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
        !           211: | off form a third 64-bit result as follows:  The _last_ bit shifted off is
        !           212: | the most-significant bit of the extra result, and the other 63 bits of the
        !           213: | extra result are all zero if and only if _all_but_the_last_ bits shifted off
        !           214: | were all zero.  This extra result is stored in the location pointed to by
        !           215: | `z2Ptr'.  The value of `count' can be arbitrarily large.
        !           216: |     (This routine makes more sense if `a0', `a1', and `a2' are considered
        !           217: | to form a fixed-point value with binary point between `a1' and `a2'.  This
        !           218: | fixed-point value is shifted right by the number of bits given in `count',
        !           219: | and the integer part of the result is returned at the locations pointed to
        !           220: | by `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
        !           221: | corrupted as described above, and is returned at the location pointed to by
        !           222: | `z2Ptr'.)
        !           223: *----------------------------------------------------------------------------*/
        !           224: 
        !           225: INLINE void
        !           226:  shift128ExtraRightJamming(
        !           227:      bits64 a0,
        !           228:      bits64 a1,
        !           229:      bits64 a2,
        !           230:      int16 count,
        !           231:      bits64 *z0Ptr,
        !           232:      bits64 *z1Ptr,
        !           233:      bits64 *z2Ptr
        !           234:  )
        !           235: {
        !           236:     bits64 z0, z1, z2;
        !           237:     int8 negCount = ( - count ) & 63;
        !           238: 
        !           239:     if ( count == 0 ) {
        !           240:         z2 = a2;
        !           241:         z1 = a1;
        !           242:         z0 = a0;
        !           243:     }
        !           244:     else {
        !           245:         if ( count < 64 ) {
        !           246:             z2 = a1<<negCount;
        !           247:             z1 = ( a0<<negCount ) | ( a1>>count );
        !           248:             z0 = a0>>count;
        !           249:         }
        !           250:         else {
        !           251:             if ( count == 64 ) {
        !           252:                 z2 = a1;
        !           253:                 z1 = a0;
        !           254:             }
        !           255:             else {
        !           256:                 a2 |= a1;
        !           257:                 if ( count < 128 ) {
        !           258:                     z2 = a0<<negCount;
        !           259:                     z1 = a0>>( count & 63 );
        !           260:                 }
        !           261:                 else {
        !           262:                     z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
        !           263:                     z1 = 0;
        !           264:                 }
        !           265:             }
        !           266:             z0 = 0;
        !           267:         }
        !           268:         z2 |= ( a2 != 0 );
        !           269:     }
        !           270:     *z2Ptr = z2;
        !           271:     *z1Ptr = z1;
        !           272:     *z0Ptr = z0;
        !           273: 
        !           274: }
        !           275: 
        !           276: /*----------------------------------------------------------------------------
        !           277: | Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
        !           278: | number of bits given in `count'.  Any bits shifted off are lost.  The value
        !           279: | of `count' must be less than 64.  The result is broken into two 64-bit
        !           280: | pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           281: *----------------------------------------------------------------------------*/
        !           282: 
        !           283: INLINE void
        !           284:  shortShift128Left(
        !           285:      bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
        !           286: {
        !           287: 
        !           288:     *z1Ptr = a1<<count;
        !           289:     *z0Ptr =
        !           290:         ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
        !           291: 
        !           292: }
        !           293: 
        !           294: /*----------------------------------------------------------------------------
        !           295: | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
        !           296: | by the number of bits given in `count'.  Any bits shifted off are lost.
        !           297: | The value of `count' must be less than 64.  The result is broken into three
        !           298: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
        !           299: | `z1Ptr', and `z2Ptr'.
        !           300: *----------------------------------------------------------------------------*/
        !           301: 
        !           302: INLINE void
        !           303:  shortShift192Left(
        !           304:      bits64 a0,
        !           305:      bits64 a1,
        !           306:      bits64 a2,
        !           307:      int16 count,
        !           308:      bits64 *z0Ptr,
        !           309:      bits64 *z1Ptr,
        !           310:      bits64 *z2Ptr
        !           311:  )
        !           312: {
        !           313:     bits64 z0, z1, z2;
        !           314:     int8 negCount;
        !           315: 
        !           316:     z2 = a2<<count;
        !           317:     z1 = a1<<count;
        !           318:     z0 = a0<<count;
        !           319:     if ( 0 < count ) {
        !           320:         negCount = ( ( - count ) & 63 );
        !           321:         z1 |= a2>>negCount;
        !           322:         z0 |= a1>>negCount;
        !           323:     }
        !           324:     *z2Ptr = z2;
        !           325:     *z1Ptr = z1;
        !           326:     *z0Ptr = z0;
        !           327: 
        !           328: }
        !           329: 
        !           330: /*----------------------------------------------------------------------------
        !           331: | Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
        !           332: | value formed by concatenating `b0' and `b1'.  Addition is modulo 2^128, so
        !           333: | any carry out is lost.  The result is broken into two 64-bit pieces which
        !           334: | are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
        !           335: *----------------------------------------------------------------------------*/
        !           336: 
        !           337: INLINE void
        !           338:  add128(
        !           339:      bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
        !           340: {
        !           341:     bits64 z1;
        !           342: 
        !           343:     z1 = a1 + b1;
        !           344:     *z1Ptr = z1;
        !           345:     *z0Ptr = a0 + b0 + ( z1 < a1 );
        !           346: 
        !           347: }
        !           348: 
        !           349: /*----------------------------------------------------------------------------
        !           350: | Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
        !           351: | 192-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
        !           352: | modulo 2^192, so any carry out is lost.  The result is broken into three
        !           353: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
        !           354: | `z1Ptr', and `z2Ptr'.
        !           355: *----------------------------------------------------------------------------*/
        !           356: 
        !           357: INLINE void
        !           358:  add192(
        !           359:      bits64 a0,
        !           360:      bits64 a1,
        !           361:      bits64 a2,
        !           362:      bits64 b0,
        !           363:      bits64 b1,
        !           364:      bits64 b2,
        !           365:      bits64 *z0Ptr,
        !           366:      bits64 *z1Ptr,
        !           367:      bits64 *z2Ptr
        !           368:  )
        !           369: {
        !           370:     bits64 z0, z1, z2;
        !           371:     int8 carry0, carry1;
        !           372: 
        !           373:     z2 = a2 + b2;
        !           374:     carry1 = ( z2 < a2 );
        !           375:     z1 = a1 + b1;
        !           376:     carry0 = ( z1 < a1 );
        !           377:     z0 = a0 + b0;
        !           378:     z1 += carry1;
        !           379:     z0 += ( z1 < carry1 );
        !           380:     z0 += carry0;
        !           381:     *z2Ptr = z2;
        !           382:     *z1Ptr = z1;
        !           383:     *z0Ptr = z0;
        !           384: 
        !           385: }
        !           386: 
        !           387: /*----------------------------------------------------------------------------
        !           388: | Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
        !           389: | 128-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
        !           390: | 2^128, so any borrow out (carry out) is lost.  The result is broken into two
        !           391: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
        !           392: | `z1Ptr'.
        !           393: *----------------------------------------------------------------------------*/
        !           394: 
        !           395: INLINE void
        !           396:  sub128(
        !           397:      bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
        !           398: {
        !           399: 
        !           400:     *z1Ptr = a1 - b1;
        !           401:     *z0Ptr = a0 - b0 - ( a1 < b1 );
        !           402: 
        !           403: }
        !           404: 
        !           405: /*----------------------------------------------------------------------------
        !           406: | Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
        !           407: | from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
        !           408: | Subtraction is modulo 2^192, so any borrow out (carry out) is lost.  The
        !           409: | result is broken into three 64-bit pieces which are stored at the locations
        !           410: | pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
        !           411: *----------------------------------------------------------------------------*/
        !           412: 
        !           413: INLINE void
        !           414:  sub192(
        !           415:      bits64 a0,
        !           416:      bits64 a1,
        !           417:      bits64 a2,
        !           418:      bits64 b0,
        !           419:      bits64 b1,
        !           420:      bits64 b2,
        !           421:      bits64 *z0Ptr,
        !           422:      bits64 *z1Ptr,
        !           423:      bits64 *z2Ptr
        !           424:  )
        !           425: {
        !           426:     bits64 z0, z1, z2;
        !           427:     int8 borrow0, borrow1;
        !           428: 
        !           429:     z2 = a2 - b2;
        !           430:     borrow1 = ( a2 < b2 );
        !           431:     z1 = a1 - b1;
        !           432:     borrow0 = ( a1 < b1 );
        !           433:     z0 = a0 - b0;
        !           434:     z0 -= ( z1 < borrow1 );
        !           435:     z1 -= borrow1;
        !           436:     z0 -= borrow0;
        !           437:     *z2Ptr = z2;
        !           438:     *z1Ptr = z1;
        !           439:     *z0Ptr = z0;
        !           440: 
        !           441: }
        !           442: 
        !           443: /*----------------------------------------------------------------------------
        !           444: | Multiplies `a' by `b' to obtain a 128-bit product.  The product is broken
        !           445: | into two 64-bit pieces which are stored at the locations pointed to by
        !           446: | `z0Ptr' and `z1Ptr'.
        !           447: *----------------------------------------------------------------------------*/
        !           448: 
        !           449: INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
        !           450: {
        !           451:     bits32 aHigh, aLow, bHigh, bLow;
        !           452:     bits64 z0, zMiddleA, zMiddleB, z1;
        !           453: 
        !           454:     aLow = a;
        !           455:     aHigh = a>>32;
        !           456:     bLow = b;
        !           457:     bHigh = b>>32;
        !           458:     z1 = ( (bits64) aLow ) * bLow;
        !           459:     zMiddleA = ( (bits64) aLow ) * bHigh;
        !           460:     zMiddleB = ( (bits64) aHigh ) * bLow;
        !           461:     z0 = ( (bits64) aHigh ) * bHigh;
        !           462:     zMiddleA += zMiddleB;
        !           463:     z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
        !           464:     zMiddleA <<= 32;
        !           465:     z1 += zMiddleA;
        !           466:     z0 += ( z1 < zMiddleA );
        !           467:     *z1Ptr = z1;
        !           468:     *z0Ptr = z0;
        !           469: 
        !           470: }
        !           471: 
        !           472: /*----------------------------------------------------------------------------
        !           473: | Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
        !           474: | `b' to obtain a 192-bit product.  The product is broken into three 64-bit
        !           475: | pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
        !           476: | `z2Ptr'.
        !           477: *----------------------------------------------------------------------------*/
        !           478: 
        !           479: INLINE void
        !           480:  mul128By64To192(
        !           481:      bits64 a0,
        !           482:      bits64 a1,
        !           483:      bits64 b,
        !           484:      bits64 *z0Ptr,
        !           485:      bits64 *z1Ptr,
        !           486:      bits64 *z2Ptr
        !           487:  )
        !           488: {
        !           489:     bits64 z0, z1, z2, more1;
        !           490: 
        !           491:     mul64To128( a1, b, &z1, &z2 );
        !           492:     mul64To128( a0, b, &z0, &more1 );
        !           493:     add128( z0, more1, 0, z1, &z0, &z1 );
        !           494:     *z2Ptr = z2;
        !           495:     *z1Ptr = z1;
        !           496:     *z0Ptr = z0;
        !           497: 
        !           498: }
        !           499: 
        !           500: /*----------------------------------------------------------------------------
        !           501: | Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
        !           502: | 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
        !           503: | product.  The product is broken into four 64-bit pieces which are stored at
        !           504: | the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
        !           505: *----------------------------------------------------------------------------*/
        !           506: 
        !           507: INLINE void
        !           508:  mul128To256(
        !           509:      bits64 a0,
        !           510:      bits64 a1,
        !           511:      bits64 b0,
        !           512:      bits64 b1,
        !           513:      bits64 *z0Ptr,
        !           514:      bits64 *z1Ptr,
        !           515:      bits64 *z2Ptr,
        !           516:      bits64 *z3Ptr
        !           517:  )
        !           518: {
        !           519:     bits64 z0, z1, z2, z3;
        !           520:     bits64 more1, more2;
        !           521: 
        !           522:     mul64To128( a1, b1, &z2, &z3 );
        !           523:     mul64To128( a1, b0, &z1, &more2 );
        !           524:     add128( z1, more2, 0, z2, &z1, &z2 );
        !           525:     mul64To128( a0, b0, &z0, &more1 );
        !           526:     add128( z0, more1, 0, z1, &z0, &z1 );
        !           527:     mul64To128( a0, b1, &more1, &more2 );
        !           528:     add128( more1, more2, 0, z2, &more1, &z2 );
        !           529:     add128( z0, z1, 0, more1, &z0, &z1 );
        !           530:     *z3Ptr = z3;
        !           531:     *z2Ptr = z2;
        !           532:     *z1Ptr = z1;
        !           533:     *z0Ptr = z0;
        !           534: 
        !           535: }
        !           536: 
        !           537: /*----------------------------------------------------------------------------
        !           538: | Returns an approximation to the 64-bit integer quotient obtained by dividing
        !           539: | `b' into the 128-bit value formed by concatenating `a0' and `a1'.  The
        !           540: | divisor `b' must be at least 2^63.  If q is the exact quotient truncated
        !           541: | toward zero, the approximation returned lies between q and q + 2 inclusive.
        !           542: | If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
        !           543: | unsigned integer is returned.
        !           544: *----------------------------------------------------------------------------*/
        !           545: 
        !           546: static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
        !           547: {
        !           548:     bits64 b0, b1;
        !           549:     bits64 rem0, rem1, term0, term1;
        !           550:     bits64 z;
        !           551: 
        !           552:     if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
        !           553:     b0 = b>>32;
        !           554:     z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
        !           555:     mul64To128( b, z, &term0, &term1 );
        !           556:     sub128( a0, a1, term0, term1, &rem0, &rem1 );
        !           557:     while ( ( (sbits64) rem0 ) < 0 ) {
        !           558:         z -= LIT64( 0x100000000 );
        !           559:         b1 = b<<32;
        !           560:         add128( rem0, rem1, b0, b1, &rem0, &rem1 );
        !           561:     }
        !           562:     rem0 = ( rem0<<32 ) | ( rem1>>32 );
        !           563:     z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
        !           564:     return z;
        !           565: 
        !           566: }
        !           567: 
        !           568: /*----------------------------------------------------------------------------
        !           569: | Returns an approximation to the square root of the 32-bit significand given
        !           570: | by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
        !           571: | `aExp' (the least significant bit) is 1, the integer returned approximates
        !           572: | 2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
        !           573: | is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
        !           574: | case, the approximation returned lies strictly within +/-2 of the exact
        !           575: | value.
        !           576: *----------------------------------------------------------------------------*/
        !           577: 
        !           578: static bits32 estimateSqrt32( int16 aExp, bits32 a )
        !           579: {
        !           580:     static const bits16 sqrtOddAdjustments[] = {
        !           581:         0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
        !           582:         0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
        !           583:     };
        !           584:     static const bits16 sqrtEvenAdjustments[] = {
        !           585:         0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
        !           586:         0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
        !           587:     };
        !           588:     int8 index;
        !           589:     bits32 z;
        !           590: 
        !           591:     index = ( a>>27 ) & 15;
        !           592:     if ( aExp & 1 ) {
        !           593:         z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
        !           594:         z = ( ( a / z )<<14 ) + ( z<<15 );
        !           595:         a >>= 1;
        !           596:     }
        !           597:     else {
        !           598:         z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
        !           599:         z = a / z + z;
        !           600:         z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
        !           601:         if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
        !           602:     }
        !           603:     return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
        !           604: 
        !           605: }
        !           606: 
        !           607: /*----------------------------------------------------------------------------
        !           608: | Returns the number of leading 0 bits before the most-significant 1 bit of
        !           609: | `a'.  If `a' is zero, 32 is returned.
        !           610: *----------------------------------------------------------------------------*/
        !           611: 
        !           612: static int8 countLeadingZeros32( bits32 a )
        !           613: {
        !           614:     static const int8 countLeadingZerosHigh[] = {
        !           615:         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
        !           616:         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        !           617:         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        !           618:         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        !           619:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           620:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           621:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           622:         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        !           623:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           624:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           625:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           626:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           627:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           628:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           629:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           630:         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        !           631:     };
        !           632:     int8 shiftCount;
        !           633: 
        !           634:     shiftCount = 0;
        !           635:     if ( a < 0x10000 ) {
        !           636:         shiftCount += 16;
        !           637:         a <<= 16;
        !           638:     }
        !           639:     if ( a < 0x1000000 ) {
        !           640:         shiftCount += 8;
        !           641:         a <<= 8;
        !           642:     }
        !           643:     shiftCount += countLeadingZerosHigh[ a>>24 ];
        !           644:     return shiftCount;
        !           645: 
        !           646: }
        !           647: 
        !           648: /*----------------------------------------------------------------------------
        !           649: | Returns the number of leading 0 bits before the most-significant 1 bit of
        !           650: | `a'.  If `a' is zero, 64 is returned.
        !           651: *----------------------------------------------------------------------------*/
        !           652: 
        !           653: static int8 countLeadingZeros64( bits64 a )
        !           654: {
        !           655:     int8 shiftCount;
        !           656: 
        !           657:     shiftCount = 0;
        !           658:     if ( a < ( (bits64) 1 )<<32 ) {
        !           659:         shiftCount += 32;
        !           660:     }
        !           661:     else {
        !           662:         a >>= 32;
        !           663:     }
        !           664:     shiftCount += countLeadingZeros32( a );
        !           665:     return shiftCount;
        !           666: 
        !           667: }
        !           668: 
        !           669: /*----------------------------------------------------------------------------
        !           670: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
        !           671: | is equal to the 128-bit value formed by concatenating `b0' and `b1'.
        !           672: | Otherwise, returns 0.
        !           673: *----------------------------------------------------------------------------*/
        !           674: 
        !           675: INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
        !           676: {
        !           677: 
        !           678:     return ( a0 == b0 ) && ( a1 == b1 );
        !           679: 
        !           680: }
        !           681: 
        !           682: /*----------------------------------------------------------------------------
        !           683: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
        !           684: | than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
        !           685: | Otherwise, returns 0.
        !           686: *----------------------------------------------------------------------------*/
        !           687: 
        !           688: INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
        !           689: {
        !           690: 
        !           691:     return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
        !           692: 
        !           693: }
        !           694: 
        !           695: /*----------------------------------------------------------------------------
        !           696: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
        !           697: | than the 128-bit value formed by concatenating `b0' and `b1'.  Otherwise,
        !           698: | returns 0.
        !           699: *----------------------------------------------------------------------------*/
        !           700: 
        !           701: INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
        !           702: {
        !           703: 
        !           704:     return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
        !           705: 
        !           706: }
        !           707: 
        !           708: /*----------------------------------------------------------------------------
        !           709: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
        !           710: | not equal to the 128-bit value formed by concatenating `b0' and `b1'.
        !           711: | Otherwise, returns 0.
        !           712: *----------------------------------------------------------------------------*/
        !           713: 
        !           714: INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
        !           715: {
        !           716: 
        !           717:     return ( a0 != b0 ) || ( a1 != b1 );
        !           718: 
        !           719: }
        !           720: 

unix.superglobalmegacorp.com

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