Skip to content

Commit

Permalink
wrap __floattidf
Browse files Browse the repository at this point in the history
Signed-off-by: before-Sunrise <unclejyj@gmail.com>
  • Loading branch information
before-Sunrise committed Jan 26, 2025
1 parent e7e28e9 commit 5c2976b
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
2 changes: 1 addition & 1 deletion be/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ endif()

set(STARROCKS_LINK_LIBS ${STARROCKS_LINK_LIBS}
${WL_LINK_STATIC} -lbfd
${WL_LINK_DYNAMIC} -lresolv -liberty -lc -lm -ldl -rdynamic -pthread -Wl,-wrap=__cxa_throw
${WL_LINK_DYNAMIC} -lresolv -liberty -lc -lm -ldl -rdynamic -pthread -Wl,-wrap,__cxa_throw -Wl,-wrap,__floattidf
)

# link gcov if WITH_GCOV is on
Expand Down
90 changes: 90 additions & 0 deletions be/src/runtime/int128_to_double.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2021-present StarRocks, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "runtime/int128_to_double.h"

#include <climits>
#include <cstdint>

#include "integer_overflow_arithmetics.h"
namespace starrocks {
double __wrap___floattidf(__int128 a) {
typedef double dst_t;
typedef uint64_t dst_rep_t;
typedef __uint128_t usrc_t;
#define DST_REP_C UINT64_C

enum {
dstSigBits = 52,
};

if (a == 0) return 0.0;

enum {
dstMantDig = dstSigBits + 1,
srcBits = sizeof(__int128) * CHAR_BIT,
srcIsSigned = ((__int128)-1) < 0,
};

const __int128 s = srcIsSigned ? a >> (srcBits - 1) : 0;

a = (usrc_t)(a ^ s) - s;
int sd = srcBits - clz128(a); // number of significant digits
int e = sd - 1; // exponent
if (sd > dstMantDig) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit dstMantDig-1 bits to the right of 1
// Q = bit dstMantDig bits to the right of 1
// R = "or" of all bits to the right of Q
if (sd == dstMantDig + 1) {
a <<= 1;
} else if (sd == dstMantDig + 2) {
// Do nothing.
} else {
a = ((usrc_t)a >> (sd - (dstMantDig + 2))) |
((a & ((usrc_t)(-1) >> ((srcBits + dstMantDig + 2) - sd))) != 0);
}
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to dstMantDig or dstMantDig+1 bits
if (a & ((usrc_t)1 << dstMantDig)) {
a >>= 1;
++e;
}
// a is now rounded to dstMantDig bits
} else {
a <<= (dstMantDig - sd);
// a is now rounded to dstMantDig bits
}
const int dstBits = sizeof(dst_t) * CHAR_BIT;
const dst_rep_t dstSignMask = DST_REP_C(1) << (dstBits - 1);
const int dstExpBits = dstBits - dstSigBits - 1;
const int dstExpBias = (1 << (dstExpBits - 1)) - 1;
const dst_rep_t dstSignificandMask = (DST_REP_C(1) << dstSigBits) - 1;
// Combine sign, exponent, and mantissa.
const dst_rep_t result = ((dst_rep_t)s & dstSignMask) | ((dst_rep_t)(e + dstExpBias) << dstSigBits) |
((dst_rep_t)(a)&dstSignificandMask);

const union {
dst_t f;
dst_rep_t i;
} rep = {.i = result};
return rep.f;
}
} // namespace starrocks
21 changes: 21 additions & 0 deletions be/src/runtime/int128_to_double.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2021-present StarRocks, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace starrocks {
extern "C" {
// origin from llvm-project
// https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/int_to_fp_impl.inc
// this implementation is 20x faster than gcc
double __wrap___floattidf(__int128 a);
}
} // namespace starrocks

0 comments on commit 5c2976b

Please sign in to comment.