diff --git a/flang/include/flang/Common/uint128.h b/flang/include/flang/Common/uint128.h index bfd2eef01f6f0..03e44eb6997d5 100644 --- a/flang/include/flang/Common/uint128.h +++ b/flang/include/flang/Common/uint128.h @@ -33,15 +33,18 @@ template 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(n)}, high_{-static_cast( - n < 0)} {} - constexpr Int128(long n) - : low_{static_cast(n)}, high_{-static_cast( - n < 0)} {} - constexpr Int128(long long n) - : low_{static_cast(n)}, high_{-static_cast( - n < 0)} {} + constexpr Int128(int n) { + low_ = static_cast(n); + high_ = -static_cast(n < 0); + } + constexpr Int128(long n) { + low_ = static_cast(n); + high_ = -static_cast(n < 0); + } + constexpr Int128(long long n) { + low_ = static_cast(n); + high_ = -static_cast(n < 0); + } constexpr Int128(const Int128 &) = default; constexpr Int128(Int128 &&) = default; constexpr Int128 &operator=(const Int128 &) = default; @@ -246,7 +249,10 @@ template 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 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; diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp index 2b80974906777..c4fa186e289db 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(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; }