1 // SPDX-License-Identifier: BSD-3-Clause 2 3 /*============================================================================ 4 5 This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic 6 Package, Release 3a, by John R. Hauser. 7 8 Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions are met: 13 14 1. Redistributions of source code must retain the above copyright notice, 15 this list of conditions, and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright notice, 18 this list of conditions, and the following disclaimer in the documentation 19 and/or other materials provided with the distribution. 20 21 3. Neither the name of the University nor the names of its contributors may 22 be used to endorse or promote products derived from this software without 23 specific prior written permission. 24 25 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY 26 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE 28 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 36 =============================================================================*/ 37 38 #include <stdbool.h> 39 #include <stdint.h> 40 #include "platform.h" 41 #include "internals.h" 42 #include "specialize.h" 43 #include "softfloat.h" 44 45 #ifdef SOFTFLOAT_FAST_INT64 46 47 void f128M_div(const float128_t * aPtr,const float128_t * bPtr,float128_t * zPtr)48 f128M_div( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) 49 { 50 51 *zPtr = f128_div( *aPtr, *bPtr ); 52 53 } 54 55 #else 56 57 void f128M_div(const float128_t * aPtr,const float128_t * bPtr,float128_t * zPtr)58 f128M_div( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) 59 { 60 const uint32_t *aWPtr, *bWPtr; 61 uint32_t *zWPtr, uiA96; 62 bool signA; 63 int32_t expA; 64 uint32_t uiB96; 65 bool signB; 66 int32_t expB; 67 bool signZ; 68 uint32_t y[5], sigB[4]; 69 int32_t expZ; 70 uint32_t recip32; 71 int ix; 72 uint64_t q64; 73 uint32_t q, qs[3], uiZ96; 74 75 /*------------------------------------------------------------------------ 76 *------------------------------------------------------------------------*/ 77 aWPtr = (const uint32_t *) aPtr; 78 bWPtr = (const uint32_t *) bPtr; 79 zWPtr = (uint32_t *) zPtr; 80 /*------------------------------------------------------------------------ 81 *------------------------------------------------------------------------*/ 82 uiA96 = aWPtr[indexWordHi( 4 )]; 83 signA = signF128UI96( uiA96 ); 84 expA = expF128UI96( uiA96 ); 85 uiB96 = bWPtr[indexWordHi( 4 )]; 86 signB = signF128UI96( uiB96 ); 87 expB = expF128UI96( uiB96 ); 88 signZ = signA ^ signB; 89 /*------------------------------------------------------------------------ 90 *------------------------------------------------------------------------*/ 91 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { 92 if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return; 93 if ( expA == 0x7FFF ) { 94 if ( expB == 0x7FFF ) goto invalid; 95 goto infinity; 96 } 97 goto zero; 98 } 99 /*------------------------------------------------------------------------ 100 *------------------------------------------------------------------------*/ 101 expA = softfloat_shiftNormSigF128M( aWPtr, 13, y ); 102 expB = softfloat_shiftNormSigF128M( bWPtr, 13, sigB ); 103 if ( expA == -128 ) { 104 if ( expB == -128 ) goto invalid; 105 goto zero; 106 } 107 if ( expB == -128 ) { 108 softfloat_raiseFlags( softfloat_flag_infinite ); 109 goto infinity; 110 } 111 /*------------------------------------------------------------------------ 112 *------------------------------------------------------------------------*/ 113 expZ = expA - expB + 0x3FFE; 114 if ( softfloat_compare128M( y, sigB ) < 0 ) { 115 --expZ; 116 softfloat_add128M( y, y, y ); 117 } 118 recip32 = 119 softfloat_approxRecip32_1( 120 ((uint64_t) sigB[indexWord( 4, 3 )]<<32 | sigB[indexWord( 4, 2 )]) 121 >>30 122 ); 123 ix = 3; 124 for (;;) { 125 q64 = (uint64_t) y[indexWordHi( 4 )] * recip32; 126 q = (q64 + 0x80000000)>>32; 127 --ix; 128 if ( ix < 0 ) break; 129 softfloat_remStep128MBy32( y, 29, sigB, q, y ); 130 if ( y[indexWordHi( 4 )] & 0x80000000 ) { 131 --q; 132 softfloat_add128M( y, sigB, y ); 133 } 134 qs[ix] = q; 135 } 136 /*------------------------------------------------------------------------ 137 *------------------------------------------------------------------------*/ 138 if ( ((q + 1) & 7) < 2 ) { 139 softfloat_remStep128MBy32( y, 29, sigB, q, y ); 140 if ( y[indexWordHi( 4 )] & 0x80000000 ) { 141 --q; 142 softfloat_add128M( y, sigB, y ); 143 } else if ( softfloat_compare128M( sigB, y ) <= 0 ) { 144 ++q; 145 softfloat_sub128M( y, sigB, y ); 146 } 147 if ( 148 y[indexWordLo( 4 )] || y[indexWord( 4, 1 )] 149 || (y[indexWord( 4, 2 )] | y[indexWord( 4, 3 )]) 150 ) { 151 q |= 1; 152 } 153 } 154 /*------------------------------------------------------------------------ 155 *------------------------------------------------------------------------*/ 156 q64 = (uint64_t) q<<28; 157 y[indexWord( 5, 0 )] = q64; 158 q64 = ((uint64_t) qs[0]<<25) + (q64>>32); 159 y[indexWord( 5, 1 )] = q64; 160 q64 = ((uint64_t) qs[1]<<22) + (q64>>32); 161 y[indexWord( 5, 2 )] = q64; 162 q64 = ((uint64_t) qs[2]<<19) + (q64>>32); 163 y[indexWord( 5, 3 )] = q64; 164 y[indexWord( 5, 4 )] = q64>>32; 165 softfloat_roundPackMToF128M( signZ, expZ, y, zWPtr ); 166 return; 167 /*------------------------------------------------------------------------ 168 *------------------------------------------------------------------------*/ 169 invalid: 170 softfloat_invalidF128M( zWPtr ); 171 return; 172 /*------------------------------------------------------------------------ 173 *------------------------------------------------------------------------*/ 174 infinity: 175 uiZ96 = packToF128UI96( signZ, 0x7FFF, 0 ); 176 goto uiZ96; 177 zero: 178 uiZ96 = packToF128UI96( signZ, 0, 0 ); 179 uiZ96: 180 zWPtr[indexWordHi( 4 )] = uiZ96; 181 zWPtr[indexWord( 4, 2 )] = 0; 182 zWPtr[indexWord( 4, 1 )] = 0; 183 zWPtr[indexWord( 4, 0 )] = 0; 184 185 } 186 187 #endif 188 189