kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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; }