1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #if !defined(fltconst_h) 19 #define fltconst_h 20 21 #include "hycomp.h" 22 23 /* IEEE floats consist of: sign bit, exponent field, significand field 24 single: 31 = sign bit, 30..23 = exponent (8 bits), 22..0 = significand (23 bits) 25 double: 63 = sign bit, 62..52 = exponent (11 bits), 51..0 = significand (52 bits) 26 inf == (all exponent bits set) and (all mantissa bits clear) 27 nan == (all exponent bits set) and (at least one mantissa bit set) 28 finite == (at least one exponent bit clear) 29 zero == (all exponent bits clear) and (all mantissa bits clear) 30 denormal == (all exponent bits clear) and (at least one mantissa bit set) 31 positive == sign bit clear 32 negative == sign bit set 33 */ 34 #define MAX_U32_DOUBLE (ESDOUBLE) (4294967296.0) /* 2^32 */ 35 #define MAX_U32_SINGLE (ESSINGLE) (4294967296.0) /* 2^32 */ 36 #define HY_POS_PI (ESDOUBLE) (3.141592653589793) 37 38 #ifdef HY_LITTLE_ENDIAN 39 #ifdef HY_PLATFORM_DOUBLE_ORDER 40 #define DOUBLE_LO_OFFSET 0 41 #define DOUBLE_HI_OFFSET 1 42 #else 43 #define DOUBLE_LO_OFFSET 1 44 #define DOUBLE_HI_OFFSET 0 45 #endif 46 #define LONG_LO_OFFSET 0 47 #define LONG_HI_OFFSET 1 48 #else 49 #ifdef HY_PLATFORM_DOUBLE_ORDER 50 #define DOUBLE_LO_OFFSET 1 51 #define DOUBLE_HI_OFFSET 0 52 #else 53 #define DOUBLE_LO_OFFSET 0 54 #define DOUBLE_HI_OFFSET 1 55 #endif 56 #define LONG_LO_OFFSET 1 57 #define LONG_HI_OFFSET 0 58 #endif 59 60 #define RETURN_FINITE 0 61 #define RETURN_NAN 1 62 #define RETURN_POS_INF 2 63 #define RETURN_NEG_INF 3 64 #define DOUBLE_SIGN_MASK_HI 0x80000000 65 #define DOUBLE_EXPONENT_MASK_HI 0x7FF00000 66 #define DOUBLE_MANTISSA_MASK_LO 0xFFFFFFFF 67 #define DOUBLE_MANTISSA_MASK_HI 0x000FFFFF 68 #define SINGLE_SIGN_MASK 0x80000000 69 #define SINGLE_EXPONENT_MASK 0x7F800000 70 #define SINGLE_MANTISSA_MASK 0x007FFFFF 71 #define SINGLE_NAN_BITS (SINGLE_EXPONENT_MASK | 0x00400000) 72 73 typedef union u64u32dbl_tag { 74 U_64 u64val; 75 U_32 u32val[2]; 76 I_32 i32val[2]; 77 double dval; 78 } U64U32DBL; 79 80 /* Replace P_FLOAT_HI and P_FLOAT_LOW */ 81 /* These macros are used to access the high and low 32-bit parts of a double (64-bit) value. */ 82 #define LOW_U32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->u32val[DOUBLE_LO_OFFSET]) 83 #define HIGH_U32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->u32val[DOUBLE_HI_OFFSET]) 84 #define LOW_I32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->i32val[DOUBLE_LO_OFFSET]) 85 #define HIGH_I32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->i32val[DOUBLE_HI_OFFSET]) 86 #define LOW_U32_FROM_DBL(dbl) LOW_U32_FROM_DBL_PTR(&(dbl)) 87 #define HIGH_U32_FROM_DBL(dbl) HIGH_U32_FROM_DBL_PTR(&(dbl)) 88 #define LOW_I32_FROM_DBL(dbl) LOW_I32_FROM_DBL_PTR(&(dbl)) 89 #define HIGH_I32_FROM_DBL(dbl) HIGH_I32_FROM_DBL_PTR(&(dbl)) 90 #define LOW_U32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->u32val[LONG_LO_OFFSET]) 91 #define HIGH_U32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->u32val[LONG_HI_OFFSET]) 92 #define LOW_I32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->i32val[LONG_LO_OFFSET]) 93 #define HIGH_I32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->i32val[LONG_HI_OFFSET]) 94 #define LOW_U32_FROM_LONG64(long64) LOW_U32_FROM_LONG64_PTR(&(long64)) 95 #define HIGH_U32_FROM_LONG64(long64) HIGH_U32_FROM_LONG64_PTR(&(long64)) 96 #define LOW_I32_FROM_LONG64(long64) LOW_I32_FROM_LONG64_PTR(&(long64)) 97 #define HIGH_I32_FROM_LONG64(long64) HIGH_I32_FROM_LONG64_PTR(&(long64)) 98 #define IS_ZERO_DBL_PTR(dblptr) ((LOW_U32_FROM_DBL_PTR(dblptr) == 0) && ((HIGH_U32_FROM_DBL_PTR(dblptr) == 0) || (HIGH_U32_FROM_DBL_PTR(dblptr) == DOUBLE_SIGN_MASK_HI))) 99 #define IS_ONE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) == 0x3ff00000 || HIGH_U32_FROM_DBL_PTR(dblptr) == 0xbff00000) && (LOW_U32_FROM_DBL_PTR(dblptr) == 0)) 100 #define IS_NAN_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) == DOUBLE_EXPONENT_MASK_HI) && (LOW_U32_FROM_DBL_PTR(dblptr) | (HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_MANTISSA_MASK_HI))) 101 #define IS_INF_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & (DOUBLE_EXPONENT_MASK_HI|DOUBLE_MANTISSA_MASK_HI)) == DOUBLE_EXPONENT_MASK_HI) && (LOW_U32_FROM_DBL_PTR(dblptr) == 0)) 102 #define IS_DENORMAL_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) == 0) && ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_MANTISSA_MASK_HI) != 0 || (LOW_U32_FROM_DBL_PTR(dblptr) != 0))) 103 #define IS_FINITE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) < DOUBLE_EXPONENT_MASK_HI) 104 #define IS_POSITIVE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_SIGN_MASK_HI) == 0) 105 #define IS_NEGATIVE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_SIGN_MASK_HI) != 0) 106 #define IS_NEGATIVE_MAX_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) == 0xFFEFFFFF) && (LOW_U32_FROM_DBL_PTR(dblptr) == 0xFFFFFFFF)) 107 #define IS_ZERO_DBL(dbl) IS_ZERO_DBL_PTR(&(dbl)) 108 #define IS_ONE_DBL(dbl) IS_ONE_DBL_PTR(&(dbl)) 109 #define IS_NAN_DBL(dbl) IS_NAN_DBL_PTR(&(dbl)) 110 #define IS_INF_DBL(dbl) IS_INF_DBL_PTR(&(dbl)) 111 #define IS_DENORMAL_DBL(dbl) IS_DENORMAL_DBL_PTR(&(dbl)) 112 #define IS_FINITE_DBL(dbl) IS_FINITE_DBL_PTR(&(dbl)) 113 #define IS_POSITIVE_DBL(dbl) IS_POSITIVE_DBL_PTR(&(dbl)) 114 #define IS_NEGATIVE_DBL(dbl) IS_NEGATIVE_DBL_PTR(&(dbl)) 115 #define IS_NEGATIVE_MAX_DBL(dbl) IS_NEGATIVE_MAX_DBL_PTR(&(dbl)) 116 #define IS_ZERO_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) == (U_32)0) 117 #define IS_ONE_SNGL_PTR(fltptr) ((*U32P((fltptr)) == 0x3f800000) || (*U32P((fltptr)) == 0xbf800000)) 118 #define IS_NAN_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) > (U_32)SINGLE_EXPONENT_MASK) 119 #define IS_INF_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) == (U_32)SINGLE_EXPONENT_MASK) 120 #define IS_DENORMAL_SNGL_PTR(fltptr) (((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK)-(U_32)1) < (U_32)SINGLE_MANTISSA_MASK) 121 #define IS_FINITE_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) < (U_32)SINGLE_EXPONENT_MASK) 122 #define IS_POSITIVE_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)SINGLE_SIGN_MASK) == (U_32)0) 123 #define IS_NEGATIVE_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)SINGLE_SIGN_MASK) != (U_32)0) 124 #define IS_ZERO_SNGL(flt) IS_ZERO_SNGL_PTR(&(flt)) 125 #define IS_ONE_SNGL(flt) IS_ONE_SNGL_PTR(&(flt)) 126 #define IS_NAN_SNGL(flt) IS_NAN_SNGL_PTR(&(flt)) 127 #define IS_INF_SNGL(flt) IS_INF_SNGL_PTR(&(flt)) 128 #define IS_DENORMAL_SNGL(flt) IS_DENORMAL_SNGL_PTR(&(flt)) 129 #define IS_FINITE_SNGL(flt) IS_FINITE_SNGL_PTR(&(flt)) 130 #define IS_POSITIVE_SNGL(flt) IS_POSITIVE_SNGL_PTR(&(flt)) 131 #define IS_NEGATIVE_SNGL(flt) IS_NEGATIVE_SNGL_PTR(&(flt)) 132 #define SET_NAN_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = (DOUBLE_EXPONENT_MASK_HI | 0x00080000); LOW_U32_FROM_DBL_PTR(dblptr) = 0 133 #define SET_PZERO_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = 0; LOW_U32_FROM_DBL_PTR(dblptr) = 0 134 #define SET_NZERO_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = DOUBLE_SIGN_MASK_HI; LOW_U32_FROM_DBL_PTR(dblptr) = 0 135 #define SET_PINF_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = DOUBLE_EXPONENT_MASK_HI; LOW_U32_FROM_DBL_PTR(dblptr) = 0 136 #define SET_NINF_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = (DOUBLE_EXPONENT_MASK_HI | DOUBLE_SIGN_MASK_HI); LOW_U32_FROM_DBL_PTR(dblptr) = 0 137 #define SET_NAN_SNGL_PTR(fltptr) *U32P((fltptr)) = ((U_32)SINGLE_NAN_BITS) 138 #define SET_PZERO_SNGL_PTR(fltptr) *U32P((fltptr)) = 0 139 #define SET_NZERO_SNGL_PTR(fltptr) *U32P((fltptr)) = SINGLE_SIGN_MASK 140 #define SET_PINF_SNGL_PTR(fltptr) *U32P((fltptr)) = SINGLE_EXPONENT_MASK 141 #define SET_NINF_SNGL_PTR(fltptr) *U32P((fltptr)) = (SINGLE_EXPONENT_MASK | SINGLE_SIGN_MASK) 142 143 #if defined(HY_WORD64) 144 #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) ((U64U32DBL *)(aDoublePtr))->u64val = ((U64U32DBL *)(dstPtr))->u64val 145 #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) ((U64U32DBL *)(dstPtr))->u64val = ((U64U32DBL *)(aDoublePtr))->u64val 146 #define STORE_LONG(dstPtr, hi, lo) ((U64U32DBL *)(dstPtr))->u64val = (((U_64)(hi)) << 32) | (lo) 147 #else 148 /* on some platforms (HP720) we cannot reference an unaligned float. Build them by hand, one U_32 at a time. */ 149 #if defined(ATOMIC_FLOAT_ACCESS) 150 #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(dstPtr) = HIGH_U32_FROM_DBL_PTR(aDoublePtr); LOW_U32_FROM_DBL_PTR(dstPtr) = LOW_U32_FROM_DBL_PTR(aDoublePtr) 151 #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(aDoublePtr) = HIGH_U32_FROM_DBL_PTR(dstPtr); LOW_U32_FROM_DBL_PTR(aDoublePtr) = LOW_U32_FROM_DBL_PTR(dstPtr) 152 #else 153 #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) (*(dstPtr) = *(aDoublePtr)) 154 #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) (*(aDoublePtr) = *(dstPtr)) 155 #endif 156 157 #define STORE_LONG(dstPtr, hi, lo) HIGH_U32_FROM_LONG64_PTR(dstPtr) = (hi); LOW_U32_FROM_LONG64_PTR(dstPtr) = (lo) 158 #endif /* HY_WORD64 */ 159 160 #define PTR_SINGLE_VALUE(dstPtr, aSinglePtr) (*U32P(aSinglePtr) = *U32P(dstPtr)) 161 #define PTR_SINGLE_STORE(dstPtr, aSinglePtr) *((U_32 *)(dstPtr)) = (*U32P(aSinglePtr)) 162 163 #endif /* fltconst_h */ 164