[flang] LOGICAL
Original-commit: flang-compiler/f18@6ec49f6edc Reviewed-on: https://github.com/flang-compiler/f18/pull/101 Tree-same-pre-rewrite: false
This commit is contained in:
parent
564292ccf7
commit
ed71134af7
|
|
@ -108,4 +108,5 @@ enable_testing()
|
||||||
add_test(NAME Leadz COMMAND leading-zero-bit-count-test)
|
add_test(NAME Leadz COMMAND leading-zero-bit-count-test)
|
||||||
add_test(NAME PopPar COMMAND bit-population-count-test)
|
add_test(NAME PopPar COMMAND bit-population-count-test)
|
||||||
add_test(NAME Integer COMMAND integer-test)
|
add_test(NAME Integer COMMAND integer-test)
|
||||||
|
add_test(NAME Logical COMMAND logical-test)
|
||||||
add_test(NAME Real COMMAND real-test)
|
add_test(NAME Real COMMAND real-test)
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,7 @@ public:
|
||||||
// For static expression evaluation, all the bits will have the same value.
|
// For static expression evaluation, all the bits will have the same value.
|
||||||
constexpr bool IsTrue() const { return word_.BTEST(0); }
|
constexpr bool IsTrue() const { return word_.BTEST(0); }
|
||||||
|
|
||||||
constexpr Logical NOT() const {
|
constexpr Logical NOT() const { return {word_.NOT()}; }
|
||||||
return {word_.NOT()};
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Logical AND(const Logical &that) const {
|
constexpr Logical AND(const Logical &that) const {
|
||||||
return {word_.IAND(that.word_)};
|
return {word_.IAND(that.word_)};
|
||||||
|
|
@ -41,9 +39,7 @@ public:
|
||||||
return {word_.IOR(that.word_)};
|
return {word_.IOR(that.word_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Logical EQV(const Logical &that) const {
|
constexpr Logical EQV(const Logical &that) const { return NEQV(that).NOT(); }
|
||||||
return NEQV(that).NOT();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Logical NEQV(const Logical &that) const {
|
constexpr Logical NEQV(const Logical &that) const {
|
||||||
return {word_.IEOR(that.word_)};
|
return {word_.IEOR(that.word_)};
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,7 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename INT>
|
template<typename INT> constexpr INT EXPONENT() const {
|
||||||
constexpr INT EXPONENT() const {
|
|
||||||
std::uint64_t exponent{Exponent()};
|
std::uint64_t exponent{Exponent()};
|
||||||
if (exponent == maxExponent) {
|
if (exponent == maxExponent) {
|
||||||
return INT::HUGE();
|
return INT::HUGE();
|
||||||
|
|
@ -171,7 +170,8 @@ public:
|
||||||
if (lshift + precision >= result.value.bits) {
|
if (lshift + precision >= result.value.bits) {
|
||||||
result.flags.set(RealFlag::Overflow);
|
result.flags.set(RealFlag::Overflow);
|
||||||
} else {
|
} else {
|
||||||
result.value = result.value.ConvertUnsigned(fraction).value.SHIFTL(lshift);
|
result.value =
|
||||||
|
result.value.ConvertUnsigned(fraction).value.SHIFTL(lshift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result.flags.test(RealFlag::Overflow)) {
|
if (result.flags.test(RealFlag::Overflow)) {
|
||||||
|
|
@ -680,21 +680,11 @@ private:
|
||||||
Word word_{}; // an Integer<>
|
Word word_{}; // an Integer<>
|
||||||
};
|
};
|
||||||
|
|
||||||
using RealKind2 = Real<Integer<16>, 11>;
|
|
||||||
extern template class Real<Integer<16>, 11>;
|
extern template class Real<Integer<16>, 11>;
|
||||||
|
|
||||||
using RealKind4 = Real<Integer<32>, 24>;
|
|
||||||
extern template class Real<Integer<32>, 24>;
|
extern template class Real<Integer<32>, 24>;
|
||||||
|
|
||||||
using RealKind8 = Real<Integer<64>, 53>;
|
|
||||||
extern template class Real<Integer<64>, 53>;
|
extern template class Real<Integer<64>, 53>;
|
||||||
|
extern template class Real<Integer<80>, 64, false>; // 80387 extended precision
|
||||||
using RealKind10 = Real<Integer<80>, 64, false>; // 80387 extended precision
|
|
||||||
extern template class Real<Integer<80>, 64, false>;
|
|
||||||
|
|
||||||
using RealKind16 = Real<Integer<128>, 112>;
|
|
||||||
extern template class Real<Integer<128>, 112>;
|
extern template class Real<Integer<128>, 112>;
|
||||||
|
|
||||||
// N.B. No "double-double" support.
|
// N.B. No "double-double" support.
|
||||||
|
|
||||||
} // namespace Fortran::evaluate::value
|
} // namespace Fortran::evaluate::value
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,36 @@ template<int KIND> struct Integer {
|
||||||
using ValueType = value::Integer<8 * kind>;
|
using ValueType = value::Integer<8 * kind>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int KIND> struct Real {
|
template<int KIND> struct Real;
|
||||||
|
template<> struct Real<2> {
|
||||||
static constexpr Classification classification{Classification::Real};
|
static constexpr Classification classification{Classification::Real};
|
||||||
static constexpr int kind{KIND};
|
static constexpr int kind{2};
|
||||||
static constexpr bool hasLen{false};
|
static constexpr bool hasLen{false};
|
||||||
using ValueType = value::Real<8 * K>;
|
using ValueType = value::Real<value::Integer<16>, 11>;
|
||||||
|
};
|
||||||
|
template<> struct Real<4> {
|
||||||
|
static constexpr Classification classification{Classification::Real};
|
||||||
|
static constexpr int kind{4};
|
||||||
|
static constexpr bool hasLen{false};
|
||||||
|
using ValueType = value::Real<value::Integer<32>, 24>;
|
||||||
|
};
|
||||||
|
template<> struct Real<8> {
|
||||||
|
static constexpr Classification classification{Classification::Real};
|
||||||
|
static constexpr int kind{8};
|
||||||
|
static constexpr bool hasLen{false};
|
||||||
|
using ValueType = value::Real<value::Integer<64>, 53>;
|
||||||
|
};
|
||||||
|
template<> struct Real<10> {
|
||||||
|
static constexpr Classification classification{Classification::Real};
|
||||||
|
static constexpr int kind{10};
|
||||||
|
static constexpr bool hasLen{false};
|
||||||
|
using ValueType = value::Real<value::Integer<80>, 64, false>;
|
||||||
|
};
|
||||||
|
template<> struct Real<16> {
|
||||||
|
static constexpr Classification classification{Classification::Real};
|
||||||
|
static constexpr int kind{16};
|
||||||
|
static constexpr bool hasLen{false};
|
||||||
|
using ValueType = value::Real<value::Integer<128>, 112>;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0 // TODO
|
#if 0 // TODO
|
||||||
|
|
@ -46,7 +71,7 @@ template<int KIND> struct Complex {
|
||||||
static constexpr Classification classification{Classification::Complex};
|
static constexpr Classification classification{Classification::Complex};
|
||||||
static constexpr int kind{KIND};
|
static constexpr int kind{KIND};
|
||||||
static constexpr bool hasLen{false};
|
static constexpr bool hasLen{false};
|
||||||
using ValueType = value::Complex<8 * K>;
|
using ValueType = value::Complex<8 * kind>;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -54,7 +79,7 @@ template<int KIND> struct Logical {
|
||||||
static constexpr Classification classification{Classification::Logical};
|
static constexpr Classification classification{Classification::Logical};
|
||||||
static constexpr int kind{KIND};
|
static constexpr int kind{KIND};
|
||||||
static constexpr bool hasLen{false};
|
static constexpr bool hasLen{false};
|
||||||
using ValueType = value::Logical<8 * K>;
|
using ValueType = value::Logical<8 * kind>;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0 // TODO
|
#if 0 // TODO
|
||||||
|
|
@ -62,7 +87,7 @@ template<int KIND> struct Character {
|
||||||
static constexpr Classification classification{Classification::Character};
|
static constexpr Classification classification{Classification::Character};
|
||||||
static constexpr int kind{KIND};
|
static constexpr int kind{KIND};
|
||||||
static constexpr bool hasLen{true};
|
static constexpr bool hasLen{true};
|
||||||
using ValueType = value::Character<8 * K>;
|
using ValueType = value::Character<8 * kind>;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -75,13 +100,13 @@ template<int KIND> struct Character {
|
||||||
using DefaultReal = Real<4>;
|
using DefaultReal = Real<4>;
|
||||||
using DefaultInteger = Integer<DefaultReal::kind>;
|
using DefaultInteger = Integer<DefaultReal::kind>;
|
||||||
using IntrinsicTypeParameterType = DefaultInteger;
|
using IntrinsicTypeParameterType = DefaultInteger;
|
||||||
#if 0 // TODO
|
#if 0 // TODO
|
||||||
using DefaultComplex = Complex<2 * DefaultReal::kind>;
|
using DefaultComplex = Complex<2 * DefaultReal::kind>;
|
||||||
#endif
|
#endif
|
||||||
using DefaultLogical = Logical<DefaultReal::kind>;
|
using DefaultLogical = Logical<DefaultReal::kind>;
|
||||||
#if 0 // TODO
|
#if 0 // TODO
|
||||||
using DefaultCharacter = Character<1>;
|
using DefaultCharacter = Character<1>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Fortran::evaluate
|
} // namespace Fortran::evaluate::type
|
||||||
#endif // FORTRAN_EVALUATE_TYPE_H_
|
#endif // FORTRAN_EVALUATE_TYPE_H_
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,15 @@ target_link_libraries(integer-test
|
||||||
FortranEvaluateTesting
|
FortranEvaluateTesting
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_executable(logical-test
|
||||||
|
logical.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(logical-test
|
||||||
|
FortranEvaluate
|
||||||
|
FortranEvaluateTesting
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(real-test
|
add_executable(real-test
|
||||||
real.cc
|
real.cc
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
#include "testing.h"
|
#include "testing.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
using Fortran::evaluate::value::Integer;
|
|
||||||
using Fortran::evaluate::Ordering;
|
using Fortran::evaluate::Ordering;
|
||||||
|
using Fortran::evaluate::value::Integer;
|
||||||
|
|
||||||
template<int BITS, typename INT = Integer<BITS>> void exhaustiveTesting() {
|
template<int BITS, typename INT = Integer<BITS>> void exhaustiveTesting() {
|
||||||
std::uint64_t maxUnsignedValue{(std::uint64_t{1} << BITS) - 1};
|
std::uint64_t maxUnsignedValue{(std::uint64_t{1} << BITS) - 1};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright (c) 2018, NVIDIA CORPORATION. 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
|
||||||
|
//
|
||||||
|
// http://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 "testing.h"
|
||||||
|
#include "../../lib/evaluate/type.h"
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
using namespace Fortran::evaluate::type;
|
||||||
|
|
||||||
|
template<int KIND> void testKind() {
|
||||||
|
using Type = Logical<KIND>;
|
||||||
|
TEST(Type::classification == Classification::Logical);
|
||||||
|
TEST(Type::kind == KIND);
|
||||||
|
TEST(!Type::hasLen);
|
||||||
|
using Value = typename Type::ValueType;
|
||||||
|
MATCH(8 * KIND, Value::bits);
|
||||||
|
TEST(!Value{}.IsTrue());
|
||||||
|
TEST(!Value{false}.IsTrue());
|
||||||
|
TEST(Value{true}.IsTrue());
|
||||||
|
TEST(Value{false}.NOT().IsTrue());
|
||||||
|
TEST(!Value{true}.NOT().IsTrue());
|
||||||
|
TEST(!Value{false}.AND(Value{false}).IsTrue());
|
||||||
|
TEST(!Value{false}.AND(Value{true}).IsTrue());
|
||||||
|
TEST(!Value{true}.AND(Value{false}).IsTrue());
|
||||||
|
TEST(Value{true}.AND(Value{true}).IsTrue());
|
||||||
|
TEST(!Value{false}.OR(Value{false}).IsTrue());
|
||||||
|
TEST(Value{false}.OR(Value{true}).IsTrue());
|
||||||
|
TEST(Value{true}.OR(Value{false}).IsTrue());
|
||||||
|
TEST(Value{true}.OR(Value{true}).IsTrue());
|
||||||
|
TEST(Value{false}.EQV(Value{false}).IsTrue());
|
||||||
|
TEST(!Value{false}.EQV(Value{true}).IsTrue());
|
||||||
|
TEST(!Value{true}.EQV(Value{false}).IsTrue());
|
||||||
|
TEST(Value{true}.EQV(Value{true}).IsTrue());
|
||||||
|
TEST(!Value{false}.NEQV(Value{false}).IsTrue());
|
||||||
|
TEST(Value{false}.NEQV(Value{true}).IsTrue());
|
||||||
|
TEST(Value{true}.NEQV(Value{false}).IsTrue());
|
||||||
|
TEST(!Value{true}.NEQV(Value{true}).IsTrue());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
testKind<1>();
|
||||||
|
testKind<2>();
|
||||||
|
testKind<4>();
|
||||||
|
testKind<8>();
|
||||||
|
testKind<16>();
|
||||||
|
return testing::Complete();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue