Home | History | Annotate | Download | only in native
      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