OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [math-emu/] [udivmodti4.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny.  */
2
 
3
#include "soft-fp.h"
4
 
5
#undef count_leading_zeros
6
#define count_leading_zeros  __FP_CLZ
7
 
8
void
9
_fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],
10
               _FP_W_TYPE n1, _FP_W_TYPE n0,
11
               _FP_W_TYPE d1, _FP_W_TYPE d0)
12
{
13
  _FP_W_TYPE q0, q1, r0, r1;
14
  _FP_I_TYPE b, bm;
15
 
16
  if (d1 == 0)
17
    {
18
#if !UDIV_NEEDS_NORMALIZATION
19
      if (d0 > n1)
20
        {
21
          /* 0q = nn / 0D */
22
 
23
          udiv_qrnnd (q0, n0, n1, n0, d0);
24
          q1 = 0;
25
 
26
          /* Remainder in n0.  */
27
        }
28
      else
29
        {
30
          /* qq = NN / 0d */
31
 
32
          if (d0 == 0)
33
            d0 = 1 / d0;        /* Divide intentionally by zero.  */
34
 
35
          udiv_qrnnd (q1, n1, 0, n1, d0);
36
          udiv_qrnnd (q0, n0, n1, n0, d0);
37
 
38
          /* Remainder in n0.  */
39
        }
40
 
41
      r0 = n0;
42
      r1 = 0;
43
 
44
#else /* UDIV_NEEDS_NORMALIZATION */
45
 
46
      if (d0 > n1)
47
        {
48
          /* 0q = nn / 0D */
49
 
50
          count_leading_zeros (bm, d0);
51
 
52
          if (bm != 0)
53
            {
54
              /* Normalize, i.e. make the most significant bit of the
55
                 denominator set.  */
56
 
57
              d0 = d0 << bm;
58
              n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));
59
              n0 = n0 << bm;
60
            }
61
 
62
          udiv_qrnnd (q0, n0, n1, n0, d0);
63
          q1 = 0;
64
 
65
          /* Remainder in n0 >> bm.  */
66
        }
67
      else
68
        {
69
          /* qq = NN / 0d */
70
 
71
          if (d0 == 0)
72
            d0 = 1 / d0;        /* Divide intentionally by zero.  */
73
 
74
          count_leading_zeros (bm, d0);
75
 
76
          if (bm == 0)
77
            {
78
              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
79
                 conclude (the most significant bit of n1 is set) /\ (the
80
                 leading quotient digit q1 = 1).
81
 
82
                 This special case is necessary, not an optimization.
83
                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
84
 
85
              n1 -= d0;
86
              q1 = 1;
87
            }
88
          else
89
            {
90
              _FP_W_TYPE n2;
91
 
92
              /* Normalize.  */
93
 
94
              b = _FP_W_TYPE_SIZE - bm;
95
 
96
              d0 = d0 << bm;
97
              n2 = n1 >> b;
98
              n1 = (n1 << bm) | (n0 >> b);
99
              n0 = n0 << bm;
100
 
101
              udiv_qrnnd (q1, n1, n2, n1, d0);
102
            }
103
 
104
          /* n1 != d0...  */
105
 
106
          udiv_qrnnd (q0, n0, n1, n0, d0);
107
 
108
          /* Remainder in n0 >> bm.  */
109
        }
110
 
111
      r0 = n0 >> bm;
112
      r1 = 0;
113
#endif /* UDIV_NEEDS_NORMALIZATION */
114
    }
115
  else
116
    {
117
      if (d1 > n1)
118
        {
119
          /* 00 = nn / DD */
120
 
121
          q0 = 0;
122
          q1 = 0;
123
 
124
          /* Remainder in n1n0.  */
125
          r0 = n0;
126
          r1 = n1;
127
        }
128
      else
129
        {
130
          /* 0q = NN / dd */
131
 
132
          count_leading_zeros (bm, d1);
133
          if (bm == 0)
134
            {
135
              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
136
                 conclude (the most significant bit of n1 is set) /\ (the
137
                 quotient digit q0 = 0 or 1).
138
 
139
                 This special case is necessary, not an optimization.  */
140
 
141
              /* The condition on the next line takes advantage of that
142
                 n1 >= d1 (true due to program flow).  */
143
              if (n1 > d1 || n0 >= d0)
144
                {
145
                  q0 = 1;
146
                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
147
                }
148
              else
149
                q0 = 0;
150
 
151
              q1 = 0;
152
 
153
              r0 = n0;
154
              r1 = n1;
155
            }
156
          else
157
            {
158
              _FP_W_TYPE m1, m0, n2;
159
 
160
              /* Normalize.  */
161
 
162
              b = _FP_W_TYPE_SIZE - bm;
163
 
164
              d1 = (d1 << bm) | (d0 >> b);
165
              d0 = d0 << bm;
166
              n2 = n1 >> b;
167
              n1 = (n1 << bm) | (n0 >> b);
168
              n0 = n0 << bm;
169
 
170
              udiv_qrnnd (q0, n1, n2, n1, d1);
171
              umul_ppmm (m1, m0, q0, d0);
172
 
173
              if (m1 > n1 || (m1 == n1 && m0 > n0))
174
                {
175
                  q0--;
176
                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
177
                }
178
 
179
              q1 = 0;
180
 
181
              /* Remainder in (n1n0 - m1m0) >> bm.  */
182
              sub_ddmmss (n1, n0, n1, n0, m1, m0);
183
              r0 = (n1 << b) | (n0 >> bm);
184
              r1 = n1 >> bm;
185
            }
186
        }
187
    }
188
 
189
  q[0] = q0; q[1] = q1;
190
  r[0] = r0, r[1] = r1;
191
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.