1 /* $OpenBSD: cnv_float.h,v 1.9 2003/04/10 17:27:58 mickey Exp $ */ 2 /* 3 (c) Copyright 1986 HEWLETT-PACKARD COMPANY 4 To anyone who acknowledges that this file is provided "AS IS" 5 without any express or implied warranty: 6 permission to use, copy, modify, and distribute this file 7 for any purpose is hereby granted without fee, provided that 8 the above copyright notice and this notice appears in all 9 copies, and that the name of Hewlett-Packard Company not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific, written prior permission. 12 Hewlett-Packard Company makes no representations about the 13 suitability of this software for any purpose. 14 */ 15 /* @(#)cnv_float.h: Revision: 2.9.88.1 Date: 93/12/07 15:05:29 */ 16 17 /* 18 * Some more constants 19 */ 20 #define SGL_FX_MAX_EXP 30 21 #define DBL_FX_MAX_EXP 62 22 #define QUAD_FX_MAX_EXP 126 23 24 25 #define Dintp1(object) (object) 26 #define Dintp2(object) (object) 27 28 #define Qintp0(object) (object) 29 #define Qintp1(object) (object) 30 #define Qintp2(object) (object) 31 #define Qintp3(object) (object) 32 33 34 /* 35 * These macros will be used specifically by the convert instructions. 36 * 37 * 38 * Single format macros 39 */ 40 41 #define Sgl_to_dbl_exponent(src_exponent,dest) \ 42 Deposit_dexponent(dest,src_exponent+(DBL_BIAS-SGL_BIAS)) 43 44 #define Sgl_to_dbl_mantissa(src_mantissa,destA,destB) \ 45 Deposit_dmantissap1(destA,src_mantissa>>3); \ 46 Dmantissap2(destB) = src_mantissa << 29 47 48 #define Sgl_isinexact_to_fix(sgl_value,exponent) \ 49 ((exponent < (SGL_P - 1)) ? \ 50 (Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE) 51 52 #define Int_isinexact_to_sgl(int_value) (int_value << (33 - SGL_EXP_LENGTH)) 53 54 #define Sgl_roundnearest_from_int(int_value,sgl_value) \ 55 if (int_value & 1<<(SGL_EXP_LENGTH - 2)) /* round bit */ \ 56 if ((int_value << (34 - SGL_EXP_LENGTH)) || Slow(sgl_value)) \ 57 Sall(sgl_value)++ 58 59 #define Dint_isinexact_to_sgl(dint_valueA,dint_valueB) \ 60 ((Dintp1(dint_valueA) << (33 - SGL_EXP_LENGTH)) || Dintp2(dint_valueB)) 61 62 #define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value) \ 63 if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2)) \ 64 if ((Dintp1(dint_valueA) << (34 - SGL_EXP_LENGTH)) || \ 65 Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++ 66 67 #define Dint_isinexact_to_dbl(dint_value) \ 68 (Dintp2(dint_value) << (33 - DBL_EXP_LENGTH)) 69 70 #define Dbl_roundnearest_from_dint(dint_opndB,dbl_opndA,dbl_opndB) \ 71 if (Dintp2(dint_opndB) & 1<<(DBL_EXP_LENGTH - 2)) \ 72 if ((Dintp2(dint_opndB) << (34 - DBL_EXP_LENGTH)) || Dlowp2(dbl_opndB)) \ 73 if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++ 74 75 #define Sgl_isone_roundbit(sgl_value,exponent) \ 76 ((Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) >> 31) 77 78 #define Sgl_isone_stickybit(sgl_value,exponent) \ 79 (exponent < (SGL_P - 2) ? \ 80 Sall(sgl_value) << (SGL_EXP_LENGTH + 2 + exponent) : FALSE) 81 82 83 /* 84 * Double format macros 85 */ 86 87 #define Dbl_to_sgl_exponent(src_exponent,dest) \ 88 dest = src_exponent + (SGL_BIAS - DBL_BIAS) 89 90 #define Dbl_to_sgl_mantissa(srcA,srcB,dest,inexact,guard,sticky,odd) \ 91 Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest); \ 92 guard = Dbit3p2(srcB); \ 93 sticky = Dallp2(srcB)<<4; \ 94 inexact = guard | sticky; \ 95 odd = Dbit2p2(srcB) 96 97 #define Dbl_to_sgl_denormalized(srcA,srcB,exp,dest,inexact,guard,sticky,odd,tiny) \ 98 Deposit_dexponent(srcA,1); \ 99 tiny = TRUE; \ 100 if (exp >= -2) { \ 101 if (exp == 0) { \ 102 inexact = Dallp2(srcB) << 3; \ 103 guard = inexact >> 31; \ 104 sticky = inexact << 1; \ 105 Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest); \ 106 odd = dest << 31; \ 107 if (inexact) { \ 108 switch(Rounding_mode()) { \ 109 case ROUNDPLUS: \ 110 if (Dbl_iszero_sign(srcA)) { \ 111 dest++; \ 112 if (Sgl_isone_hidden(dest)) \ 113 tiny = FALSE; \ 114 dest--; \ 115 } \ 116 break; \ 117 case ROUNDMINUS: \ 118 if (Dbl_isone_sign(srcA)) { \ 119 dest++; \ 120 if (Sgl_isone_hidden(dest)) \ 121 tiny = FALSE; \ 122 dest--; \ 123 } \ 124 break; \ 125 case ROUNDNEAREST: \ 126 if (guard && (sticky || odd)) { \ 127 dest++; \ 128 if (Sgl_isone_hidden(dest)) \ 129 tiny = FALSE; \ 130 dest--; \ 131 } \ 132 break; \ 133 } \ 134 } \ 135 /* shift right by one to get correct result */ \ 136 guard = odd; \ 137 sticky = inexact; \ 138 inexact |= guard; \ 139 dest >>= 1; \ 140 Deposit_dsign(srcA,0); \ 141 Shiftdouble(Dallp1(srcA),Dallp2(srcB),30,dest); \ 142 odd = dest << 31; \ 143 } \ 144 else { \ 145 inexact = Dallp2(srcB) << (2 + exp); \ 146 guard = inexact >> 31; \ 147 sticky = inexact << 1; \ 148 Deposit_dsign(srcA,0); \ 149 if (exp == -2) dest = Dallp1(srcA); \ 150 else Variable_shift_double(Dallp1(srcA),Dallp2(srcB),30-exp,dest); \ 151 odd = dest << 31; \ 152 } \ 153 } \ 154 else { \ 155 Deposit_dsign(srcA,0); \ 156 if (exp > (1 - SGL_P)) { \ 157 dest = Dallp1(srcA) >> (- 2 - exp); \ 158 inexact = Dallp1(srcA) << (34 + exp); \ 159 guard = inexact >> 31; \ 160 sticky = (inexact << 1) | Dallp2(srcB); \ 161 inexact |= Dallp2(srcB); \ 162 odd = dest << 31; \ 163 } \ 164 else { \ 165 dest = 0; \ 166 inexact = Dallp1(srcA) | Dallp2(srcB); \ 167 if (exp == (1 - SGL_P)) { \ 168 guard = Dhidden(srcA); \ 169 sticky = Dmantissap1(srcA) | Dallp2(srcB); \ 170 } \ 171 else { \ 172 guard = 0; \ 173 sticky = inexact; \ 174 } \ 175 odd = 0; \ 176 } \ 177 } \ 178 exp = 0 179 180 #define Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent) \ 181 (exponent < (DBL_P-33) ? \ 182 Dallp2(dbl_valueB) || Dallp1(dbl_valueA) << (DBL_EXP_LENGTH+1+exponent) : \ 183 (exponent < (DBL_P-1) ? Dallp2(dbl_valueB) << (exponent + (33-DBL_P)) : \ 184 FALSE)) 185 186 #define Dbl_isoverflow_to_int(exponent,dbl_valueA,dbl_valueB) \ 187 ((exponent > SGL_FX_MAX_EXP + 1) || Dsign(dbl_valueA)==0 || \ 188 Dmantissap1(dbl_valueA)!=0 || (Dallp2(dbl_valueB)>>21)!=0 ) 189 190 #define Dbl_isone_roundbit(dbl_valueA,dbl_valueB,exponent) \ 191 ((exponent < (DBL_P - 33) ? \ 192 Dallp1(dbl_valueA) >> ((30 - DBL_EXP_LENGTH) - exponent) : \ 193 Dallp2(dbl_valueB) >> ((DBL_P - 2) - exponent)) & 1) 194 195 #define Dbl_isone_stickybit(dbl_valueA,dbl_valueB,exponent) \ 196 (exponent < (DBL_P-34) ? \ 197 (Dallp2(dbl_valueB) || Dallp1(dbl_valueA)<<(DBL_EXP_LENGTH+2+exponent)) : \ 198 (exponent<(DBL_P-2) ? (Dallp2(dbl_valueB) << (exponent + (34-DBL_P))) : \ 199 FALSE)) 200 201 202 /* Int macros */ 203 204 #define Int_from_sgl_mantissa(sgl_value,exponent) \ 205 Sall(sgl_value) = \ 206 (unsigned)(Sall(sgl_value) << SGL_EXP_LENGTH)>>(31 - exponent) 207 208 #define Int_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent) \ 209 Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),22,Dallp1(dbl_valueA)); \ 210 if (exponent < 31) Dallp1(dbl_valueA) >>= 30 - exponent; \ 211 else Dallp1(dbl_valueA) <<= 1 212 213 #define Int_negate(int_value) int_value = -int_value 214 215 216 /* Dint macros */ 217 218 #define Dint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \ 219 {Sall(sgl_value) <<= SGL_EXP_LENGTH; /* left-justify */ \ 220 if (exponent <= 31) { \ 221 Dintp1(dresultA) = 0; \ 222 Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \ 223 } \ 224 else { \ 225 Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent); \ 226 Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31); \ 227 }} 228 229 230 #define Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \ 231 {if (exponent < 32) { \ 232 Dintp1(destA) = 0; \ 233 if (exponent <= 20) \ 234 Dintp2(destB) = Dallp1(dbl_valueA) >> (20-exponent); \ 235 else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \ 236 52-exponent,Dintp2(destB)); \ 237 } \ 238 else { \ 239 if (exponent <= 52) { \ 240 Dintp1(destA) = Dallp1(dbl_valueA) >> (52-exponent); \ 241 if (exponent == 52) Dintp2(destB) = Dallp2(dbl_valueB); \ 242 else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \ 243 52-exponent,Dintp2(destB)); \ 244 } \ 245 else { \ 246 Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \ 247 84-exponent,Dintp1(destA)); \ 248 Dintp2(destB) = Dallp2(dbl_valueB) << (exponent-52); \ 249 } \ 250 }} 251 252 #define Dint_setzero(dresultA,dresultB) \ 253 Dintp1(dresultA) = 0; \ 254 Dintp2(dresultB) = 0 255 256 #define Dint_setone_sign(dresultA,dresultB) \ 257 Dintp1(dresultA) = ~Dintp1(dresultA); \ 258 if ((Dintp2(dresultB) = -Dintp2(dresultB)) == 0) Dintp1(dresultA)++ 259 260 #define Dint_set_minint(dresultA,dresultB) \ 261 Dintp1(dresultA) = 1<<31; \ 262 Dintp2(dresultB) = 0 263 264 #define Dint_isone_lowp2(dresultB) (Dintp2(dresultB) & 01) 265 266 #define Dint_increment(dresultA,dresultB) \ 267 if ((++Dintp2(dresultB))==0) Dintp1(dresultA)++ 268 269 #define Dint_decrement(dresultA,dresultB) \ 270 if ((Dintp2(dresultB)--)==0) Dintp1(dresultA)-- 271 272 #define Dint_negate(dresultA,dresultB) \ 273 Dintp1(dresultA) = ~Dintp1(dresultA); \ 274 if ((Dintp2(dresultB) = -Dintp2(dresultB))==0) Dintp1(dresultA)++ 275 276 #define Dint_copyfromptr(src,destA,destB) \ 277 Dintp1(destA) = src->wd0; \ 278 Dintp2(destB) = src->wd1 279 #define Dint_copytoptr(srcA,srcB,dest) \ 280 dest->wd0 = Dintp1(srcA); \ 281 dest->wd1 = Dintp2(srcB) 282 283 284 /* other macros */ 285 286 #define Find_ms_one_bit(value, position) \ 287 { \ 288 int var; \ 289 for (var = 8; var >= 1; var >>= 1) { \ 290 if (value >> (32 - position)) \ 291 position -= var; \ 292 else position += var; \ 293 } \ 294 if ((value >> (32 - position)) == 0) \ 295 position--; \ 296 else position -= 2; \ 297 } 298 299 int sgl_to_sgl_fcnvfx(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *); 300 int sgl_to_dbl_fcnvfx(sgl_floating_point *, sgl_floating_point *, dbl_integer *, unsigned int *); 301 int dbl_to_sgl_fcnvfx(dbl_floating_point *, dbl_floating_point *, int *, unsigned int *); 302 int dbl_to_dbl_fcnvfx(dbl_floating_point *, dbl_floating_point *, dbl_integer *, unsigned int *); 303 304 int sgl_to_sgl_fcnvfxt(sgl_floating_point *, sgl_floating_point *, int *, unsigned int *); 305 int sgl_to_dbl_fcnvfxt(sgl_floating_point *, sgl_floating_point *, dbl_integer *, unsigned int *); 306 int dbl_to_sgl_fcnvfxt(dbl_floating_point *, dbl_floating_point *, int *, unsigned int *); 307 int dbl_to_dbl_fcnvfxt(dbl_floating_point *, dbl_floating_point *, dbl_integer *, unsigned int *); 308 309 int sgl_to_sgl_fcnvxf(int *, int *, sgl_floating_point *, unsigned int *); 310 int sgl_to_dbl_fcnvxf(int *, int *, dbl_floating_point *, unsigned int *); 311 int dbl_to_sgl_fcnvxf(dbl_integer *, dbl_integer *, sgl_floating_point *, unsigned int *); 312 int dbl_to_dbl_fcnvxf(dbl_integer *, dbl_integer *, dbl_floating_point *, unsigned int *); 313