compat: Add libcomparetf2 shim
Provide __lttf2 to various blobs Change-Id: Idb8309fcdc969e9954f0b8b4ca7a39ab261e64de
This commit is contained in:
parent
07607db7a4
commit
bfad08e532
2 changed files with 78 additions and 0 deletions
|
@ -359,3 +359,10 @@ cc_library_shared {
|
|||
system_ext_specific: true,
|
||||
vendor_available: true,
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libcomparetf2_shim",
|
||||
srcs: ["libcomparetf2/comparetf2.c"],
|
||||
compile_multilib: "64",
|
||||
vendor: true,
|
||||
}
|
||||
|
|
71
libcomparetf2/comparetf2.c
Normal file
71
libcomparetf2/comparetf2.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
//===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
typedef __uint128_t rep_t;
|
||||
typedef __int128_t srep_t;
|
||||
typedef long double fp_t;
|
||||
|
||||
#define REP_C (__uint128_t)
|
||||
#define typeWidth (sizeof(rep_t) * CHAR_BIT)
|
||||
#define significandBits 112
|
||||
#define exponentBits (typeWidth - significandBits - 1)
|
||||
|
||||
#define implicitBit (REP_C(1) << significandBits)
|
||||
#define significandMask (implicitBit - 1U)
|
||||
#define signBit (REP_C(1) << (significandBits + exponentBits))
|
||||
#define absMask (signBit - 1U)
|
||||
#define exponentMask (absMask ^ significandMask)
|
||||
#define infRep exponentMask
|
||||
|
||||
static __inline rep_t toRep(fp_t x) {
|
||||
const union {
|
||||
fp_t f;
|
||||
rep_t i;
|
||||
} rep = {.f = x};
|
||||
return rep.i;
|
||||
}
|
||||
|
||||
enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 };
|
||||
|
||||
enum LE_RESULT __lttf2(fp_t a, fp_t b) {
|
||||
|
||||
const srep_t aInt = toRep(a);
|
||||
const srep_t bInt = toRep(b);
|
||||
const rep_t aAbs = aInt & absMask;
|
||||
const rep_t bAbs = bInt & absMask;
|
||||
|
||||
// If either a or b is NaN, they are unordered.
|
||||
if (aAbs > infRep || bAbs > infRep)
|
||||
return LE_UNORDERED;
|
||||
|
||||
// If a and b are both zeros, they are equal.
|
||||
if ((aAbs | bAbs) == 0)
|
||||
return LE_EQUAL;
|
||||
|
||||
// If at least one of a and b is positive, we get the same result comparing
|
||||
// a and b as signed integers as we would with a floating-point compare.
|
||||
if ((aInt & bInt) >= 0) {
|
||||
if (aInt < bInt)
|
||||
return LE_LESS;
|
||||
else if (aInt == bInt)
|
||||
return LE_EQUAL;
|
||||
else
|
||||
return LE_GREATER;
|
||||
} else {
|
||||
// Otherwise, both are negative, so we need to flip the sense of the
|
||||
// comparison to get the correct result. (This assumes a twos- or ones-
|
||||
// complement integer representation; if integers are represented in a
|
||||
// sign-magnitude representation, then this flip is incorrect).
|
||||
if (aInt > bInt)
|
||||
return LE_LESS;
|
||||
else if (aInt == bInt)
|
||||
return LE_EQUAL;
|
||||
else
|
||||
return LE_GREATER;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue