[flang-commits] [flang] [Flang] Shift the data from lower to higher order bits in the big endian environment (PR #73670)
via flang-commits
flang-commits at lists.llvm.org
Thu Dec 14 09:13:06 PST 2023
https://github.com/madanial0 updated https://github.com/llvm/llvm-project/pull/73670
>From 7cffd6fa49ce7a0e7c9ef0af6ad1e8d42598e099 Mon Sep 17 00:00:00 2001
From: Mark Danial <madanial at dixon.rtp.raleigh.ibm.com>
Date: Mon, 27 Nov 2023 21:11:52 -0500
Subject: [PATCH 1/2] [Flang] Shift the data from lower to higher order bits in
the big endian environment
---
flang/runtime/edit-input.cpp | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index 822099b5141b1b..71b2d3a4818427 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -244,7 +244,15 @@ bool EditIntegerInput(
value = -value;
}
if (any || !io.GetConnectionState().IsAtEOF()) {
- std::memcpy(n, &value, kind); // a blank field means zero
+ // For integer kind <= 4, the value is stored in the lower order bits on
+ // the big endian platform. When memcpy the value, shift the value, shift
+ // the value to the higher order bit.
+ if (!isHostLittleEndian && kind <= 4) {
+ auto l{value.low() << (8 * (sizeof(value.low()) - kind))};
+ std::memcpy(n, &l, kind);
+ } else {
+ std::memcpy(n, &value, kind); // a blank field means zero
+ }
}
return any;
}
>From 19367432e424f117c7c8a3267419307ea6e130aa Mon Sep 17 00:00:00 2001
From: Kelvin Li <kli at ca.ibm.com>
Date: Tue, 12 Dec 2023 15:56:33 -0500
Subject: [PATCH 2/2] swap two halves in Int128 in big endian
---
flang/include/flang/Common/uint128.h | 30 ++++++++++++++++++++--------
flang/runtime/edit-input.cpp | 10 +++++-----
2 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/flang/include/flang/Common/uint128.h b/flang/include/flang/Common/uint128.h
index bfd2eef01f6f08..c66dc4f303a734 100644
--- a/flang/include/flang/Common/uint128.h
+++ b/flang/include/flang/Common/uint128.h
@@ -23,6 +23,16 @@
#include <cstdint>
#include <type_traits>
+#if FLANG_LITTLE_ENDIAN
+#define SWAP(a, i, b, j) \
+ a{i}, b { j }
+#elif FLANG_BIG_ENDIAN
+#define SWAP(a, i, b, j) \
+ b{j}, a { i }
+#else
+#error host endianness is not known
+#endif
+
namespace Fortran::common {
template <bool IS_SIGNED = false> class Int128 {
@@ -34,14 +44,14 @@ template <bool IS_SIGNED = false> class Int128 {
constexpr Int128(unsigned long n) : low_{n} {}
constexpr Int128(unsigned long long n) : low_{n} {}
constexpr Int128(int n)
- : low_{static_cast<std::uint64_t>(n)}, high_{-static_cast<std::uint64_t>(
- n < 0)} {}
+ : SWAP(low_, static_cast<std::uint64_t>(n), high_,
+ -static_cast<std::uint64_t>(n < 0)) {}
constexpr Int128(long n)
- : low_{static_cast<std::uint64_t>(n)}, high_{-static_cast<std::uint64_t>(
- n < 0)} {}
+ : SWAP(low_, static_cast<std::uint64_t>(n), high_,
+ -static_cast<std::uint64_t>(n < 0)) {}
constexpr Int128(long long n)
- : low_{static_cast<std::uint64_t>(n)}, high_{-static_cast<std::uint64_t>(
- n < 0)} {}
+ : SWAP(low_, static_cast<std::uint64_t>(n), high_,
+ -static_cast<std::uint64_t>(n < 0)) {}
constexpr Int128(const Int128 &) = default;
constexpr Int128(Int128 &&) = default;
constexpr Int128 &operator=(const Int128 &) = default;
@@ -246,7 +256,8 @@ template <bool IS_SIGNED = false> class Int128 {
}
private:
- constexpr Int128(std::uint64_t hi, std::uint64_t lo) : low_{lo}, high_{hi} {}
+ constexpr Int128(std::uint64_t hi, std::uint64_t lo)
+ : SWAP(low_, lo, high_, hi) {}
constexpr int LeadingZeroes() const {
if (high_ == 0) {
return 64 + LeadingZeroBitCount(low_);
@@ -255,7 +266,7 @@ template <bool IS_SIGNED = false> class Int128 {
}
}
static constexpr std::uint64_t topBit{std::uint64_t{1} << 63};
- std::uint64_t low_{0}, high_{0};
+ std::uint64_t SWAP(low_, 0, high_, 0);
};
using UnsignedInt128 = Int128<false>;
@@ -288,4 +299,7 @@ template <int BITS>
using HostSignedIntType = typename HostSignedIntTypeHelper<BITS>::type;
} // namespace Fortran::common
+
+#undef SWAP
+
#endif
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index 71b2d3a4818427..1267e5281c5ab4 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -244,11 +244,11 @@ bool EditIntegerInput(
value = -value;
}
if (any || !io.GetConnectionState().IsAtEOF()) {
- // For integer kind <= 4, the value is stored in the lower order bits on
- // the big endian platform. When memcpy the value, shift the value, shift
- // the value to the higher order bit.
- if (!isHostLittleEndian && kind <= 4) {
- auto l{value.low() << (8 * (sizeof(value.low()) - kind))};
+ // The value is stored in the lower order bits on big endian platform.
+ // When memcpy, shift the value to the higher order bit.
+ auto shft{static_cast<int>(sizeof(value.low())) - kind};
+ if (!isHostLittleEndian && shft >= 0) {
+ auto l{value.low() << (8 * shft)};
std::memcpy(n, &l, kind);
} else {
std::memcpy(n, &value, kind); // a blank field means zero
More information about the flang-commits
mailing list