• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * License for Berkeley SoftFloat Release 3e
3   *
4   * John R. Hauser
5   * 2018 January 20
6   *
7   * The following applies to the whole of SoftFloat Release 3e as well as to
8   * each source file individually.
9   *
10   * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
11   * University of California.  All rights reserved.
12   *
13   * Redistribution and use in source and binary forms, with or without
14   * modification, are permitted provided that the following conditions are met:
15   *
16   *  1. Redistributions of source code must retain the above copyright notice,
17   *     this list of conditions, and the following disclaimer.
18   *
19   *  2. Redistributions in binary form must reproduce the above copyright
20   *     notice, this list of conditions, and the following disclaimer in the
21   *     documentation and/or other materials provided with the distribution.
22   *
23   *  3. Neither the name of the University nor the names of its contributors
24   *     may be used to endorse or promote products derived from this software
25   *     without specific prior written permission.
26   *
27   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
28   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
30   * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
31   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   *
38   *
39   * The functions listed in this file are modified versions of the ones
40   * from the Berkeley SoftFloat 3e Library.
41   *
42   * Their implementation correctness has been checked with the Berkeley
43   * TestFloat Release 3e tool for x86_64.
44   */
45  
46  #include "rounding.h"
47  #include "bitscan.h"
48  #include "softfloat.h"
49  
50  #if defined(BIG_ENDIAN)
51  #define word_incr -1
52  #define index_word(total, n) ((total) - 1 - (n))
53  #define index_word_hi(total) 0
54  #define index_word_lo(total) ((total) - 1)
55  #define index_multiword_hi(total, n) 0
56  #define index_multiword_lo(total, n) ((total) - (n))
57  #define index_multiword_hi_but(total, n) 0
58  #define index_multiword_lo_but(total, n) (n)
59  #else
60  #define word_incr 1
61  #define index_word(total, n) (n)
62  #define index_word_hi(total) ((total) - 1)
63  #define index_word_lo(total) 0
64  #define index_multiword_hi(total, n) ((total) - (n))
65  #define index_multiword_lo(total, n) 0
66  #define index_multiword_hi_but(total, n) (n)
67  #define index_multiword_lo_but(total, n) 0
68  #endif
69  
70  typedef union { double f; int64_t i; uint64_t u; } di_type;
71  typedef union { float f; int32_t i; uint32_t u; } fi_type;
72  
73  const uint8_t count_leading_zeros8[256] = {
74      8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
75      3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
76      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
77      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
78      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
79      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
80      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
81      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
82      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
90  };
91  
92  /**
93   * \brief Shifts 'a' right by the number of bits given in 'dist', which must be in
94   * the range 1 to 63.  If any nonzero bits are shifted off, they are "jammed"
95   * into the least-significant bit of the shifted value by setting the
96   * least-significant bit to 1.  This shifted-and-jammed value is returned.
97   *
98   * From softfloat_shortShiftRightJam64()
99   */
100  static inline
_mesa_short_shift_right_jam64(uint64_t a,uint8_t dist)101  uint64_t _mesa_short_shift_right_jam64(uint64_t a, uint8_t dist)
102  {
103      return a >> dist | ((a & (((uint64_t) 1 << dist) - 1)) != 0);
104  }
105  
106  /**
107   * \brief Shifts 'a' right by the number of bits given in 'dist', which must not
108   * be zero.  If any nonzero bits are shifted off, they are "jammed" into the
109   * least-significant bit of the shifted value by setting the least-significant
110   * bit to 1.  This shifted-and-jammed value is returned.
111   * The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is
112   * greater than 64, the result will be either 0 or 1, depending on whether 'a'
113   * is zero or nonzero.
114   *
115   * From softfloat_shiftRightJam64()
116   */
117  static inline
_mesa_shift_right_jam64(uint64_t a,uint32_t dist)118  uint64_t _mesa_shift_right_jam64(uint64_t a, uint32_t dist)
119  {
120      return
121          (dist < 63) ? a >> dist | ((uint64_t) (a << (-dist & 63)) != 0) : (a != 0);
122  }
123  
124  /**
125   * \brief Shifts 'a' right by the number of bits given in 'dist', which must not be
126   * zero.  If any nonzero bits are shifted off, they are "jammed" into the
127   * least-significant bit of the shifted value by setting the least-significant
128   * bit to 1.  This shifted-and-jammed value is returned.
129   * The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is
130   * greater than 32, the result will be either 0 or 1, depending on whether 'a'
131   * is zero or nonzero.
132   *
133   * From softfloat_shiftRightJam32()
134   */
135  static inline
_mesa_shift_right_jam32(uint32_t a,uint16_t dist)136  uint32_t _mesa_shift_right_jam32(uint32_t a, uint16_t dist)
137  {
138      return
139          (dist < 31) ? a >> dist | ((uint32_t) (a << (-dist & 31)) != 0) : (a != 0);
140  }
141  
142  /**
143   * \brief Extracted from softfloat_roundPackToF64()
144   */
145  static inline
_mesa_roundtozero_f64(int64_t s,int64_t e,int64_t m)146  double _mesa_roundtozero_f64(int64_t s, int64_t e, int64_t m)
147  {
148      di_type result;
149  
150      if ((uint64_t) e >= 0x7fd) {
151          if (e < 0) {
152              m = _mesa_shift_right_jam64(m, -e);
153              e = 0;
154          } else if ((e > 0x7fd) || (0x8000000000000000 <= m)) {
155              e = 0x7ff;
156              m = 0;
157              result.u = (s << 63) + (e << 52) + m;
158              result.u -= 1;
159              return result.f;
160          }
161      }
162  
163      m >>= 10;
164      if (m == 0)
165          e = 0;
166  
167      result.u = (s << 63) + (e << 52) + m;
168      return result.f;
169  }
170  
171  /**
172   * \brief Extracted from softfloat_roundPackToF32()
173   */
174  static inline
_mesa_round_f32(int32_t s,int32_t e,int32_t m,bool rtz)175  float _mesa_round_f32(int32_t s, int32_t e, int32_t m, bool rtz)
176  {
177      fi_type result;
178      uint8_t round_increment = rtz ? 0 : 0x40;
179  
180      if ((uint32_t) e >= 0xfd) {
181          if (e < 0) {
182              m = _mesa_shift_right_jam32(m, -e);
183              e = 0;
184          } else if ((e > 0xfd) || (0x80000000 <= m + round_increment)) {
185              e = 0xff;
186              m = 0;
187              result.u = (s << 31) + (e << 23) + m;
188              result.u -= !round_increment;
189              return result.f;
190          }
191      }
192  
193      uint8_t round_bits;
194      round_bits = m & 0x7f;
195      m = ((uint32_t) m + round_increment) >> 7;
196      m &= ~(uint32_t) (! (round_bits ^ 0x40) & !rtz);
197      if (m == 0)
198          e = 0;
199  
200      result.u = (s << 31) + (e << 23) + m;
201      return result.f;
202  }
203  
204  /**
205   * \brief Extracted from softfloat_roundPackToF16()
206   */
207  static inline
_mesa_roundtozero_f16(int16_t s,int16_t e,int16_t m)208  uint16_t _mesa_roundtozero_f16(int16_t s, int16_t e, int16_t m)
209  {
210      if ((uint16_t) e >= 0x1d) {
211          if (e < 0) {
212              m = _mesa_shift_right_jam32(m, -e);
213              e = 0;
214          } else if (e > 0x1d) {
215              e = 0x1f;
216              m = 0;
217              return (s << 15) + (e << 10) + m - 1;
218          }
219      }
220  
221      m >>= 4;
222      if (m == 0)
223          e = 0;
224  
225      return (s << 15) + (e << 10) + m;
226  }
227  
228  /**
229   * \brief Shifts the N-bit unsigned integer pointed to by 'a' left by the number of
230   * bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'
231   * must be in the range 1 to 31.  Any nonzero bits shifted off are lost.  The
232   * shifted N-bit result is stored at the location pointed to by 'm_out'.  Each
233   * of 'a' and 'm_out' points to a 'size_words'-long array of 32-bit elements
234   * that concatenate in the platform's normal endian order to form an N-bit
235   * integer.
236   *
237   * From softfloat_shortShiftLeftM()
238   */
239  static inline void
_mesa_short_shift_left_m(uint8_t size_words,const uint32_t * a,uint8_t dist,uint32_t * m_out)240  _mesa_short_shift_left_m(uint8_t size_words, const uint32_t *a, uint8_t dist, uint32_t *m_out)
241  {
242      uint8_t neg_dist;
243      unsigned index, last_index;
244      uint32_t part_word, a_word;
245  
246      neg_dist = -dist;
247      index = index_word_hi(size_words);
248      last_index = index_word_lo(size_words);
249      part_word = a[index] << dist;
250      while (index != last_index) {
251          a_word = a[index - word_incr];
252          m_out[index] = part_word | a_word >> (neg_dist & 31);
253          index -= word_incr;
254          part_word = a_word << dist;
255      }
256      m_out[index] = part_word;
257  }
258  
259  /**
260   * \brief Shifts the N-bit unsigned integer pointed to by 'a' left by the number of
261   * bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'
262   * must not be zero.  Any nonzero bits shifted off are lost.  The shifted
263   * N-bit result is stored at the location pointed to by 'm_out'.  Each of 'a'
264   * and 'm_out' points to a 'size_words'-long array of 32-bit elements that
265   * concatenate in the platform's normal endian order to form an N-bit
266   * integer. The value of 'dist' can be arbitrarily large.  In particular, if
267   * 'dist' is greater than N, the stored result will be 0.
268   *
269   * From softfloat_shiftLeftM()
270   */
271  static inline void
_mesa_shift_left_m(uint8_t size_words,const uint32_t * a,uint32_t dist,uint32_t * m_out)272  _mesa_shift_left_m(uint8_t size_words, const uint32_t *a, uint32_t dist, uint32_t *m_out)
273  {
274      uint32_t word_dist;
275      uint8_t inner_dist;
276      uint8_t i;
277  
278      word_dist = dist >> 5;
279      if (word_dist < size_words) {
280          a += index_multiword_lo_but(size_words, word_dist);
281          inner_dist = dist & 31;
282          if (inner_dist) {
283              _mesa_short_shift_left_m(size_words - word_dist, a, inner_dist,
284                                       m_out + index_multiword_hi_but(size_words, word_dist));
285              if (!word_dist)
286                  return;
287          } else {
288              uint32_t *dest = m_out + index_word_hi(size_words);
289              a += index_word_hi(size_words - word_dist);
290              for (i = size_words - word_dist; i; --i) {
291                  *dest = *a;
292                  a -= word_incr;
293                  dest -= word_incr;
294              }
295          }
296          m_out += index_multiword_lo(size_words, word_dist);
297      } else {
298          word_dist = size_words;
299      }
300      do {
301          *m_out++ = 0;
302          --word_dist;
303      } while (word_dist);
304  }
305  
306  /**
307   * \brief Shifts the N-bit unsigned integer pointed to by 'a' right by the number of
308   * bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'
309   * must be in the range 1 to 31.  Any nonzero bits shifted off are lost.  The
310   * shifted N-bit result is stored at the location pointed to by 'm_out'.  Each
311   * of 'a' and 'm_out' points to a 'size_words'-long array of 32-bit elements
312   * that concatenate in the platform's normal endian order to form an N-bit
313   * integer.
314   *
315   * From softfloat_shortShiftRightM()
316   */
317  static inline void
_mesa_short_shift_right_m(uint8_t size_words,const uint32_t * a,uint8_t dist,uint32_t * m_out)318  _mesa_short_shift_right_m(uint8_t size_words, const uint32_t *a, uint8_t dist, uint32_t *m_out)
319  {
320      uint8_t neg_dist;
321      unsigned index, last_index;
322      uint32_t part_word, a_word;
323  
324      neg_dist = -dist;
325      index = index_word_lo(size_words);
326      last_index = index_word_hi(size_words);
327      part_word = a[index] >> dist;
328      while (index != last_index) {
329          a_word = a[index + word_incr];
330          m_out[index] = a_word << (neg_dist & 31) | part_word;
331          index += word_incr;
332          part_word = a_word >> dist;
333      }
334      m_out[index] = part_word;
335  }
336  
337  /**
338   * \brief Shifts the N-bit unsigned integer pointed to by 'a' right by the number of
339   * bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'
340   * must be in the range 1 to 31.  If any nonzero bits are shifted off, they
341   * are "jammed" into the least-significant bit of the shifted value by setting
342   * the least-significant bit to 1.  This shifted-and-jammed N-bit result is
343   * stored at the location pointed to by 'm_out'.  Each of 'a' and 'm_out'
344   * points to a 'size_words'-long array of 32-bit elements that concatenate in
345   * the platform's normal endian order to form an N-bit integer.
346   *
347   *
348   * From softfloat_shortShiftRightJamM()
349   */
350  static inline void
_mesa_short_shift_right_jam_m(uint8_t size_words,const uint32_t * a,uint8_t dist,uint32_t * m_out)351  _mesa_short_shift_right_jam_m(uint8_t size_words, const uint32_t *a, uint8_t dist, uint32_t *m_out)
352  {
353      uint8_t neg_dist;
354      unsigned index, last_index;
355      uint64_t part_word, a_word;
356  
357      neg_dist = -dist;
358      index = index_word_lo(size_words);
359      last_index = index_word_hi(size_words);
360      a_word = a[index];
361      part_word = a_word >> dist;
362      if (part_word << dist != a_word )
363          part_word |= 1;
364      while (index != last_index) {
365          a_word = a[index + word_incr];
366          m_out[index] = a_word << (neg_dist & 31) | part_word;
367          index += word_incr;
368          part_word = a_word >> dist;
369      }
370      m_out[index] = part_word;
371  }
372  
373  /**
374   * \brief Shifts the N-bit unsigned integer pointed to by 'a' right by the number of
375   * bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'
376   * must not be zero.  If any nonzero bits are shifted off, they are "jammed"
377   * into the least-significant bit of the shifted value by setting the
378   * least-significant bit to 1.  This shifted-and-jammed N-bit result is stored
379   * at the location pointed to by 'm_out'.  Each of 'a' and 'm_out' points to a
380   * 'size_words'-long array of 32-bit elements that concatenate in the
381   * platform's normal endian order to form an N-bit integer.  The value of
382   * 'dist' can be arbitrarily large.  In particular, if 'dist' is greater than
383   * N, the stored result will be either 0 or 1, depending on whether the
384   * original N bits are all zeros.
385   *
386   * From softfloat_shiftRightJamM()
387   */
388  static inline void
_mesa_shift_right_jam_m(uint8_t size_words,const uint32_t * a,uint32_t dist,uint32_t * m_out)389  _mesa_shift_right_jam_m(uint8_t size_words, const uint32_t *a, uint32_t dist, uint32_t *m_out)
390  {
391      uint32_t word_jam, word_dist, *tmp;
392      uint8_t i, inner_dist;
393  
394      word_jam = 0;
395      word_dist = dist >> 5;
396      tmp = NULL;
397      if (word_dist) {
398          if (size_words < word_dist)
399              word_dist = size_words;
400          tmp = (uint32_t *) (a + index_multiword_lo(size_words, word_dist));
401          i = word_dist;
402          do {
403              word_jam = *tmp++;
404              if (word_jam)
405                  break;
406              --i;
407          } while (i);
408          tmp = m_out;
409      }
410      if (word_dist < size_words) {
411          a += index_multiword_hi_but(size_words, word_dist);
412          inner_dist = dist & 31;
413          if (inner_dist) {
414              _mesa_short_shift_right_jam_m(size_words - word_dist, a, inner_dist,
415                                            m_out + index_multiword_lo_but(size_words, word_dist));
416              if (!word_dist) {
417                  if (word_jam)
418                      m_out[index_word_lo(size_words)] |= 1;
419                  return;
420              }
421          } else {
422              a += index_word_lo(size_words - word_dist);
423              tmp = m_out + index_word_lo(size_words);
424              for (i = size_words - word_dist; i; --i) {
425                  *tmp = *a;
426                  a += word_incr;
427                  tmp += word_incr;
428              }
429          }
430          tmp = m_out + index_multiword_hi(size_words, word_dist);
431      }
432      if (tmp) {
433         do {
434             *tmp++ = 0;
435             --word_dist;
436         } while (word_dist);
437      }
438      if (word_jam)
439          m_out[index_word_lo(size_words)] |= 1;
440  }
441  
442  /**
443   * \brief Calculate a + b but rounding to zero.
444   *
445   * Notice that this mainly differs from the original Berkeley SoftFloat 3e
446   * implementation in that we don't really treat NaNs, Zeroes nor the
447   * signalling flags. Any NaN is good for us and the sign of the Zero is not
448   * important.
449   *
450   * From f64_add()
451   */
452  double
_mesa_double_add_rtz(double a,double b)453  _mesa_double_add_rtz(double a, double b)
454  {
455      const di_type a_di = {a};
456      uint64_t a_flt_m = a_di.u & 0x0fffffffffffff;
457      uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff;
458      uint64_t a_flt_s = (a_di.u >> 63) & 0x1;
459      const di_type b_di = {b};
460      uint64_t b_flt_m = b_di.u & 0x0fffffffffffff;
461      uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff;
462      uint64_t b_flt_s = (b_di.u >> 63) & 0x1;
463      int64_t s, e, m = 0;
464  
465      s = a_flt_s;
466  
467      const int64_t exp_diff = a_flt_e - b_flt_e;
468  
469      /* Handle special cases */
470  
471      if (a_flt_s != b_flt_s) {
472          return _mesa_double_sub_rtz(a, -b);
473      } else if ((a_flt_e == 0) && (a_flt_m == 0)) {
474          /* 'a' is zero, return 'b' */
475          return b;
476      } else if ((b_flt_e == 0) && (b_flt_m == 0)) {
477          /* 'b' is zero, return 'a' */
478          return a;
479      } else if (a_flt_e == 0x7ff && a_flt_m != 0) {
480          /* 'a' is a NaN, return NaN */
481          return a;
482      } else if (b_flt_e == 0x7ff && b_flt_m != 0) {
483          /* 'b' is a NaN, return NaN */
484          return b;
485      } else if (a_flt_e == 0x7ff && a_flt_m == 0) {
486          /* Inf + x = Inf */
487          return a;
488      } else if (b_flt_e == 0x7ff && b_flt_m == 0) {
489          /* x + Inf = Inf */
490          return b;
491      } else if (exp_diff == 0 && a_flt_e == 0) {
492          di_type result_di;
493          result_di.u = a_di.u + b_flt_m;
494          return result_di.f;
495      } else if (exp_diff == 0) {
496          e = a_flt_e;
497          m = 0x0020000000000000 + a_flt_m + b_flt_m;
498          m <<= 9;
499      } else if (exp_diff < 0) {
500          a_flt_m <<= 9;
501          b_flt_m <<= 9;
502          e = b_flt_e;
503  
504          if (a_flt_e != 0)
505              a_flt_m += 0x2000000000000000;
506          else
507              a_flt_m <<= 1;
508  
509          a_flt_m = _mesa_shift_right_jam64(a_flt_m, -exp_diff);
510          m = 0x2000000000000000 + a_flt_m + b_flt_m;
511          if (m < 0x4000000000000000) {
512              --e;
513              m <<= 1;
514          }
515      } else {
516          a_flt_m <<= 9;
517          b_flt_m <<= 9;
518          e = a_flt_e;
519  
520          if (b_flt_e != 0)
521              b_flt_m += 0x2000000000000000;
522          else
523              b_flt_m <<= 1;
524  
525          b_flt_m = _mesa_shift_right_jam64(b_flt_m, exp_diff);
526          m = 0x2000000000000000 + a_flt_m + b_flt_m;
527          if (m < 0x4000000000000000) {
528              --e;
529              m <<= 1;
530          }
531      }
532  
533      return _mesa_roundtozero_f64(s, e, m);
534  }
535  
536  /**
537   * \brief Returns the number of leading 0 bits before the most-significant 1 bit of
538   * 'a'.  If 'a' is zero, 64 is returned.
539   */
540  static inline unsigned
_mesa_count_leading_zeros64(uint64_t a)541  _mesa_count_leading_zeros64(uint64_t a)
542  {
543      return 64 - util_last_bit64(a);
544  }
545  
546  /**
547   * \brief Returns the number of leading 0 bits before the most-significant 1 bit of
548   * 'a'.  If 'a' is zero, 32 is returned.
549   */
550  static inline unsigned
_mesa_count_leading_zeros32(uint32_t a)551  _mesa_count_leading_zeros32(uint32_t a)
552  {
553      return 32 - util_last_bit(a);
554  }
555  
556  static inline double
_mesa_norm_round_pack_f64(int64_t s,int64_t e,int64_t m)557  _mesa_norm_round_pack_f64(int64_t s, int64_t e, int64_t m)
558  {
559      int8_t shift_dist;
560  
561      shift_dist = _mesa_count_leading_zeros64(m) - 1;
562      e -= shift_dist;
563      if ((10 <= shift_dist) && ((unsigned) e < 0x7fd)) {
564          di_type result;
565          result.u = (s << 63) + ((m ? e : 0) << 52) + (m << (shift_dist - 10));
566          return result.f;
567      } else {
568          return _mesa_roundtozero_f64(s, e, m << shift_dist);
569      }
570  }
571  
572  /**
573   * \brief Replaces the N-bit unsigned integer pointed to by 'm_out' by the
574   * 2s-complement of itself, where N = 'size_words' * 32.  Argument 'm_out'
575   * points to a 'size_words'-long array of 32-bit elements that concatenate in
576   * the platform's normal endian order to form an N-bit integer.
577   *
578   * From softfloat_negXM()
579   */
580  static inline void
_mesa_neg_x_m(uint8_t size_words,uint32_t * m_out)581  _mesa_neg_x_m(uint8_t size_words, uint32_t *m_out)
582  {
583      unsigned index, last_index;
584      uint8_t carry;
585      uint32_t word;
586  
587      index = index_word_lo(size_words);
588      last_index = index_word_hi(size_words);
589      carry = 1;
590      for (;;) {
591          word = ~m_out[index] + carry;
592          m_out[index] = word;
593          if (index == last_index)
594              break;
595          index += word_incr;
596          if (word)
597              carry = 0;
598      }
599  }
600  
601  /**
602   * \brief Adds the two N-bit integers pointed to by 'a' and 'b', where N =
603   * 'size_words' * 32.  The addition is modulo 2^N, so any carry out is
604   * lost. The N-bit sum is stored at the location pointed to by 'm_out'.  Each
605   * of 'a', 'b', and 'm_out' points to a 'size_words'-long array of 32-bit
606   * elements that concatenate in the platform's normal endian order to form an
607   * N-bit integer.
608   *
609   * From softfloat_addM()
610   */
611  static inline void
_mesa_add_m(uint8_t size_words,const uint32_t * a,const uint32_t * b,uint32_t * m_out)612  _mesa_add_m(uint8_t size_words, const uint32_t *a, const uint32_t *b, uint32_t *m_out)
613  {
614      unsigned index, last_index;
615      uint8_t carry;
616      uint32_t a_word, word;
617  
618      index = index_word_lo(size_words);
619      last_index = index_word_hi(size_words);
620      carry = 0;
621      for (;;) {
622          a_word = a[index];
623          word = a_word + b[index] + carry;
624          m_out[index] = word;
625          if (index == last_index)
626              break;
627          if (word != a_word)
628              carry = (word < a_word);
629          index += word_incr;
630      }
631  }
632  
633  /**
634   * \brief Subtracts the two N-bit integers pointed to by 'a' and 'b', where N =
635   * 'size_words' * 32.  The subtraction is modulo 2^N, so any borrow out (carry
636   * out) is lost.  The N-bit difference is stored at the location pointed to by
637   * 'm_out'.  Each of 'a', 'b', and 'm_out' points to a 'size_words'-long array
638   * of 32-bit elements that concatenate in the platform's normal endian order
639   * to form an N-bit integer.
640   *
641   * From softfloat_subM()
642   */
643  static inline void
_mesa_sub_m(uint8_t size_words,const uint32_t * a,const uint32_t * b,uint32_t * m_out)644  _mesa_sub_m(uint8_t size_words, const uint32_t *a, const uint32_t *b, uint32_t *m_out)
645  {
646      unsigned index, last_index;
647      uint8_t borrow;
648      uint32_t a_word, b_word;
649  
650      index = index_word_lo(size_words);
651      last_index = index_word_hi(size_words);
652      borrow = 0;
653      for (;;) {
654          a_word = a[index];
655          b_word = b[index];
656          m_out[index] = a_word - b_word - borrow;
657          if (index == last_index)
658              break;
659          borrow = borrow ? (a_word <= b_word) : (a_word < b_word);
660          index += word_incr;
661      }
662  }
663  
664  /* Calculate a - b but rounding to zero.
665   *
666   * Notice that this mainly differs from the original Berkeley SoftFloat 3e
667   * implementation in that we don't really treat NaNs, Zeroes nor the
668   * signalling flags. Any NaN is good for us and the sign of the Zero is not
669   * important.
670   *
671   * From f64_sub()
672   */
673  double
_mesa_double_sub_rtz(double a,double b)674  _mesa_double_sub_rtz(double a, double b)
675  {
676      const di_type a_di = {a};
677      uint64_t a_flt_m = a_di.u & 0x0fffffffffffff;
678      uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff;
679      uint64_t a_flt_s = (a_di.u >> 63) & 0x1;
680      const di_type b_di = {b};
681      uint64_t b_flt_m = b_di.u & 0x0fffffffffffff;
682      uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff;
683      uint64_t b_flt_s = (b_di.u >> 63) & 0x1;
684      int64_t s, e, m = 0;
685      int64_t m_diff = 0;
686      unsigned shift_dist = 0;
687  
688      s = a_flt_s;
689  
690      const int64_t exp_diff = a_flt_e - b_flt_e;
691  
692      /* Handle special cases */
693  
694      if (a_flt_s != b_flt_s) {
695          return _mesa_double_add_rtz(a, -b);
696      } else if ((a_flt_e == 0) && (a_flt_m == 0)) {
697          /* 'a' is zero, return '-b' */
698          return -b;
699      } else if ((b_flt_e == 0) && (b_flt_m == 0)) {
700          /* 'b' is zero, return 'a' */
701          return a;
702      } else if (a_flt_e == 0x7ff && a_flt_m != 0) {
703          /* 'a' is a NaN, return NaN */
704          return a;
705      } else if (b_flt_e == 0x7ff && b_flt_m != 0) {
706          /* 'b' is a NaN, return NaN */
707          return b;
708      } else if (a_flt_e == 0x7ff && a_flt_m == 0) {
709          if (b_flt_e == 0x7ff && b_flt_m == 0) {
710              /* Inf - Inf =  NaN */
711              di_type result;
712              e = 0x7ff;
713              result.u = (s << 63) + (e << 52) + 0x1;
714              return result.f;
715          }
716          /* Inf - x = Inf */
717          return a;
718      } else if (b_flt_e == 0x7ff && b_flt_m == 0) {
719          /* x - Inf = -Inf */
720          return -b;
721      } else if (exp_diff == 0) {
722          m_diff = a_flt_m - b_flt_m;
723  
724          if (m_diff == 0)
725              return 0;
726          if (a_flt_e)
727              --a_flt_e;
728          if (m_diff < 0) {
729              s = !s;
730              m_diff = -m_diff;
731          }
732  
733          shift_dist = _mesa_count_leading_zeros64(m_diff) - 11;
734          e = a_flt_e - shift_dist;
735          if (e < 0) {
736              shift_dist = a_flt_e;
737              e = 0;
738          }
739  
740          di_type result;
741          result.u = (s << 63) + (e << 52) + (m_diff << shift_dist);
742          return result.f;
743      } else if (exp_diff < 0) {
744          a_flt_m <<= 10;
745          b_flt_m <<= 10;
746          s = !s;
747  
748          a_flt_m += (a_flt_e) ? 0x4000000000000000 : a_flt_m;
749          a_flt_m = _mesa_shift_right_jam64(a_flt_m, -exp_diff);
750          b_flt_m |= 0x4000000000000000;
751          e = b_flt_e;
752          m = b_flt_m - a_flt_m;
753      } else {
754          a_flt_m <<= 10;
755          b_flt_m <<= 10;
756  
757          b_flt_m += (b_flt_e) ? 0x4000000000000000 : b_flt_m;
758          b_flt_m = _mesa_shift_right_jam64(b_flt_m, exp_diff);
759          a_flt_m |= 0x4000000000000000;
760          e = a_flt_e;
761          m = a_flt_m - b_flt_m;
762      }
763  
764      return _mesa_norm_round_pack_f64(s, e - 1, m);
765  }
766  
767  static inline void
_mesa_norm_subnormal_mantissa_f64(uint64_t m,uint64_t * exp,uint64_t * m_out)768  _mesa_norm_subnormal_mantissa_f64(uint64_t m, uint64_t *exp, uint64_t *m_out)
769  {
770      int shift_dist;
771  
772      shift_dist = _mesa_count_leading_zeros64(m) - 11;
773      *exp = 1 - shift_dist;
774      *m_out = m << shift_dist;
775  }
776  
777  static inline void
_mesa_norm_subnormal_mantissa_f32(uint32_t m,uint32_t * exp,uint32_t * m_out)778  _mesa_norm_subnormal_mantissa_f32(uint32_t m, uint32_t *exp, uint32_t *m_out)
779  {
780      int shift_dist;
781  
782      shift_dist = _mesa_count_leading_zeros32(m) - 8;
783      *exp = 1 - shift_dist;
784      *m_out = m << shift_dist;
785  }
786  
787  /**
788   * \brief Multiplies 'a' and 'b' and stores the 128-bit product at the location
789   * pointed to by 'zPtr'.  Argument 'zPtr' points to an array of four 32-bit
790   * elements that concatenate in the platform's normal endian order to form a
791   * 128-bit integer.
792   *
793   * From softfloat_mul64To128M()
794   */
795  static inline void
_mesa_softfloat_mul_f64_to_f128_m(uint64_t a,uint64_t b,uint32_t * m_out)796  _mesa_softfloat_mul_f64_to_f128_m(uint64_t a, uint64_t b, uint32_t *m_out)
797  {
798      uint32_t a32, a0, b32, b0;
799      uint64_t z0, mid1, z64, mid;
800  
801      a32 = a >> 32;
802      a0 = a;
803      b32 = b >> 32;
804      b0 = b;
805      z0 = (uint64_t) a0 * b0;
806      mid1 = (uint64_t) a32 * b0;
807      mid = mid1 + (uint64_t) a0 * b32;
808      z64 = (uint64_t) a32 * b32;
809      z64 += (uint64_t) (mid < mid1) << 32 | mid >> 32;
810      mid <<= 32;
811      z0 += mid;
812      m_out[index_word(4, 1)] = z0 >> 32;
813      m_out[index_word(4, 0)] = z0;
814      z64 += (z0 < mid);
815      m_out[index_word(4, 3)] = z64 >> 32;
816      m_out[index_word(4, 2)] = z64;
817  }
818  
819  /* Calculate a * b but rounding to zero.
820   *
821   * Notice that this mainly differs from the original Berkeley SoftFloat 3e
822   * implementation in that we don't really treat NaNs, Zeroes nor the
823   * signalling flags. Any NaN is good for us and the sign of the Zero is not
824   * important.
825   *
826   * From f64_mul()
827   */
828  double
_mesa_double_mul_rtz(double a,double b)829  _mesa_double_mul_rtz(double a, double b)
830  {
831      const di_type a_di = {a};
832      uint64_t a_flt_m = a_di.u & 0x0fffffffffffff;
833      uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff;
834      uint64_t a_flt_s = (a_di.u >> 63) & 0x1;
835      const di_type b_di = {b};
836      uint64_t b_flt_m = b_di.u & 0x0fffffffffffff;
837      uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff;
838      uint64_t b_flt_s = (b_di.u >> 63) & 0x1;
839      int64_t s, e, m = 0;
840  
841      s = a_flt_s ^ b_flt_s;
842  
843      if (a_flt_e == 0x7ff) {
844          if (a_flt_m != 0) {
845              /* 'a' is a NaN, return NaN */
846              return a;
847          } else if (b_flt_e == 0x7ff && b_flt_m != 0) {
848              /* 'b' is a NaN, return NaN */
849              return b;
850          }
851  
852          if (!(b_flt_e | b_flt_m)) {
853              /* Inf * 0 = NaN */
854              di_type result;
855              e = 0x7ff;
856              result.u = (s << 63) + (e << 52) + 0x1;
857              return result.f;
858          }
859          /* Inf * x = Inf */
860          di_type result;
861          e = 0x7ff;
862          result.u = (s << 63) + (e << 52) + 0;
863          return result.f;
864      }
865  
866      if (b_flt_e == 0x7ff) {
867          if (b_flt_m != 0) {
868              /* 'b' is a NaN, return NaN */
869              return b;
870          }
871          if (!(a_flt_e | a_flt_m)) {
872              /* 0 * Inf = NaN */
873              di_type result;
874              e = 0x7ff;
875              result.u = (s << 63) + (e << 52) + 0x1;
876              return result.f;
877          }
878          /* x * Inf = Inf */
879          di_type result;
880          e = 0x7ff;
881          result.u = (s << 63) + (e << 52) + 0;
882          return result.f;
883      }
884  
885      if (a_flt_e == 0) {
886          if (a_flt_m == 0) {
887              /* 'a' is zero. Return zero */
888              di_type result;
889              result.u = (s << 63) + 0;
890              return result.f;
891          }
892          _mesa_norm_subnormal_mantissa_f64(a_flt_m , &a_flt_e, &a_flt_m);
893      }
894      if (b_flt_e == 0) {
895          if (b_flt_m == 0) {
896              /* 'b' is zero. Return zero */
897              di_type result;
898              result.u = (s << 63) + 0;
899              return result.f;
900          }
901          _mesa_norm_subnormal_mantissa_f64(b_flt_m , &b_flt_e, &b_flt_m);
902      }
903  
904      e = a_flt_e + b_flt_e - 0x3ff;
905      a_flt_m = (a_flt_m | 0x0010000000000000) << 10;
906      b_flt_m = (b_flt_m | 0x0010000000000000) << 11;
907  
908      uint32_t m_128[4];
909      _mesa_softfloat_mul_f64_to_f128_m(a_flt_m, b_flt_m, m_128);
910  
911      m = (uint64_t) m_128[index_word(4, 3)] << 32 | m_128[index_word(4, 2)];
912      if (m_128[index_word(4, 1)] || m_128[index_word(4, 0)])
913          m |= 1;
914  
915      if (m < 0x4000000000000000) {
916          --e;
917          m <<= 1;
918      }
919  
920      return _mesa_roundtozero_f64(s, e, m);
921  }
922  
923  
924  /**
925   * \brief Calculate a * b + c but rounding to zero.
926   *
927   * Notice that this mainly differs from the original Berkeley SoftFloat 3e
928   * implementation in that we don't really treat NaNs, Zeroes nor the
929   * signalling flags. Any NaN is good for us and the sign of the Zero is not
930   * important.
931   *
932   * From f64_mulAdd()
933   */
934  double
_mesa_double_fma_rtz(double a,double b,double c)935  _mesa_double_fma_rtz(double a, double b, double c)
936  {
937      const di_type a_di = {a};
938      uint64_t a_flt_m = a_di.u & 0x0fffffffffffff;
939      uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff;
940      uint64_t a_flt_s = (a_di.u >> 63) & 0x1;
941      const di_type b_di = {b};
942      uint64_t b_flt_m = b_di.u & 0x0fffffffffffff;
943      uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff;
944      uint64_t b_flt_s = (b_di.u >> 63) & 0x1;
945      const di_type c_di = {c};
946      uint64_t c_flt_m = c_di.u & 0x0fffffffffffff;
947      uint64_t c_flt_e = (c_di.u >> 52) & 0x7ff;
948      uint64_t c_flt_s = (c_di.u >> 63) & 0x1;
949      int64_t s, e, m = 0;
950  
951      c_flt_s ^= 0;
952      s = a_flt_s ^ b_flt_s ^ 0;
953  
954      if (a_flt_e == 0x7ff) {
955          if (a_flt_m != 0) {
956              /* 'a' is a NaN, return NaN */
957              return a;
958          } else if (b_flt_e == 0x7ff && b_flt_m != 0) {
959              /* 'b' is a NaN, return NaN */
960              return b;
961          } else if (c_flt_e == 0x7ff && c_flt_m != 0) {
962              /* 'c' is a NaN, return NaN */
963              return c;
964          }
965  
966          if (!(b_flt_e | b_flt_m)) {
967              /* Inf * 0 + y = NaN */
968              di_type result;
969              e = 0x7ff;
970              result.u = (s << 63) + (e << 52) + 0x1;
971              return result.f;
972          }
973  
974          if ((c_flt_e == 0x7ff && c_flt_m == 0) && (s != c_flt_s)) {
975              /* Inf * x - Inf = NaN */
976              di_type result;
977              e = 0x7ff;
978              result.u = (s << 63) + (e << 52) + 0x1;
979              return result.f;
980          }
981  
982          /* Inf * x + y = Inf */
983          di_type result;
984          e = 0x7ff;
985          result.u = (s << 63) + (e << 52) + 0;
986          return result.f;
987      }
988  
989      if (b_flt_e == 0x7ff) {
990          if (b_flt_m != 0) {
991              /* 'b' is a NaN, return NaN */
992              return b;
993          } else if (c_flt_e == 0x7ff && c_flt_m != 0) {
994              /* 'c' is a NaN, return NaN */
995              return c;
996          }
997  
998          if (!(a_flt_e | a_flt_m)) {
999              /* 0 * Inf + y = NaN */
1000              di_type result;
1001              e = 0x7ff;
1002              result.u = (s << 63) + (e << 52) + 0x1;
1003              return result.f;
1004          }
1005  
1006          if ((c_flt_e == 0x7ff && c_flt_m == 0) && (s != c_flt_s)) {
1007              /* x * Inf - Inf = NaN */
1008              di_type result;
1009              e = 0x7ff;
1010              result.u = (s << 63) + (e << 52) + 0x1;
1011              return result.f;
1012          }
1013  
1014          /* x * Inf + y = Inf */
1015          di_type result;
1016          e = 0x7ff;
1017          result.u = (s << 63) + (e << 52) + 0;
1018          return result.f;
1019      }
1020  
1021      if (c_flt_e == 0x7ff) {
1022          if (c_flt_m != 0) {
1023              /* 'c' is a NaN, return NaN */
1024              return c;
1025          }
1026  
1027          /* x * y + Inf = Inf */
1028          return c;
1029      }
1030  
1031      if (a_flt_e == 0) {
1032          if (a_flt_m == 0) {
1033              /* 'a' is zero, return 'c' */
1034              return c;
1035          }
1036          _mesa_norm_subnormal_mantissa_f64(a_flt_m , &a_flt_e, &a_flt_m);
1037      }
1038  
1039      if (b_flt_e == 0) {
1040          if (b_flt_m == 0) {
1041              /* 'b' is zero, return 'c' */
1042              return c;
1043          }
1044          _mesa_norm_subnormal_mantissa_f64(b_flt_m , &b_flt_e, &b_flt_m);
1045      }
1046  
1047      e = a_flt_e + b_flt_e - 0x3fe;
1048      a_flt_m = (a_flt_m | 0x0010000000000000) << 10;
1049      b_flt_m = (b_flt_m | 0x0010000000000000) << 11;
1050  
1051      uint32_t m_128[4];
1052      _mesa_softfloat_mul_f64_to_f128_m(a_flt_m, b_flt_m, m_128);
1053  
1054      m = (uint64_t) m_128[index_word(4, 3)] << 32 | m_128[index_word(4, 2)];
1055  
1056      int64_t shift_dist = 0;
1057      if (!(m & 0x4000000000000000)) {
1058          --e;
1059          shift_dist = -1;
1060      }
1061  
1062      if (c_flt_e == 0) {
1063          if (c_flt_m == 0) {
1064              /* 'c' is zero, return 'a * b' */
1065              if (shift_dist)
1066                  m <<= 1;
1067  
1068              if (m_128[index_word(4, 1)] || m_128[index_word(4, 0)])
1069                  m |= 1;
1070              return _mesa_roundtozero_f64(s, e - 1, m);
1071          }
1072          _mesa_norm_subnormal_mantissa_f64(c_flt_m , &c_flt_e, &c_flt_m);
1073      }
1074      c_flt_m = (c_flt_m | 0x0010000000000000) << 10;
1075  
1076      uint32_t c_flt_m_128[4];
1077      int64_t exp_diff = e - c_flt_e;
1078      if (exp_diff < 0) {
1079          e = c_flt_e;
1080          if ((s == c_flt_s) || (exp_diff < -1)) {
1081              shift_dist -= exp_diff;
1082              if (shift_dist) {
1083                  m = _mesa_shift_right_jam64(m, shift_dist);
1084              }
1085          } else {
1086              if (!shift_dist) {
1087                  _mesa_short_shift_right_m(4, m_128, 1, m_128);
1088              }
1089          }
1090      } else {
1091          if (shift_dist)
1092              _mesa_add_m(4, m_128, m_128, m_128);
1093          if (!exp_diff) {
1094              m = (uint64_t) m_128[index_word(4, 3)] << 32
1095                  | m_128[index_word(4, 2)];
1096          } else {
1097              c_flt_m_128[index_word(4, 3)] = c_flt_m >> 32;
1098              c_flt_m_128[index_word(4, 2)] = c_flt_m;
1099              c_flt_m_128[index_word(4, 1)] = 0;
1100              c_flt_m_128[index_word(4, 0)] = 0;
1101              _mesa_shift_right_jam_m(4, c_flt_m_128, exp_diff, c_flt_m_128);
1102          }
1103      }
1104  
1105      if (s == c_flt_s) {
1106          if (exp_diff <= 0) {
1107              m += c_flt_m;
1108          } else {
1109              _mesa_add_m(4, m_128, c_flt_m_128, m_128);
1110              m = (uint64_t) m_128[index_word(4, 3)] << 32
1111                  | m_128[index_word(4, 2)];
1112          }
1113          if (m & 0x8000000000000000) {
1114              e++;
1115              m = _mesa_short_shift_right_jam64(m, 1);
1116          }
1117      } else {
1118          if (exp_diff < 0) {
1119              s = c_flt_s;
1120              if (exp_diff < -1) {
1121                  m = c_flt_m - m;
1122                  if (m_128[index_word(4, 1)] || m_128[index_word(4, 0)]) {
1123                      m = (m - 1) | 1;
1124                  }
1125                  if (!(m & 0x4000000000000000)) {
1126                      --e;
1127                      m <<= 1;
1128                  }
1129                  return _mesa_roundtozero_f64(s, e - 1, m);
1130              } else {
1131                  c_flt_m_128[index_word(4, 3)] = c_flt_m >> 32;
1132                  c_flt_m_128[index_word(4, 2)] = c_flt_m;
1133                  c_flt_m_128[index_word(4, 1)] = 0;
1134                  c_flt_m_128[index_word(4, 0)] = 0;
1135                  _mesa_sub_m(4, c_flt_m_128, m_128, m_128);
1136              }
1137          } else if (!exp_diff) {
1138              m -= c_flt_m;
1139              if (!m && !m_128[index_word(4, 1)] && !m_128[index_word(4, 0)]) {
1140                  /* Return zero */
1141                  di_type result;
1142                  result.u = (s << 63) + 0;
1143                  return result.f;
1144              }
1145              m_128[index_word(4, 3)] = m >> 32;
1146              m_128[index_word(4, 2)] = m;
1147              if (m & 0x8000000000000000) {
1148                  s = !s;
1149                  _mesa_neg_x_m(4, m_128);
1150              }
1151          } else {
1152              _mesa_sub_m(4, m_128, c_flt_m_128, m_128);
1153              if (1 < exp_diff) {
1154                  m = (uint64_t) m_128[index_word(4, 3)] << 32
1155                      | m_128[index_word(4, 2)];
1156                  if (!(m & 0x4000000000000000)) {
1157                      --e;
1158                      m <<= 1;
1159                  }
1160                  if (m_128[index_word(4, 1)] || m_128[index_word(4, 0)])
1161                      m |= 1;
1162                  return _mesa_roundtozero_f64(s, e - 1, m);
1163              }
1164          }
1165  
1166          shift_dist = 0;
1167          m = (uint64_t) m_128[index_word(4, 3)] << 32
1168              | m_128[index_word(4, 2)];
1169          if (!m) {
1170              shift_dist = 64;
1171              m = (uint64_t) m_128[index_word(4, 1)] << 32
1172                  | m_128[index_word(4, 0)];
1173          }
1174          shift_dist += _mesa_count_leading_zeros64(m) - 1;
1175          if (shift_dist) {
1176              e -= shift_dist;
1177              _mesa_shift_left_m(4, m_128, shift_dist, m_128);
1178              m = (uint64_t) m_128[index_word(4, 3)] << 32
1179                  | m_128[index_word(4, 2)];
1180          }
1181      }
1182  
1183      if (m_128[index_word(4, 1)] || m_128[index_word(4, 0)])
1184          m |= 1;
1185      return _mesa_roundtozero_f64(s, e - 1, m);
1186  }
1187  
1188  
1189  /**
1190   * \brief Calculate a * b + c but rounding to zero.
1191   *
1192   * Notice that this mainly differs from the original Berkeley SoftFloat 3e
1193   * implementation in that we don't really treat NaNs, Zeroes nor the
1194   * signalling flags. Any NaN is good for us and the sign of the Zero is not
1195   * important.
1196   *
1197   * From f32_mulAdd()
1198   */
1199  float
_mesa_float_fma_rtz(float a,float b,float c)1200  _mesa_float_fma_rtz(float a, float b, float c)
1201  {
1202      const fi_type a_fi = {a};
1203      uint32_t a_flt_m = a_fi.u & 0x07fffff;
1204      uint32_t a_flt_e = (a_fi.u >> 23) & 0xff;
1205      uint32_t a_flt_s = (a_fi.u >> 31) & 0x1;
1206      const fi_type b_fi = {b};
1207      uint32_t b_flt_m = b_fi.u & 0x07fffff;
1208      uint32_t b_flt_e = (b_fi.u >> 23) & 0xff;
1209      uint32_t b_flt_s = (b_fi.u >> 31) & 0x1;
1210      const fi_type c_fi = {c};
1211      uint32_t c_flt_m = c_fi.u & 0x07fffff;
1212      uint32_t c_flt_e = (c_fi.u >> 23) & 0xff;
1213      uint32_t c_flt_s = (c_fi.u >> 31) & 0x1;
1214      int32_t s, e, m = 0;
1215  
1216      c_flt_s ^= 0;
1217      s = a_flt_s ^ b_flt_s ^ 0;
1218  
1219      if (a_flt_e == 0xff) {
1220          if (a_flt_m != 0) {
1221              /* 'a' is a NaN, return NaN */
1222              return a;
1223          } else if (b_flt_e == 0xff && b_flt_m != 0) {
1224              /* 'b' is a NaN, return NaN */
1225              return b;
1226          } else if (c_flt_e == 0xff && c_flt_m != 0) {
1227              /* 'c' is a NaN, return NaN */
1228              return c;
1229          }
1230  
1231          if (!(b_flt_e | b_flt_m)) {
1232              /* Inf * 0 + y = NaN */
1233              fi_type result;
1234              e = 0xff;
1235              result.u = (s << 31) + (e << 23) + 0x1;
1236              return result.f;
1237          }
1238  
1239          if ((c_flt_e == 0xff && c_flt_m == 0) && (s != c_flt_s)) {
1240              /* Inf * x - Inf = NaN */
1241              fi_type result;
1242              e = 0xff;
1243              result.u = (s << 31) + (e << 23) + 0x1;
1244              return result.f;
1245          }
1246  
1247          /* Inf * x + y = Inf */
1248          fi_type result;
1249          e = 0xff;
1250          result.u = (s << 31) + (e << 23) + 0;
1251          return result.f;
1252      }
1253  
1254      if (b_flt_e == 0xff) {
1255          if (b_flt_m != 0) {
1256              /* 'b' is a NaN, return NaN */
1257              return b;
1258          } else if (c_flt_e == 0xff && c_flt_m != 0) {
1259              /* 'c' is a NaN, return NaN */
1260              return c;
1261          }
1262  
1263          if (!(a_flt_e | a_flt_m)) {
1264              /* 0 * Inf + y = NaN */
1265              fi_type result;
1266              e = 0xff;
1267              result.u = (s << 31) + (e << 23) + 0x1;
1268              return result.f;
1269          }
1270  
1271          if ((c_flt_e == 0xff && c_flt_m == 0) && (s != c_flt_s)) {
1272              /* x * Inf - Inf = NaN */
1273              fi_type result;
1274              e = 0xff;
1275              result.u = (s << 31) + (e << 23) + 0x1;
1276              return result.f;
1277          }
1278  
1279          /* x * Inf + y = Inf */
1280          fi_type result;
1281          e = 0xff;
1282          result.u = (s << 31) + (e << 23) + 0;
1283          return result.f;
1284      }
1285  
1286      if (c_flt_e == 0xff) {
1287          if (c_flt_m != 0) {
1288              /* 'c' is a NaN, return NaN */
1289              return c;
1290          }
1291  
1292          /* x * y + Inf = Inf */
1293          return c;
1294      }
1295  
1296      if (a_flt_e == 0) {
1297          if (a_flt_m == 0) {
1298              /* 'a' is zero, return 'c' */
1299              return c;
1300          }
1301          _mesa_norm_subnormal_mantissa_f32(a_flt_m , &a_flt_e, &a_flt_m);
1302      }
1303  
1304      if (b_flt_e == 0) {
1305          if (b_flt_m == 0) {
1306              /* 'b' is zero, return 'c' */
1307              return c;
1308          }
1309          _mesa_norm_subnormal_mantissa_f32(b_flt_m , &b_flt_e, &b_flt_m);
1310      }
1311  
1312      e = a_flt_e + b_flt_e - 0x7e;
1313      a_flt_m = (a_flt_m | 0x00800000) << 7;
1314      b_flt_m = (b_flt_m | 0x00800000) << 7;
1315  
1316      uint64_t m_64 = (uint64_t) a_flt_m * b_flt_m;
1317      if (m_64 < 0x2000000000000000) {
1318          --e;
1319          m_64 <<= 1;
1320      }
1321  
1322      if (c_flt_e == 0) {
1323          if (c_flt_m == 0) {
1324              /* 'c' is zero, return 'a * b' */
1325              m = _mesa_short_shift_right_jam64(m_64, 31);
1326              return _mesa_round_f32(s, e - 1, m, true);
1327          }
1328          _mesa_norm_subnormal_mantissa_f32(c_flt_m , &c_flt_e, &c_flt_m);
1329      }
1330      c_flt_m = (c_flt_m | 0x00800000) << 6;
1331  
1332      int16_t exp_diff = e - c_flt_e;
1333      if (s == c_flt_s) {
1334          if (exp_diff <= 0) {
1335              e = c_flt_e;
1336              m = c_flt_m + _mesa_shift_right_jam64(m_64, 32 - exp_diff);
1337          } else {
1338              m_64 += _mesa_shift_right_jam64((uint64_t) c_flt_m << 32, exp_diff);
1339              m = _mesa_short_shift_right_jam64(m_64, 32);
1340          }
1341          if (m < 0x40000000) {
1342              --e;
1343              m <<= 1;
1344          }
1345      } else {
1346          uint64_t c_flt_m_64 = (uint64_t) c_flt_m << 32;
1347          if (exp_diff < 0) {
1348              s = c_flt_s;
1349              e = c_flt_e;
1350              m_64 = c_flt_m_64 - _mesa_shift_right_jam64(m_64, -exp_diff);
1351          } else if (!exp_diff) {
1352              m_64 -= c_flt_m_64;
1353              if (!m_64) {
1354                  /* Return zero */
1355                  fi_type result;
1356                  result.u = (s << 31) + 0;
1357                  return result.f;
1358              }
1359              if (m_64 & 0x8000000000000000) {
1360                  s = !s;
1361                  m_64 = -m_64;
1362              }
1363          } else {
1364              m_64 -= _mesa_shift_right_jam64(c_flt_m_64, exp_diff);
1365          }
1366          int8_t shift_dist = _mesa_count_leading_zeros64(m_64) - 1;
1367          e -= shift_dist;
1368          shift_dist -= 32;
1369          if (shift_dist < 0) {
1370              m = _mesa_short_shift_right_jam64(m_64, -shift_dist);
1371          } else {
1372              m = (uint32_t) m_64 << shift_dist;
1373          }
1374      }
1375  
1376      return _mesa_round_f32(s, e, m, true);
1377  }
1378  
1379  
1380  /**
1381   * \brief Converts from 64bits to 32bits float and rounds according to
1382   * instructed.
1383   *
1384   * From f64_to_f32()
1385   */
1386  float
_mesa_double_to_f32(double val,bool rtz)1387  _mesa_double_to_f32(double val, bool rtz)
1388  {
1389      const di_type di = {val};
1390      uint64_t flt_m = di.u & 0x0fffffffffffff;
1391      uint64_t flt_e = (di.u >> 52) & 0x7ff;
1392      uint64_t flt_s = (di.u >> 63) & 0x1;
1393      int32_t s, e, m = 0;
1394  
1395      s = flt_s;
1396  
1397      if (flt_e == 0x7ff) {
1398          if (flt_m != 0) {
1399              /* 'val' is a NaN, return NaN */
1400              fi_type result;
1401              e = 0xff;
1402              m = 0x1;
1403              result.u = (s << 31) + (e << 23) + m;
1404              return result.f;
1405          }
1406  
1407          /* 'val' is Inf, return Inf */
1408          fi_type result;
1409          e = 0xff;
1410          result.u = (s << 31) + (e << 23) + m;
1411          return result.f;
1412      }
1413  
1414      if (!(flt_e | flt_m)) {
1415          /* 'val' is zero, return zero */
1416          fi_type result;
1417          e = 0;
1418          result.u = (s << 31) + (e << 23) + m;
1419          return result.f;
1420      }
1421  
1422      m = _mesa_short_shift_right_jam64(flt_m, 22);
1423      if ( ! (flt_e | m) ) {
1424          /* 'val' is denorm, return zero */
1425          fi_type result;
1426          e = 0;
1427          result.u = (s << 31) + (e << 23) + m;
1428          return result.f;
1429      }
1430  
1431      return _mesa_round_f32(s, flt_e - 0x381, m | 0x40000000, rtz);
1432  }
1433  
1434  
1435  /**
1436   * \brief Converts from 32bits to 16bits float and rounds the result to zero.
1437   *
1438   * From f32_to_f16()
1439   */
1440  uint16_t
_mesa_float_to_half_rtz_slow(float val)1441  _mesa_float_to_half_rtz_slow(float val)
1442  {
1443      const fi_type fi = {val};
1444      const uint32_t flt_m = fi.u & 0x7fffff;
1445      const uint32_t flt_e = (fi.u >> 23) & 0xff;
1446      const uint32_t flt_s = (fi.u >> 31) & 0x1;
1447      int16_t s, e, m = 0;
1448  
1449      s = flt_s;
1450  
1451      if (flt_e == 0xff) {
1452          if (flt_m != 0) {
1453              /* 'val' is a NaN, return NaN */
1454              e = 0x1f;
1455              /* Retain the top bits of a NaN to make sure that the quiet/signaling
1456              * status stays the same.
1457              */
1458              m = flt_m >> 13;
1459              if (!m)
1460                 m = 1;
1461              return (s << 15) + (e << 10) + m;
1462          }
1463  
1464          /* 'val' is Inf, return Inf */
1465          e = 0x1f;
1466          return (s << 15) + (e << 10) + m;
1467      }
1468  
1469      if (!(flt_e | flt_m)) {
1470          /* 'val' is zero, return zero */
1471          e = 0;
1472          return (s << 15) + (e << 10) + m;
1473      }
1474  
1475      m = flt_m >> 9 | ((flt_m & 0x1ff) != 0);
1476      if ( ! (flt_e | m) ) {
1477          /* 'val' is denorm, return zero */
1478          e = 0;
1479          return (s << 15) + (e << 10) + m;
1480      }
1481  
1482      return _mesa_roundtozero_f16(s, flt_e - 0x71, m | 0x4000);
1483  }
1484