Skip to content

Commit 0c25a34

Browse files
kkwliMark Danial
authored andcommitted
swap two halves in Int128 in big endian
1 parent e5639ec commit 0c25a34

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

flang/include/flang/Common/uint128.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323
#include <cstdint>
2424
#include <type_traits>
2525

26+
#if FLANG_LITTLE_ENDIAN
27+
#define SWAP(a, i, b, j) \
28+
a{i}, b { j }
29+
#elif FLANG_BIG_ENDIAN
30+
#define SWAP(a, i, b, j) \
31+
b{j}, a { i }
32+
#else
33+
#error host endianness is not known
34+
#endif
35+
2636
namespace Fortran::common {
2737

2838
template <bool IS_SIGNED = false> class Int128 {
@@ -34,14 +44,14 @@ template <bool IS_SIGNED = false> class Int128 {
3444
constexpr Int128(unsigned long n) : low_{n} {}
3545
constexpr Int128(unsigned long long n) : low_{n} {}
3646
constexpr Int128(int n)
37-
: low_{static_cast<std::uint64_t>(n)}, high_{-static_cast<std::uint64_t>(
38-
n < 0)} {}
47+
: SWAP(low_, static_cast<std::uint64_t>(n), high_,
48+
-static_cast<std::uint64_t>(n < 0)) {}
3949
constexpr Int128(long n)
40-
: low_{static_cast<std::uint64_t>(n)}, high_{-static_cast<std::uint64_t>(
41-
n < 0)} {}
50+
: SWAP(low_, static_cast<std::uint64_t>(n), high_,
51+
-static_cast<std::uint64_t>(n < 0)) {}
4252
constexpr Int128(long long n)
43-
: low_{static_cast<std::uint64_t>(n)}, high_{-static_cast<std::uint64_t>(
44-
n < 0)} {}
53+
: SWAP(low_, static_cast<std::uint64_t>(n), high_,
54+
-static_cast<std::uint64_t>(n < 0)) {}
4555
constexpr Int128(const Int128 &) = default;
4656
constexpr Int128(Int128 &&) = default;
4757
constexpr Int128 &operator=(const Int128 &) = default;
@@ -246,7 +256,8 @@ template <bool IS_SIGNED = false> class Int128 {
246256
}
247257

248258
private:
249-
constexpr Int128(std::uint64_t hi, std::uint64_t lo) : low_{lo}, high_{hi} {}
259+
constexpr Int128(std::uint64_t hi, std::uint64_t lo)
260+
: SWAP(low_, lo, high_, hi) {}
250261
constexpr int LeadingZeroes() const {
251262
if (high_ == 0) {
252263
return 64 + LeadingZeroBitCount(low_);
@@ -255,7 +266,7 @@ template <bool IS_SIGNED = false> class Int128 {
255266
}
256267
}
257268
static constexpr std::uint64_t topBit{std::uint64_t{1} << 63};
258-
std::uint64_t low_{0}, high_{0};
269+
std::uint64_t SWAP(low_, 0, high_, 0);
259270
};
260271

261272
using UnsignedInt128 = Int128<false>;
@@ -288,4 +299,7 @@ template <int BITS>
288299
using HostSignedIntType = typename HostSignedIntTypeHelper<BITS>::type;
289300

290301
} // namespace Fortran::common
302+
303+
#undef SWAP
304+
291305
#endif

flang/runtime/edit-input.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,11 @@ bool EditIntegerInput(
244244
value = -value;
245245
}
246246
if (any || !io.GetConnectionState().IsAtEOF()) {
247-
// For integer kind <= 4, the value is stored in the lower order bits on
248-
// the big endian platform. When memcpy the value, shift the value, shift
249-
// the value to the higher order bit.
250-
if (!isHostLittleEndian && kind <= 4) {
251-
auto l{value.low() << (8 * (sizeof(value.low()) - kind))};
247+
// The value is stored in the lower order bits on big endian platform.
248+
// When memcpy, shift the value to the higher order bit.
249+
auto shft{static_cast<int>(sizeof(value.low())) - kind};
250+
if (!isHostLittleEndian && shft >= 0) {
251+
auto l{value.low() << (8 * shft)};
252252
std::memcpy(n, &l, kind);
253253
} else {
254254
std::memcpy(n, &value, kind); // a blank field means zero

0 commit comments

Comments
 (0)