Linux Audio

Check our new training course

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