[flang-commits] [flang] fdccfa3 - [Flang] Shift the data from lower to higher order bits in the big endian environment (#73670)
via flang-commits
flang-commits at lists.llvm.org
Thu Dec 28 15:29:40 PST 2023
Author: madanial0
Date: 2023-12-28T18:29:36-05:00
New Revision: fdccfa33d96b1935e90a9148a661f51ea8b46aa3
URL: https://github.com/llvm/llvm-project/commit/fdccfa33d96b1935e90a9148a661f51ea8b46aa3
DIFF: https://github.com/llvm/llvm-project/commit/fdccfa33d96b1935e90a9148a661f51ea8b46aa3.diff
LOG: [Flang] Shift the data from lower to higher order bits in the big endian environment (#73670)
Shift the data from lower to higher order bits when memcpy the value in
the namelist in the big endian environment
---------
Co-authored-by: Mark Danial <mark.danial at ibm.com>
Co-authored-by: Kelvin Li <kli at ca.ibm.com>
Added:
Modified:
flang/include/flang/Common/uint128.h
flang/runtime/edit-input.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Common/uint128.h b/flang/include/flang/Common/uint128.h
index bfd2eef01f6f08..03e44eb6997d5b 100644
--- a/flang/include/flang/Common/uint128.h
+++ b/flang/include/flang/Common/uint128.h
@@ -33,15 +33,18 @@ template <bool IS_SIGNED = false> class Int128 {
constexpr Int128(unsigned n) : low_{n} {}
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)} {}
- constexpr Int128(long n)
- : 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)} {}
+ constexpr Int128(int n) {
+ 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);
+ }
+ constexpr Int128(long long n) {
+ 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 +249,10 @@ 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) {
+ low_ = lo;
+ high_ = hi;
+ }
constexpr int LeadingZeroes() const {
if (high_ == 0) {
return 64 + LeadingZeroBitCount(low_);
@@ -255,7 +261,13 @@ template <bool IS_SIGNED = false> class Int128 {
}
}
static constexpr std::uint64_t topBit{std::uint64_t{1} << 63};
+#if FLANG_LITTLE_ENDIAN
std::uint64_t low_{0}, high_{0};
+#elif FLANG_BIG_ENDIAN
+ std::uint64_t high_{0}, low_{0};
+#else
+#error host endianness is not known
+#endif
};
using UnsignedInt128 = Int128<false>;
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index 2b809749067772..c4fa186e289db2 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -244,7 +244,16 @@ bool EditIntegerInput(
value = -value;
}
if (any || !io.GetConnectionState().IsAtEOF()) {
- std::memcpy(n, &value, kind); // a blank field means zero
+ // 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};
+ // For kind==8 (i.e. shft==0), the value is stored in low_ in big endian.
+ 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
+ }
}
return any;
}
More information about the flang-commits
mailing list