1 #define _FP_W_TYPE_SIZE 64 2 3 #define _FP_W_TYPE unsigned long long 4 #define _FP_WS_TYPE signed long long 5 #define _FP_I_TYPE long long 6 7 typedef int TItype __attribute__ ((mode (TI))); 8 typedef unsigned int UTItype __attribute__ ((mode (TI))); 9 10 #define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype)) 11 12 /* The type of the result of a floating point comparison. This must 13 match `__libgcc_cmp_return__' in GCC for the target. */ 14 typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); 15 #define CMPtype __gcc_CMPtype 16 17 #define _FP_MUL_MEAT_Q(R,X,Y) \ 18 _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) 19 20 #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) 21 22 #define _FP_NANFRAC_S _FP_QNANBIT_S 23 #define _FP_NANFRAC_D _FP_QNANBIT_D 24 #define _FP_NANFRAC_E _FP_QNANBIT_E, 0 25 #define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 26 #define _FP_NANSIGN_S 1 27 #define _FP_NANSIGN_D 1 28 #define _FP_NANSIGN_E 1 29 #define _FP_NANSIGN_Q 1 30 31 #define _FP_KEEPNANFRACP 1 32 33 /* Here is something Intel misdesigned: the specs don't define 34 the case where we have two NaNs with same mantissas, but 35 different sign. Different operations pick up different NaNs. */ 36 #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ 37 do { \ 38 if (_FP_FRAC_GT_##wc(X, Y) \ 39 || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \ 40 { \ 41 R##_s = X##_s; \ 42 _FP_FRAC_COPY_##wc(R,X); \ 43 } \ 44 else \ 45 { \ 46 R##_s = Y##_s; \ 47 _FP_FRAC_COPY_##wc(R,Y); \ 48 } \ 49 R##_c = FP_CLS_NAN; \ 50 } while (0) 51 52 #ifndef _SOFT_FLOAT 53 #define FP_EX_INVALID 0x01 54 #define FP_EX_DENORM 0x02 55 #define FP_EX_DIVZERO 0x04 56 #define FP_EX_OVERFLOW 0x08 57 #define FP_EX_UNDERFLOW 0x10 58 #define FP_EX_INEXACT 0x20 59 60 struct fenv 61 { 62 unsigned short int __control_word; 63 unsigned short int __unused1; 64 unsigned short int __status_word; 65 unsigned short int __unused2; 66 unsigned short int __tags; 67 unsigned short int __unused3; 68 unsigned int __eip; 69 unsigned short int __cs_selector; 70 unsigned int __opcode:11; 71 unsigned int __unused4:5; 72 unsigned int __data_offset; 73 unsigned short int __data_selector; 74 unsigned short int __unused5; 75 }; 76 77 #ifdef __AVX__ 78 #define ASM_INVALID "vdivss %0, %0, %0" 79 #define ASM_DIVZERO "vdivss %1, %0, %0" 80 #else 81 #define ASM_INVALID "divss %0, %0" 82 #define ASM_DIVZERO "divss %1, %0" 83 #endif 84 85 #define FP_HANDLE_EXCEPTIONS \ 86 do { \ 87 if (_fex & FP_EX_INVALID) \ 88 { \ 89 float f = 0.0; \ 90 __asm__ __volatile__ (ASM_INVALID : : "x" (f)); \ 91 } \ 92 if (_fex & FP_EX_DIVZERO) \ 93 { \ 94 float f = 1.0, g = 0.0; \ 95 __asm__ __volatile__ (ASM_DIVZERO : : "x" (f), "x" (g)); \ 96 } \ 97 if (_fex & FP_EX_OVERFLOW) \ 98 { \ 99 struct fenv temp; \ 100 __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \ 101 temp.__status_word |= FP_EX_OVERFLOW; \ 102 __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \ 103 __asm__ __volatile__ ("fwait"); \ 104 } \ 105 if (_fex & FP_EX_UNDERFLOW) \ 106 { \ 107 struct fenv temp; \ 108 __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \ 109 temp.__status_word |= FP_EX_UNDERFLOW; \ 110 __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \ 111 __asm__ __volatile__ ("fwait"); \ 112 } \ 113 if (_fex & FP_EX_INEXACT) \ 114 { \ 115 struct fenv temp; \ 116 __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \ 117 temp.__status_word |= FP_EX_INEXACT; \ 118 __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \ 119 __asm__ __volatile__ ("fwait"); \ 120 } \ 121 } while (0) 122 123 #define FP_RND_NEAREST 0 124 #define FP_RND_ZERO 0xc00 125 #define FP_RND_PINF 0x800 126 #define FP_RND_MINF 0x400 127 128 #define _FP_DECL_EX \ 129 unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST 130 131 #define FP_INIT_ROUNDMODE \ 132 do { \ 133 __asm__ ("fnstcw %0" : "=m" (_fcw)); \ 134 } while (0) 135 136 #define FP_ROUNDMODE (_fcw & 0xc00) 137 #endif 138 139 #define __LITTLE_ENDIAN 1234 140 #define __BIG_ENDIAN 4321 141 142 #define __BYTE_ORDER __LITTLE_ENDIAN 143 144 /* Define ALIASNAME as a strong alias for NAME. */ 145 #if defined __MACH__ 146 /* Mach-O doesn't support aliasing. If these functions ever return 147 anything but CMPtype we need to revisit this... */ 148 #define strong_alias(name, aliasname) \ 149 CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); } 150 #else 151 # define strong_alias(name, aliasname) _strong_alias(name, aliasname) 152 # define _strong_alias(name, aliasname) \ 153 extern __typeof (name) aliasname __attribute__ ((alias (#name))); 154 #endif 155