fp.c (13564B)
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // 3 // Consolidated soft-float runtime helpers for kit's libkit_rt.a. 4 // The build compiles only this one file; the per-op .c files are #included 5 // as snippets and not directly compiled. The fp_lib_undef.h reset header is 6 // included between sections that switch precision or (src,dst) pair. 7 // License: Apache-2.0 WITH LLVM-exception (see lib/LICENSE-compiler-rt.txt). 8 9 // ============================================================ 10 // Section 1: SINGLE precision arith / compare / conv 11 // ============================================================ 12 // ---- addsf3.c ---- 13 #define SINGLE_PRECISION 14 #include "fp_add_impl.inc" 15 16 COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); } 17 18 // ---- subsf3.c ---- 19 #define SINGLE_PRECISION 20 #include "fp_lib.h" 21 22 // Subtraction; flip the sign bit of b and add. 23 COMPILER_RT_ABI fp_t __subsf3(fp_t a, fp_t b) { 24 return __addsf3(a, fromRep(toRep(b) ^ signBit)); 25 } 26 27 // ---- mulsf3.c ---- 28 #define SINGLE_PRECISION 29 #include "fp_mul_impl.inc" 30 31 COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } 32 33 // ---- divsf3.c ---- 34 #define SINGLE_PRECISION 35 36 #define NUMBER_OF_HALF_ITERATIONS 0 37 #define NUMBER_OF_FULL_ITERATIONS 3 38 #define USE_NATIVE_FULL_ITERATIONS 39 40 #include "fp_div_impl.inc" 41 42 COMPILER_RT_ABI fp_t __divsf3(fp_t a, fp_t b) { return __divXf3__(a, b); } 43 44 #undef NUMBER_OF_HALF_ITERATIONS 45 #undef NUMBER_OF_FULL_ITERATIONS 46 #undef USE_NATIVE_FULL_ITERATIONS 47 // ---- negsf2.c ---- 48 #define SINGLE_PRECISION 49 #include "fp_lib.h" 50 51 COMPILER_RT_ABI fp_t __negsf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } 52 53 // ---- comparesf2.c ---- 54 #define SINGLE_PRECISION 55 #include "fp_compare_impl.inc" 56 #include "fp_lib.h" 57 58 COMPILER_RT_ABI CMP_RESULT __lesf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 59 COMPILER_RT_ABI CMP_RESULT __eqsf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 60 COMPILER_RT_ABI CMP_RESULT __ltsf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 61 COMPILER_RT_ABI CMP_RESULT __nesf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 62 COMPILER_RT_ABI CMP_RESULT __gesf2(fp_t a, fp_t b) { return __geXf2__(a, b); } 63 COMPILER_RT_ABI CMP_RESULT __gtsf2(fp_t a, fp_t b) { return __geXf2__(a, b); } 64 COMPILER_RT_ABI CMP_RESULT __unordsf2(fp_t a, fp_t b) { 65 return __unordXf2__(a, b); 66 } 67 68 // ---- floatsisf.c ---- 69 #define SINGLE_PRECISION 70 #include "fp_lib.h" 71 #include "int_lib.h" 72 73 COMPILER_RT_ABI fp_t __floatsisf(si_int a) { 74 const int aWidth = sizeof a * CHAR_BIT; 75 76 // Handle zero as a special case to protect clz 77 if (a == 0) return fromRep(0); 78 79 // All other cases begin by extracting the sign and absolute value of a 80 rep_t sign = 0; 81 su_int aAbs = (su_int)a; 82 if (a < 0) { 83 sign = signBit; 84 aAbs = -aAbs; 85 } 86 87 // Exponent of (fp_t)a is the width of abs(a). 88 const int exponent = (aWidth - 1) - clzsi(aAbs); 89 rep_t result; 90 91 // Shift a into the significand field, rounding if it is a right-shift 92 if (exponent <= significandBits) { 93 const int shift = significandBits - exponent; 94 result = (rep_t)aAbs << shift ^ implicitBit; 95 } else { 96 const int shift = exponent - significandBits; 97 result = (rep_t)aAbs >> shift ^ implicitBit; 98 rep_t round = (rep_t)aAbs << (typeWidth - shift); 99 if (round > signBit) result++; 100 if (round == signBit) result += result & 1; 101 } 102 103 // Insert the exponent 104 result += (rep_t)(exponent + exponentBias) << significandBits; 105 // Insert the sign bit and return 106 return fromRep(result | sign); 107 } 108 109 // ---- floatunsisf.c ---- 110 #define SINGLE_PRECISION 111 #include "fp_lib.h" 112 #include "int_lib.h" 113 114 COMPILER_RT_ABI fp_t __floatunsisf(su_int a) { 115 const int aWidth = sizeof a * CHAR_BIT; 116 117 // Handle zero as a special case to protect clz 118 if (a == 0) return fromRep(0); 119 120 // Exponent of (fp_t)a is the width of abs(a). 121 const int exponent = (aWidth - 1) - clzsi(a); 122 rep_t result; 123 124 // Shift a into the significand field, rounding if it is a right-shift 125 if (exponent <= significandBits) { 126 const int shift = significandBits - exponent; 127 result = (rep_t)a << shift ^ implicitBit; 128 } else { 129 const int shift = exponent - significandBits; 130 result = (rep_t)a >> shift ^ implicitBit; 131 rep_t round = (rep_t)a << (typeWidth - shift); 132 if (round > signBit) result++; 133 if (round == signBit) result += result & 1; 134 } 135 136 // Insert the exponent 137 result += (rep_t)(exponent + exponentBias) << significandBits; 138 return fromRep(result); 139 } 140 141 // ---- floatdisf.c ---- 142 #include "int_lib.h" 143 144 #define SRC_I64 145 #define DST_SINGLE 146 #include "int_to_fp_impl.inc" 147 148 COMPILER_RT_ABI float __floatdisf(di_int a) { return __floatXiYf__(a); } 149 150 #undef SRC_I64 151 #undef DST_SINGLE 152 // ---- floatundisf.c ---- 153 #include "int_lib.h" 154 155 #define SRC_U64 156 #define DST_SINGLE 157 #include "int_to_fp_impl.inc" 158 159 COMPILER_RT_ABI float __floatundisf(du_int a) { return __floatXiYf__(a); } 160 161 #undef SRC_U64 162 #undef DST_SINGLE 163 // ---- fixsfsi.c ---- 164 #define SINGLE_PRECISION 165 #include "fp_lib.h" 166 #define fixint_t si_int 167 #define fixuint_t su_int 168 #define FP_FIX_SUFFIX fixsfsi 169 #include "fp_fixint_impl.inc" 170 171 COMPILER_RT_ABI si_int __fixsfsi(fp_t a) { return __fixint(a); } 172 173 #undef fixint_t 174 #undef fixuint_t 175 #undef FP_FIX_SUFFIX 176 // ---- fixsfdi.c ---- 177 #define SINGLE_PRECISION 178 #include "fp_lib.h" 179 180 // Support for systems that don't have hardware floating-point; there are no 181 // flags to set, and we don't want to code-gen to an unknown soft-float 182 // implementation. 183 184 #define fixint_t di_int 185 #define fixuint_t du_int 186 #define FP_FIX_SUFFIX fixsfdi 187 #include "fp_fixint_impl.inc" 188 189 COMPILER_RT_ABI di_int __fixsfdi(fp_t a) { return __fixint(a); } 190 191 #undef fixint_t 192 #undef fixuint_t 193 #undef FP_FIX_SUFFIX 194 // ---- fixunssfsi.c ---- 195 #define SINGLE_PRECISION 196 #include "fp_lib.h" 197 #define fixuint_t su_int 198 #define FP_FIX_SUFFIX fixunssfsi 199 #include "fp_fixuint_impl.inc" 200 201 COMPILER_RT_ABI su_int __fixunssfsi(fp_t a) { return __fixuint(a); } 202 203 #undef fixuint_t 204 #undef FP_FIX_SUFFIX 205 // ---- fixunssfdi.c ---- 206 #define SINGLE_PRECISION 207 #include "fp_lib.h" 208 209 // Support for systems that don't have hardware floating-point; there are no 210 // flags to set, and we don't want to code-gen to an unknown soft-float 211 // implementation. 212 213 #define fixuint_t du_int 214 #define FP_FIX_SUFFIX fixunssfdi 215 #include "fp_fixuint_impl.inc" 216 217 COMPILER_RT_ABI du_int __fixunssfdi(fp_t a) { return __fixuint(a); } 218 219 #undef fixuint_t 220 #undef FP_FIX_SUFFIX 221 222 #include "fp_lib_undef.h" 223 224 // ============================================================ 225 // Section 2: DOUBLE precision arith / compare / conv 226 // ============================================================ 227 // ---- adddf3.c ---- 228 #define DOUBLE_PRECISION 229 #include "fp_add_impl.inc" 230 231 COMPILER_RT_ABI double __adddf3(double a, double b) { return __addXf3__(a, b); } 232 233 // ---- subdf3.c ---- 234 #define DOUBLE_PRECISION 235 #include "fp_lib.h" 236 237 // Subtraction; flip the sign bit of b and add. 238 COMPILER_RT_ABI fp_t __subdf3(fp_t a, fp_t b) { 239 return __adddf3(a, fromRep(toRep(b) ^ signBit)); 240 } 241 242 // ---- muldf3.c ---- 243 #define DOUBLE_PRECISION 244 #include "fp_mul_impl.inc" 245 246 COMPILER_RT_ABI fp_t __muldf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } 247 248 // ---- divdf3.c ---- 249 #define DOUBLE_PRECISION 250 251 #define NUMBER_OF_HALF_ITERATIONS 3 252 #define NUMBER_OF_FULL_ITERATIONS 1 253 254 #include "fp_div_impl.inc" 255 256 COMPILER_RT_ABI fp_t __divdf3(fp_t a, fp_t b) { return __divXf3__(a, b); } 257 258 #undef NUMBER_OF_HALF_ITERATIONS 259 #undef NUMBER_OF_FULL_ITERATIONS 260 // ---- negdf2.c ---- 261 #define DOUBLE_PRECISION 262 #include "fp_lib.h" 263 264 COMPILER_RT_ABI fp_t __negdf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } 265 266 // ---- comparedf2.c ---- 267 #define DOUBLE_PRECISION 268 #include "fp_compare_impl.inc" 269 #include "fp_lib.h" 270 271 COMPILER_RT_ABI CMP_RESULT __ledf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 272 COMPILER_RT_ABI CMP_RESULT __eqdf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 273 COMPILER_RT_ABI CMP_RESULT __ltdf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 274 COMPILER_RT_ABI CMP_RESULT __nedf2(fp_t a, fp_t b) { return __leXf2__(a, b); } 275 COMPILER_RT_ABI CMP_RESULT __gedf2(fp_t a, fp_t b) { return __geXf2__(a, b); } 276 COMPILER_RT_ABI CMP_RESULT __gtdf2(fp_t a, fp_t b) { return __geXf2__(a, b); } 277 COMPILER_RT_ABI CMP_RESULT __unorddf2(fp_t a, fp_t b) { 278 return __unordXf2__(a, b); 279 } 280 281 // ---- floatsidf.c ---- 282 #define DOUBLE_PRECISION 283 #include "fp_lib.h" 284 #include "int_lib.h" 285 286 COMPILER_RT_ABI fp_t __floatsidf(si_int a) { 287 const int aWidth = sizeof a * CHAR_BIT; 288 289 // Handle zero as a special case to protect clz 290 if (a == 0) return fromRep(0); 291 292 // All other cases begin by extracting the sign and absolute value of a 293 rep_t sign = 0; 294 su_int aAbs = (su_int)a; 295 if (a < 0) { 296 sign = signBit; 297 aAbs = -aAbs; 298 } 299 300 // Exponent of (fp_t)a is the width of abs(a). 301 const int exponent = (aWidth - 1) - clzsi(aAbs); 302 rep_t result; 303 304 // Shift a into the significand field and clear the implicit bit. Extra 305 // cast to unsigned int is necessary to get the correct behavior for 306 // the input INT_MIN. 307 const int shift = significandBits - exponent; 308 result = (rep_t)aAbs << shift ^ implicitBit; 309 310 // Insert the exponent 311 result += (rep_t)(exponent + exponentBias) << significandBits; 312 // Insert the sign bit and return 313 return fromRep(result | sign); 314 } 315 316 // ---- floatunsidf.c ---- 317 #define DOUBLE_PRECISION 318 #include "fp_lib.h" 319 #include "int_lib.h" 320 321 COMPILER_RT_ABI fp_t __floatunsidf(su_int a) { 322 const int aWidth = sizeof a * CHAR_BIT; 323 324 // Handle zero as a special case to protect clz 325 if (a == 0) return fromRep(0); 326 327 // Exponent of (fp_t)a is the width of abs(a). 328 const int exponent = (aWidth - 1) - clzsi(a); 329 rep_t result; 330 331 // Shift a into the significand field and clear the implicit bit. 332 const int shift = significandBits - exponent; 333 result = (rep_t)a << shift ^ implicitBit; 334 335 // Insert the exponent 336 result += (rep_t)(exponent + exponentBias) << significandBits; 337 return fromRep(result); 338 } 339 340 // ---- floatdidf.c ---- 341 #include "int_lib.h" 342 343 // Returns: convert a to a double, rounding toward even. 344 345 // Assumption: double is a IEEE 64 bit floating point type 346 // di_int is a 64 bit integral type 347 348 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm 349 // mmmm 350 351 // Support for systems that don't have hardware floating-point; there are no 352 // flags to set, and we don't want to code-gen to an unknown soft-float 353 // implementation. 354 355 #define SRC_I64 356 #define DST_DOUBLE 357 #include "int_to_fp_impl.inc" 358 359 COMPILER_RT_ABI double __floatdidf(di_int a) { return __floatXiYf__(a); } 360 361 #undef SRC_I64 362 #undef DST_DOUBLE 363 // ---- floatundidf.c ---- 364 #include "int_lib.h" 365 366 // Support for systems that don't have hardware floating-point; there are no 367 // flags to set, and we don't want to code-gen to an unknown soft-float 368 // implementation. 369 370 #define SRC_U64 371 #define DST_DOUBLE 372 #include "int_to_fp_impl.inc" 373 374 COMPILER_RT_ABI double __floatundidf(du_int a) { return __floatXiYf__(a); } 375 376 #undef SRC_U64 377 #undef DST_DOUBLE 378 // ---- fixdfsi.c ---- 379 #define DOUBLE_PRECISION 380 #include "fp_lib.h" 381 #define fixint_t si_int 382 #define fixuint_t su_int 383 #define FP_FIX_SUFFIX fixdfsi 384 #include "fp_fixint_impl.inc" 385 386 COMPILER_RT_ABI si_int __fixdfsi(fp_t a) { return __fixint(a); } 387 388 #undef fixint_t 389 #undef fixuint_t 390 #undef FP_FIX_SUFFIX 391 // ---- fixdfdi.c ---- 392 #define DOUBLE_PRECISION 393 #include "fp_lib.h" 394 395 // Support for systems that don't have hardware floating-point; there are no 396 // flags to set, and we don't want to code-gen to an unknown soft-float 397 // implementation. 398 399 #define fixint_t di_int 400 #define fixuint_t du_int 401 #define FP_FIX_SUFFIX fixdfdi 402 #include "fp_fixint_impl.inc" 403 404 COMPILER_RT_ABI di_int __fixdfdi(fp_t a) { return __fixint(a); } 405 406 #undef fixint_t 407 #undef fixuint_t 408 #undef FP_FIX_SUFFIX 409 // ---- fixunsdfsi.c ---- 410 #define DOUBLE_PRECISION 411 #include "fp_lib.h" 412 #define fixuint_t su_int 413 #define FP_FIX_SUFFIX fixunsdfsi 414 #include "fp_fixuint_impl.inc" 415 416 COMPILER_RT_ABI su_int __fixunsdfsi(fp_t a) { return __fixuint(a); } 417 418 #undef fixuint_t 419 #undef FP_FIX_SUFFIX 420 // ---- fixunsdfdi.c ---- 421 #define DOUBLE_PRECISION 422 #include "fp_lib.h" 423 424 // Support for systems that don't have hardware floating-point; there are no 425 // flags to set, and we don't want to code-gen to an unknown soft-float 426 // implementation. 427 428 #define fixuint_t du_int 429 #define FP_FIX_SUFFIX fixunsdfdi 430 #include "fp_fixuint_impl.inc" 431 432 COMPILER_RT_ABI du_int __fixunsdfdi(fp_t a) { return __fixuint(a); } 433 434 #undef fixuint_t 435 #undef FP_FIX_SUFFIX 436 437 #include "fp_lib_undef.h" 438 439 // ============================================================ 440 // Section 3: sf -> df extend 441 // ============================================================ 442 // ---- extendsfdf2.c ---- 443 #define SRC_SINGLE 444 #define DST_DOUBLE 445 #include "fp_extend_impl.inc" 446 447 COMPILER_RT_ABI double __extendsfdf2(float a) { return __extendXfYf2__(a); } 448 449 #undef SRC_SINGLE 450 #undef DST_DOUBLE 451 452 #include "fp_lib_undef.h" 453 454 // ============================================================ 455 // Section 4: df -> sf truncate 456 // ============================================================ 457 // ---- truncdfsf2.c ---- 458 #define SRC_DOUBLE 459 #define DST_SINGLE 460 #include "fp_trunc_impl.inc" 461 462 COMPILER_RT_ABI float __truncdfsf2(double a) { return __truncXfYf2__(a); } 463 464 #undef SRC_DOUBLE 465 #undef DST_SINGLE 466 467 #include "fp_lib_undef.h" 468 469 // ============================================================ 470 // Section 5: fp_mode (precision-independent) 471 // ============================================================ 472 // ---- fp_mode.c ---- 473 #include "fp_mode.h" 474 475 // IEEE-754 default rounding (to nearest, ties to even). 476 CRT_FE_ROUND_MODE __fe_getround(void) { return CRT_FE_TONEAREST; } 477 478 int __fe_raise_inexact(void) { return 0; }