fp_extend.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //===-lib/fp_extend.h - low precision -> high precision conversion -*- C
  2. //-*-===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Set source and destination setting
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef FP_EXTEND_HEADER
  14. #define FP_EXTEND_HEADER
  15. #include "int_lib.h"
  16. #if defined SRC_SINGLE
  17. typedef float src_t;
  18. typedef uint32_t src_rep_t;
  19. #define SRC_REP_C UINT32_C
  20. static const int srcBits = sizeof(src_t) * CHAR_BIT;
  21. static const int srcSigFracBits = 23;
  22. // -1 accounts for the sign bit.
  23. // srcBits - srcSigFracBits - 1
  24. static const int srcExpBits = 8;
  25. #define src_rep_t_clz clzsi
  26. #elif defined SRC_DOUBLE
  27. typedef double src_t;
  28. typedef uint64_t src_rep_t;
  29. #define SRC_REP_C UINT64_C
  30. static const int srcBits = sizeof(src_t) * CHAR_BIT;
  31. static const int srcSigFracBits = 52;
  32. // -1 accounts for the sign bit.
  33. // srcBits - srcSigFracBits - 1
  34. static const int srcExpBits = 11;
  35. static inline int src_rep_t_clz_impl(src_rep_t a) { return __builtin_clzll(a); }
  36. #define src_rep_t_clz src_rep_t_clz_impl
  37. #elif defined SRC_80
  38. typedef xf_float src_t;
  39. typedef __uint128_t src_rep_t;
  40. #define SRC_REP_C (__uint128_t)
  41. // sign bit, exponent and significand occupy the lower 80 bits.
  42. static const int srcBits = 80;
  43. static const int srcSigFracBits = 63;
  44. // -1 accounts for the sign bit.
  45. // -1 accounts for the explicitly stored integer bit.
  46. // srcBits - srcSigFracBits - 1 - 1
  47. static const int srcExpBits = 15;
  48. #elif defined SRC_HALF
  49. #ifdef COMPILER_RT_HAS_FLOAT16
  50. typedef _Float16 src_t;
  51. #else
  52. typedef uint16_t src_t;
  53. #endif
  54. typedef uint16_t src_rep_t;
  55. #define SRC_REP_C UINT16_C
  56. static const int srcBits = sizeof(src_t) * CHAR_BIT;
  57. static const int srcSigFracBits = 10;
  58. // -1 accounts for the sign bit.
  59. // srcBits - srcSigFracBits - 1
  60. static const int srcExpBits = 5;
  61. static inline int src_rep_t_clz_impl(src_rep_t a) {
  62. return __builtin_clz(a) - 16;
  63. }
  64. #define src_rep_t_clz src_rep_t_clz_impl
  65. #elif defined SRC_BFLOAT16
  66. #ifdef COMPILER_RT_HAS_BFLOAT16
  67. typedef __bf16 src_t;
  68. #else
  69. typedef uint16_t src_t;
  70. #endif
  71. typedef uint16_t src_rep_t;
  72. #define SRC_REP_C UINT16_C
  73. static const int srcBits = sizeof(src_t) * CHAR_BIT;
  74. static const int srcSigFracBits = 7;
  75. // -1 accounts for the sign bit.
  76. // srcBits - srcSigFracBits - 1
  77. static const int srcExpBits = 8;
  78. #define src_rep_t_clz __builtin_clz
  79. #else
  80. #error Source should be half, single, or double precision!
  81. #endif // end source precision
  82. #if defined DST_SINGLE
  83. typedef float dst_t;
  84. typedef uint32_t dst_rep_t;
  85. #define DST_REP_C UINT32_C
  86. static const int dstBits = sizeof(dst_t) * CHAR_BIT;
  87. static const int dstSigFracBits = 23;
  88. // -1 accounts for the sign bit.
  89. // dstBits - dstSigFracBits - 1
  90. static const int dstExpBits = 8;
  91. #elif defined DST_DOUBLE
  92. typedef double dst_t;
  93. typedef uint64_t dst_rep_t;
  94. #define DST_REP_C UINT64_C
  95. static const int dstBits = sizeof(dst_t) * CHAR_BIT;
  96. static const int dstSigFracBits = 52;
  97. // -1 accounts for the sign bit.
  98. // dstBits - dstSigFracBits - 1
  99. static const int dstExpBits = 11;
  100. #elif defined DST_QUAD
  101. typedef tf_float dst_t;
  102. typedef __uint128_t dst_rep_t;
  103. #define DST_REP_C (__uint128_t)
  104. static const int dstBits = sizeof(dst_t) * CHAR_BIT;
  105. static const int dstSigFracBits = 112;
  106. // -1 accounts for the sign bit.
  107. // dstBits - dstSigFracBits - 1
  108. static const int dstExpBits = 15;
  109. #else
  110. #error Destination should be single, double, or quad precision!
  111. #endif // end destination precision
  112. // End of specialization parameters.
  113. // TODO: These helper routines should be placed into fp_lib.h
  114. // Currently they depend on macros/constants defined above.
  115. static inline src_rep_t extract_sign_from_src(src_rep_t x) {
  116. const src_rep_t srcSignMask = SRC_REP_C(1) << (srcBits - 1);
  117. return (x & srcSignMask) >> (srcBits - 1);
  118. }
  119. static inline src_rep_t extract_exp_from_src(src_rep_t x) {
  120. const int srcSigBits = srcBits - 1 - srcExpBits;
  121. const src_rep_t srcExpMask = ((SRC_REP_C(1) << srcExpBits) - 1) << srcSigBits;
  122. return (x & srcExpMask) >> srcSigBits;
  123. }
  124. static inline src_rep_t extract_sig_frac_from_src(src_rep_t x) {
  125. const src_rep_t srcSigFracMask = (SRC_REP_C(1) << srcSigFracBits) - 1;
  126. return x & srcSigFracMask;
  127. }
  128. #ifdef src_rep_t_clz
  129. static inline int clz_in_sig_frac(src_rep_t sigFrac) {
  130. const int skip = 1 + srcExpBits;
  131. return src_rep_t_clz(sigFrac) - skip;
  132. }
  133. #endif
  134. static inline dst_rep_t construct_dst_rep(dst_rep_t sign, dst_rep_t exp, dst_rep_t sigFrac) {
  135. return (sign << (dstBits - 1)) | (exp << (dstBits - 1 - dstExpBits)) | sigFrac;
  136. }
  137. // Two helper routines for conversion to and from the representation of
  138. // floating-point data as integer values follow.
  139. static inline src_rep_t srcToRep(src_t x) {
  140. const union {
  141. src_t f;
  142. src_rep_t i;
  143. } rep = {.f = x};
  144. return rep.i;
  145. }
  146. static inline dst_t dstFromRep(dst_rep_t x) {
  147. const union {
  148. dst_t f;
  149. dst_rep_t i;
  150. } rep = {.i = x};
  151. return rep.f;
  152. }
  153. // End helper routines. Conversion implementation follows.
  154. #endif // FP_EXTEND_HEADER