bitcasts.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #pragma once
  2. #ifndef FP16_BITCASTS_H
  3. #define FP16_BITCASTS_H
  4. #if defined(__cplusplus) && (__cplusplus >= 201103L)
  5. #include <cstdint>
  6. #elif !defined(__OPENCL_VERSION__)
  7. #include <stdint.h>
  8. #endif
  9. #if defined(__INTEL_COMPILER)
  10. #include <immintrin.h>
  11. #endif
  12. #if defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
  13. #include <intrin.h>
  14. #endif
  15. static inline float fp32_from_bits(uint32_t w) {
  16. #if defined(__OPENCL_VERSION__)
  17. return as_float(w);
  18. #elif defined(__CUDA_ARCH__)
  19. return __uint_as_float((unsigned int) w);
  20. #elif defined(__INTEL_COMPILER)
  21. return _castu32_f32(w);
  22. #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
  23. return _CopyFloatFromInt32((__int32) w);
  24. #else
  25. union {
  26. uint32_t as_bits;
  27. float as_value;
  28. } fp32 = { w };
  29. return fp32.as_value;
  30. #endif
  31. }
  32. static inline uint32_t fp32_to_bits(float f) {
  33. #if defined(__OPENCL_VERSION__)
  34. return as_uint(f);
  35. #elif defined(__CUDA_ARCH__)
  36. return (uint32_t) __float_as_uint(f);
  37. #elif defined(__INTEL_COMPILER)
  38. return _castf32_u32(f);
  39. #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
  40. return (uint32_t) _CopyInt32FromFloat(f);
  41. #else
  42. union {
  43. float as_value;
  44. uint32_t as_bits;
  45. } fp32 = { f };
  46. return fp32.as_bits;
  47. #endif
  48. }
  49. static inline double fp64_from_bits(uint64_t w) {
  50. #if defined(__OPENCL_VERSION__)
  51. return as_double(w);
  52. #elif defined(__CUDA_ARCH__)
  53. return __longlong_as_double((long long) w);
  54. #elif defined(__INTEL_COMPILER)
  55. return _castu64_f64(w);
  56. #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
  57. return _CopyDoubleFromInt64((__int64) w);
  58. #else
  59. union {
  60. uint64_t as_bits;
  61. double as_value;
  62. } fp64 = { w };
  63. return fp64.as_value;
  64. #endif
  65. }
  66. static inline uint64_t fp64_to_bits(double f) {
  67. #if defined(__OPENCL_VERSION__)
  68. return as_ulong(f);
  69. #elif defined(__CUDA_ARCH__)
  70. return (uint64_t) __double_as_longlong(f);
  71. #elif defined(__INTEL_COMPILER)
  72. return _castf64_u64(f);
  73. #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
  74. return (uint64_t) _CopyInt64FromDouble(f);
  75. #else
  76. union {
  77. double as_value;
  78. uint64_t as_bits;
  79. } fp64 = { f };
  80. return fp64.as_bits;
  81. #endif
  82. }
  83. #endif /* FP16_BITCASTS_H */