1*0b57cec5SDimitry Andric //===-lib/fp_extend.h - low precision -> high precision conversion -*- C 2*0b57cec5SDimitry Andric //-*-===// 3*0b57cec5SDimitry Andric // 4*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric // 8*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric // 10*0b57cec5SDimitry Andric // Set source and destination setting 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #ifndef FP_EXTEND_HEADER 15*0b57cec5SDimitry Andric #define FP_EXTEND_HEADER 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric #include "int_lib.h" 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric #if defined SRC_SINGLE 20*0b57cec5SDimitry Andric typedef float src_t; 21*0b57cec5SDimitry Andric typedef uint32_t src_rep_t; 22*0b57cec5SDimitry Andric #define SRC_REP_C UINT32_C 23*0b57cec5SDimitry Andric static const int srcSigBits = 23; 24*0b57cec5SDimitry Andric #define src_rep_t_clz __builtin_clz 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric #elif defined SRC_DOUBLE 27*0b57cec5SDimitry Andric typedef double src_t; 28*0b57cec5SDimitry Andric typedef uint64_t src_rep_t; 29*0b57cec5SDimitry Andric #define SRC_REP_C UINT64_C 30*0b57cec5SDimitry Andric static const int srcSigBits = 52; 31*0b57cec5SDimitry Andric static __inline int src_rep_t_clz(src_rep_t a) { 32*0b57cec5SDimitry Andric #if defined __LP64__ 33*0b57cec5SDimitry Andric return __builtin_clzl(a); 34*0b57cec5SDimitry Andric #else 35*0b57cec5SDimitry Andric if (a & REP_C(0xffffffff00000000)) 36*0b57cec5SDimitry Andric return __builtin_clz(a >> 32); 37*0b57cec5SDimitry Andric else 38*0b57cec5SDimitry Andric return 32 + __builtin_clz(a & REP_C(0xffffffff)); 39*0b57cec5SDimitry Andric #endif 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric #elif defined SRC_HALF 43*0b57cec5SDimitry Andric typedef uint16_t src_t; 44*0b57cec5SDimitry Andric typedef uint16_t src_rep_t; 45*0b57cec5SDimitry Andric #define SRC_REP_C UINT16_C 46*0b57cec5SDimitry Andric static const int srcSigBits = 10; 47*0b57cec5SDimitry Andric #define src_rep_t_clz __builtin_clz 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric #else 50*0b57cec5SDimitry Andric #error Source should be half, single, or double precision! 51*0b57cec5SDimitry Andric #endif // end source precision 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric #if defined DST_SINGLE 54*0b57cec5SDimitry Andric typedef float dst_t; 55*0b57cec5SDimitry Andric typedef uint32_t dst_rep_t; 56*0b57cec5SDimitry Andric #define DST_REP_C UINT32_C 57*0b57cec5SDimitry Andric static const int dstSigBits = 23; 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric #elif defined DST_DOUBLE 60*0b57cec5SDimitry Andric typedef double dst_t; 61*0b57cec5SDimitry Andric typedef uint64_t dst_rep_t; 62*0b57cec5SDimitry Andric #define DST_REP_C UINT64_C 63*0b57cec5SDimitry Andric static const int dstSigBits = 52; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric #elif defined DST_QUAD 66*0b57cec5SDimitry Andric typedef long double dst_t; 67*0b57cec5SDimitry Andric typedef __uint128_t dst_rep_t; 68*0b57cec5SDimitry Andric #define DST_REP_C (__uint128_t) 69*0b57cec5SDimitry Andric static const int dstSigBits = 112; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric #else 72*0b57cec5SDimitry Andric #error Destination should be single, double, or quad precision! 73*0b57cec5SDimitry Andric #endif // end destination precision 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric // End of specialization parameters. Two helper routines for conversion to and 76*0b57cec5SDimitry Andric // from the representation of floating-point data as integer values follow. 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric static __inline src_rep_t srcToRep(src_t x) { 79*0b57cec5SDimitry Andric const union { 80*0b57cec5SDimitry Andric src_t f; 81*0b57cec5SDimitry Andric src_rep_t i; 82*0b57cec5SDimitry Andric } rep = {.f = x}; 83*0b57cec5SDimitry Andric return rep.i; 84*0b57cec5SDimitry Andric } 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric static __inline dst_t dstFromRep(dst_rep_t x) { 87*0b57cec5SDimitry Andric const union { 88*0b57cec5SDimitry Andric dst_t f; 89*0b57cec5SDimitry Andric dst_rep_t i; 90*0b57cec5SDimitry Andric } rep = {.i = x}; 91*0b57cec5SDimitry Andric return rep.f; 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric // End helper routines. Conversion implementation follows. 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric #endif // FP_EXTEND_HEADER 96