From 8f59d925353145a65c09301dea6c47da1f1311b1 Mon Sep 17 00:00:00 2001
From: John Hauser <jhauser@eecs.berkeley.edu>
Date: Fri, 28 Nov 2014 19:49:28 -0800
Subject: First draft of RC for Release 3, to start review process.

---
 source/f128_div.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 196 insertions(+)
 create mode 100644 source/f128_div.c

(limited to 'source/f128_div.c')

diff --git a/source/f128_div.c b/source/f128_div.c
new file mode 100644
index 0000000..152dc48
--- /dev/null
+++ b/source/f128_div.c
@@ -0,0 +1,196 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California
+(Regents).  All Rights Reserved.  Redistribution and use in source and binary
+forms, with or without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
+this list of conditions, and the following two paragraphs of disclaimer.
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions, and the following two paragraphs of disclaimer in the
+documentation and/or other materials provided with the distribution.  Neither
+the name of the Regents nor the names of its contributors may be used to
+endorse or promote products derived from this software without specific prior
+written permission.
+
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+HEREUNDER IS PROVIDED "AS IS".  REGENTS HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+=============================================================================*/
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "platform.h"
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f128_div( float128_t a, float128_t b )
+{
+    union ui128_f128 uA;
+    uint_fast64_t uiA64, uiA0;
+    bool signA;
+    int_fast32_t expA;
+    struct uint128 sigA;
+    union ui128_f128 uB;
+    uint_fast64_t uiB64, uiB0;
+    bool signB;
+    int_fast32_t expB;
+    struct uint128 sigB;
+    bool signZ;
+    struct exp32_sig128 normExpSig;
+    int_fast32_t expZ;
+    struct uint128 rem;
+    uint_fast32_t recip32;
+    int ix;
+    uint_fast64_t q64;
+    uint_fast32_t q;
+    struct uint128 term;
+    uint_fast32_t qs[3];
+    uint_fast64_t sigZExtra;
+    struct uint128 sigZ, uiZ;
+    union ui128_f128 uZ;
+
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    uA.f = a;
+    uiA64 = uA.ui.v64;
+    uiA0  = uA.ui.v0;
+    signA = signF128UI64( uiA64 );
+    expA  = expF128UI64( uiA64 );
+    sigA.v64 = fracF128UI64( uiA64 );
+    sigA.v0  = uiA0;
+    uB.f = b;
+    uiB64 = uB.ui.v64;
+    uiB0  = uB.ui.v0;
+    signB = signF128UI64( uiB64 );
+    expB  = expF128UI64( uiB64 );
+    sigB.v64 = fracF128UI64( uiB64 );
+    sigB.v0  = uiB0;
+    signZ = signA ^ signB;
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    if ( expA == 0x7FFF ) {
+        if ( sigA.v64 | sigA.v0 ) goto propagateNaN;
+        if ( expB == 0x7FFF ) {
+            if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
+            goto invalid;
+        }
+        goto infinity;
+    }
+    if ( expB == 0x7FFF ) {
+        if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
+        goto zero;
+    }
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    if ( ! expB ) {
+        if ( ! (sigB.v64 | sigB.v0) ) {
+            if ( ! (expA | sigA.v64 | sigA.v0) ) goto invalid;
+            softfloat_raiseFlags( softfloat_flag_infinite );
+            goto infinity;
+        }
+        normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );
+        expB = normExpSig.exp;
+        sigB = normExpSig.sig;
+    }
+    if ( ! expA ) {
+        if ( ! (sigA.v64 | sigA.v0) ) goto zero;
+        normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );
+        expA = normExpSig.exp;
+        sigA = normExpSig.sig;
+    }
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    expZ = expA - expB + 0x3FFE;
+    sigA.v64 |= UINT64_C( 0x0001000000000000 );
+    sigB.v64 |= UINT64_C( 0x0001000000000000 );
+    rem = sigA;
+    if ( softfloat_lt128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ) ) {
+        --expZ;
+        rem = softfloat_add128( sigA.v64, sigA.v0, sigA.v64, sigA.v0 );
+    }
+    recip32 = softfloat_approxRecip32_1( sigB.v64>>17 );
+    ix = 3;
+    for (;;) {
+        q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32;
+        q = (q64 + 0x80000000)>>32;
+        --ix;
+        if ( ix < 0 ) break;
+        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
+        term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
+        rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
+        if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
+            --q;
+            rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
+        }
+        qs[ix] = q;
+    }
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    if ( ((q + 1) & 7) < 2 ) {
+        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
+        term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
+        rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
+        if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
+            --q;
+            rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
+        } else if ( softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ) ) {
+            ++q;
+            rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
+        }
+        if ( rem.v64 | rem.v0 ) q |= 1;
+    }
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    sigZExtra = (uint64_t) ((uint_fast64_t) q<<60);
+    term = softfloat_shortShiftLeft128( 0, qs[1], 54 );
+    sigZ =
+        softfloat_add128(
+            (uint_fast64_t) qs[2]<<19, ((uint_fast64_t) qs[0]<<25) + (q>>4),
+            term.v64, term.v0
+        );
+    return
+        softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+ propagateNaN:
+    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );
+    goto uiZ;
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+ invalid:
+    softfloat_raiseFlags( softfloat_flag_invalid );
+    uiZ.v64 = defaultNaNF128UI64;
+    uiZ.v0  = defaultNaNF128UI0;
+    goto uiZ;
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+ infinity:
+    uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );
+    goto uiZ0;
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+ zero:
+    uiZ.v64 = packToF128UI64( signZ, 0, 0 );
+ uiZ0:
+    uiZ.v0 = 0;
+ uiZ:
+    uZ.ui = uiZ;
+    return uZ.f;
+
+}
+
-- 
cgit v1.1