Home | History | Annotate | Line # | Download | only in builtins
      1      1.1  joerg //===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===//
      2      1.1  joerg //
      3      1.1  joerg //                     The LLVM Compiler Infrastructure
      4      1.1  joerg //
      5      1.1  joerg // This file is dual licensed under the MIT and the University of Illinois Open
      6      1.1  joerg // Source Licenses. See LICENSE.TXT for details.
      7      1.1  joerg //
      8      1.1  joerg //===----------------------------------------------------------------------===//
      9      1.1  joerg //
     10      1.1  joerg // // This file implements the following soft-float comparison routines:
     11      1.1  joerg //
     12      1.1  joerg //   __eqtf2   __getf2   __unordtf2
     13      1.1  joerg //   __letf2   __gttf2
     14      1.1  joerg //   __lttf2
     15      1.1  joerg //   __netf2
     16      1.1  joerg //
     17      1.1  joerg // The semantics of the routines grouped in each column are identical, so there
     18      1.1  joerg // is a single implementation for each, and wrappers to provide the other names.
     19      1.1  joerg //
     20      1.1  joerg // The main routines behave as follows:
     21      1.1  joerg //
     22      1.1  joerg //   __letf2(a,b) returns -1 if a < b
     23      1.1  joerg //                         0 if a == b
     24      1.1  joerg //                         1 if a > b
     25      1.1  joerg //                         1 if either a or b is NaN
     26      1.1  joerg //
     27      1.1  joerg //   __getf2(a,b) returns -1 if a < b
     28      1.1  joerg //                         0 if a == b
     29      1.1  joerg //                         1 if a > b
     30      1.1  joerg //                        -1 if either a or b is NaN
     31      1.1  joerg //
     32      1.1  joerg //   __unordtf2(a,b) returns 0 if both a and b are numbers
     33      1.1  joerg //                           1 if either a or b is NaN
     34      1.1  joerg //
     35      1.1  joerg // Note that __letf2( ) and __getf2( ) are identical except in their handling of
     36      1.1  joerg // NaN values.
     37      1.1  joerg //
     38      1.1  joerg //===----------------------------------------------------------------------===//
     39      1.1  joerg 
     40      1.1  joerg #define QUAD_PRECISION
     41      1.1  joerg #include "fp_lib.h"
     42      1.1  joerg 
     43      1.1  joerg #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
     44      1.1  joerg enum LE_RESULT {
     45      1.1  joerg     LE_LESS      = -1,
     46      1.1  joerg     LE_EQUAL     =  0,
     47      1.1  joerg     LE_GREATER   =  1,
     48      1.1  joerg     LE_UNORDERED =  1
     49      1.1  joerg };
     50      1.1  joerg 
     51      1.1  joerg COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {
     52      1.1  joerg 
     53      1.1  joerg     const srep_t aInt = toRep(a);
     54      1.1  joerg     const srep_t bInt = toRep(b);
     55      1.1  joerg     const rep_t aAbs = aInt & absMask;
     56      1.1  joerg     const rep_t bAbs = bInt & absMask;
     57      1.1  joerg 
     58      1.1  joerg     // If either a or b is NaN, they are unordered.
     59      1.1  joerg     if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
     60      1.1  joerg 
     61      1.1  joerg     // If a and b are both zeros, they are equal.
     62      1.1  joerg     if ((aAbs | bAbs) == 0) return LE_EQUAL;
     63      1.1  joerg 
     64      1.1  joerg     // If at least one of a and b is positive, we get the same result comparing
     65      1.1  joerg     // a and b as signed integers as we would with a floating-point compare.
     66      1.1  joerg     if ((aInt & bInt) >= 0) {
     67      1.1  joerg         if (aInt < bInt) return LE_LESS;
     68      1.1  joerg         else if (aInt == bInt) return LE_EQUAL;
     69      1.1  joerg         else return LE_GREATER;
     70      1.1  joerg     }
     71      1.1  joerg     else {
     72      1.1  joerg         // Otherwise, both are negative, so we need to flip the sense of the
     73      1.1  joerg         // comparison to get the correct result.  (This assumes a twos- or ones-
     74      1.1  joerg         // complement integer representation; if integers are represented in a
     75      1.1  joerg         // sign-magnitude representation, then this flip is incorrect).
     76      1.1  joerg         if (aInt > bInt) return LE_LESS;
     77      1.1  joerg         else if (aInt == bInt) return LE_EQUAL;
     78      1.1  joerg         else return LE_GREATER;
     79      1.1  joerg     }
     80      1.1  joerg }
     81      1.1  joerg 
     82  1.1.1.3  joerg #if defined(__ELF__)
     83  1.1.1.3  joerg // Alias for libgcc compatibility
     84  1.1.1.3  joerg FNALIAS(__cmptf2, __letf2);
     85  1.1.1.3  joerg #endif
     86  1.1.1.3  joerg 
     87      1.1  joerg enum GE_RESULT {
     88      1.1  joerg     GE_LESS      = -1,
     89      1.1  joerg     GE_EQUAL     =  0,
     90      1.1  joerg     GE_GREATER   =  1,
     91      1.1  joerg     GE_UNORDERED = -1   // Note: different from LE_UNORDERED
     92      1.1  joerg };
     93      1.1  joerg 
     94      1.1  joerg COMPILER_RT_ABI enum GE_RESULT __getf2(fp_t a, fp_t b) {
     95      1.1  joerg 
     96      1.1  joerg     const srep_t aInt = toRep(a);
     97      1.1  joerg     const srep_t bInt = toRep(b);
     98      1.1  joerg     const rep_t aAbs = aInt & absMask;
     99      1.1  joerg     const rep_t bAbs = bInt & absMask;
    100      1.1  joerg 
    101      1.1  joerg     if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
    102      1.1  joerg     if ((aAbs | bAbs) == 0) return GE_EQUAL;
    103      1.1  joerg     if ((aInt & bInt) >= 0) {
    104      1.1  joerg         if (aInt < bInt) return GE_LESS;
    105      1.1  joerg         else if (aInt == bInt) return GE_EQUAL;
    106      1.1  joerg         else return GE_GREATER;
    107      1.1  joerg     } else {
    108      1.1  joerg         if (aInt > bInt) return GE_LESS;
    109      1.1  joerg         else if (aInt == bInt) return GE_EQUAL;
    110      1.1  joerg         else return GE_GREATER;
    111      1.1  joerg     }
    112      1.1  joerg }
    113      1.1  joerg 
    114      1.1  joerg COMPILER_RT_ABI int __unordtf2(fp_t a, fp_t b) {
    115      1.1  joerg     const rep_t aAbs = toRep(a) & absMask;
    116      1.1  joerg     const rep_t bAbs = toRep(b) & absMask;
    117      1.1  joerg     return aAbs > infRep || bAbs > infRep;
    118      1.1  joerg }
    119      1.1  joerg 
    120  1.1.1.2  joerg // The following are alternative names for the preceding routines.
    121      1.1  joerg 
    122      1.1  joerg COMPILER_RT_ABI enum LE_RESULT __eqtf2(fp_t a, fp_t b) {
    123      1.1  joerg     return __letf2(a, b);
    124      1.1  joerg }
    125      1.1  joerg 
    126      1.1  joerg COMPILER_RT_ABI enum LE_RESULT __lttf2(fp_t a, fp_t b) {
    127      1.1  joerg     return __letf2(a, b);
    128      1.1  joerg }
    129      1.1  joerg 
    130      1.1  joerg COMPILER_RT_ABI enum LE_RESULT __netf2(fp_t a, fp_t b) {
    131      1.1  joerg     return __letf2(a, b);
    132      1.1  joerg }
    133      1.1  joerg 
    134      1.1  joerg COMPILER_RT_ABI enum GE_RESULT __gttf2(fp_t a, fp_t b) {
    135      1.1  joerg     return __getf2(a, b);
    136      1.1  joerg }
    137      1.1  joerg 
    138      1.1  joerg #endif
    139