Back to index

glibc  2.9
Classes | Defines | Typedefs | Functions
divdi3.c File Reference
#include <endian.h>
#include <stdlib.h>
#include <bits/wordsize.h>
#include <stdlib/longlong.h>

Go to the source code of this file.

Classes

struct  DWstruct
union  DWunion

Defines

#define Wtype   SItype
#define HWtype   SItype
#define DWtype   DItype
#define UWtype   USItype
#define UHWtype   USItype
#define UDWtype   UDItype
#define W_TYPE_SIZE   32

Typedefs

typedef unsigned int UQItype __attribute__ ((mode(QI)))

Functions

DWtype __divdi3 (DWtype u, DWtype v)
DWtype __moddi3 (DWtype u, DWtype v)
UDWtype __udivdi3 (UDWtype u, UDWtype v)
UDWtype __umoddi3 (UDWtype u, UDWtype v)
static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
 strong_alias (__divdi3, __divdi3_internal)
 strong_alias (__moddi3, __moddi3_internal)
 strong_alias (__udivdi3, __udivdi3_internal)

Class Documentation

struct DWstruct

Definition at line 45 of file divdi3.c.

Class Members
Wtype high
Wtype low
union DWunion

Definition at line 51 of file divdi3.c.

Class Members
DWtype ll

Define Documentation

#define DWtype   DItype

Definition at line 36 of file divdi3.c.

#define HWtype   SItype

Definition at line 35 of file divdi3.c.

#define UDWtype   UDItype

Definition at line 39 of file divdi3.c.

#define UHWtype   USItype

Definition at line 38 of file divdi3.c.

#define UWtype   USItype

Definition at line 37 of file divdi3.c.

#define W_TYPE_SIZE   32

Definition at line 40 of file divdi3.c.

#define Wtype   SItype

Definition at line 34 of file divdi3.c.


Typedef Documentation

typedef unsigned int UDItype __attribute__((mode(DI)))

Definition at line 29 of file divdi3.c.


Function Documentation

DWtype __divdi3 ( DWtype  u,
DWtype  v 
)

Definition at line 277 of file divdi3.c.

{
  Wtype c = 0;
  DWtype w;

  if (u < 0)
    {
      c = ~c;
      u = -u;
    }
  if (v < 0)
    {
      c = ~c;
      v = -v;
    }
  w = __udivmoddi4 (u, v, NULL);
  if (c)
    w = -w;
  return w;
}

Here is the call graph for this function:

DWtype __moddi3 ( DWtype  u,
DWtype  v 
)
UDWtype __udivdi3 ( UDWtype  u,
UDWtype  v 
)
static UDWtype __udivmoddi4 ( UDWtype  n,
UDWtype  d,
UDWtype rp 
) [static]

Definition at line 60 of file divdi3.c.

{
  DWunion ww;
  DWunion nn, dd;
  DWunion rr;
  UWtype d0, d1, n0, n1, n2;
  UWtype q0, q1;
  UWtype b, bm;

  nn.ll = n;
  dd.ll = d;

  d0 = dd.s.low;
  d1 = dd.s.high;
  n0 = nn.s.low;
  n1 = nn.s.high;

#if !UDIV_NEEDS_NORMALIZATION
  if (d1 == 0)
    {
      if (d0 > n1)
       {
         /* 0q = nn / 0D */

         udiv_qrnnd (q0, n0, n1, n0, d0);
         q1 = 0;

         /* Remainder in n0.  */
       }
      else
       {
         /* qq = NN / 0d */

         if (d0 == 0)
           d0 = 1 / d0;     /* Divide intentionally by zero.  */

         udiv_qrnnd (q1, n1, 0, n1, d0);
         udiv_qrnnd (q0, n0, n1, n0, d0);

         /* Remainder in n0.  */
       }

      if (rp != 0)
       {
         rr.s.low = n0;
         rr.s.high = 0;
         *rp = rr.ll;
       }
    }

#else /* UDIV_NEEDS_NORMALIZATION */

  if (d1 == 0)
    {
      if (d0 > n1)
       {
         /* 0q = nn / 0D */

         count_leading_zeros (bm, d0);

         if (bm != 0)
           {
             /* Normalize, i.e. make the most significant bit of the
               denominator set.  */

             d0 = d0 << bm;
             n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
             n0 = n0 << bm;
           }

         udiv_qrnnd (q0, n0, n1, n0, d0);
         q1 = 0;

         /* Remainder in n0 >> bm.  */
       }
      else
       {
         /* qq = NN / 0d */

         if (d0 == 0)
           d0 = 1 / d0;     /* Divide intentionally by zero.  */

         count_leading_zeros (bm, d0);

         if (bm == 0)
           {
             /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
               conclude (the most significant bit of n1 is set) /\ (the
               leading quotient digit q1 = 1).

               This special case is necessary, not an optimization.
               (Shifts counts of W_TYPE_SIZE are undefined.)  */

             n1 -= d0;
             q1 = 1;
           }
         else
           {
             /* Normalize.  */

             b = W_TYPE_SIZE - bm;

             d0 = d0 << bm;
             n2 = n1 >> b;
             n1 = (n1 << bm) | (n0 >> b);
             n0 = n0 << bm;

             udiv_qrnnd (q1, n1, n2, n1, d0);
           }

         /* n1 != d0...  */

         udiv_qrnnd (q0, n0, n1, n0, d0);

         /* Remainder in n0 >> bm.  */
       }

      if (rp != 0)
       {
         rr.s.low = n0 >> bm;
         rr.s.high = 0;
         *rp = rr.ll;
       }
    }
#endif /* UDIV_NEEDS_NORMALIZATION */

  else
    {
      if (d1 > n1)
       {
         /* 00 = nn / DD */

         q0 = 0;
         q1 = 0;

         /* Remainder in n1n0.  */
         if (rp != 0)
           {
             rr.s.low = n0;
             rr.s.high = n1;
             *rp = rr.ll;
           }
       }
      else
       {
         /* 0q = NN / dd */

         count_leading_zeros (bm, d1);
         if (bm == 0)
           {
             /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
               conclude (the most significant bit of n1 is set) /\ (the
               quotient digit q0 = 0 or 1).

               This special case is necessary, not an optimization.  */

             /* The condition on the next line takes advantage of that
               n1 >= d1 (true due to program flow).  */
             if (n1 > d1 || n0 >= d0)
              {
                q0 = 1;
                sub_ddmmss (n1, n0, n1, n0, d1, d0);
              }
             else
              q0 = 0;

             q1 = 0;

             if (rp != 0)
              {
                rr.s.low = n0;
                rr.s.high = n1;
                *rp = rr.ll;
              }
           }
         else
           {
             UWtype m1, m0;
             /* Normalize.  */

             b = W_TYPE_SIZE - bm;

             d1 = (d1 << bm) | (d0 >> b);
             d0 = d0 << bm;
             n2 = n1 >> b;
             n1 = (n1 << bm) | (n0 >> b);
             n0 = n0 << bm;

             udiv_qrnnd (q0, n1, n2, n1, d1);
             umul_ppmm (m1, m0, q0, d0);

             if (m1 > n1 || (m1 == n1 && m0 > n0))
              {
                q0--;
                sub_ddmmss (m1, m0, m1, m0, d1, d0);
              }

             q1 = 0;

             /* Remainder in (n1n0 - m1m0) >> bm.  */
             if (rp != 0)
              {
                sub_ddmmss (n1, n0, n1, n0, m1, m0);
                rr.s.low = (n1 << b) | (n0 >> bm);
                rr.s.high = n1 >> bm;
                *rp = rr.ll;
              }
           }
       }
    }

  ww.s.low = q0;
  ww.s.high = q1;
  return ww.ll;
}

Here is the caller graph for this function:

UDWtype __umoddi3 ( UDWtype  u,
UDWtype  v 
)
strong_alias ( __divdi3  ,
__divdi3_internal   
)

Definition at line 297 of file divdi3.c.

{
  Wtype c = 0;
  DWtype w;

  if (u < 0)
    {
      c = ~c;
      u = -u;
    }
  if (v < 0)
    v = -v;
  __udivmoddi4 (u, v, (UDWtype *) &w);
  if (c)
    w = -w;
  return w;
}

Here is the call graph for this function:

strong_alias ( __moddi3  ,
__moddi3_internal   
)

Definition at line 317 of file divdi3.c.

{
  return __udivmoddi4 (u, v, NULL);
}

Here is the call graph for this function:

strong_alias ( __udivdi3  ,
__udivdi3_internal   
)

Definition at line 324 of file divdi3.c.

{
  UDWtype w;

  __udivmoddi4 (u, v, &w);
  return w;
}

Here is the call graph for this function: