mirror of https://github.com/microsoft/clang.git
Add support for generating MIPS legacy NaN
Currently, the NaN values emitted for MIPS architectures do not cover non-IEEE754-2008 compliant case. This change fixes the issue. Patch by Vladimir Radosavljevic. Differential Revision: http://reviews.llvm.org/D7882 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@230653 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
24feb0432e
commit
056cc8470b
|
@ -638,6 +638,12 @@ public:
|
||||||
return std::string(1, *Constraint);
|
return std::string(1, *Constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Returns true if NaN encoding is IEEE 754-2008.
|
||||||
|
/// Only MIPS allows a different encoding.
|
||||||
|
virtual bool isNan2008() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Returns a string of target-specific clobbers, in LLVM format.
|
/// \brief Returns a string of target-specific clobbers, in LLVM format.
|
||||||
virtual const char *getClobbers() const = 0;
|
virtual const char *getClobbers() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -7590,10 +7590,23 @@ static bool TryEvaluateBuiltinNaN(const ASTContext &Context,
|
||||||
else if (S->getString().getAsInteger(0, fill))
|
else if (S->getString().getAsInteger(0, fill))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (Context.getTargetInfo().isNan2008()) {
|
||||||
if (SNaN)
|
if (SNaN)
|
||||||
Result = llvm::APFloat::getSNaN(Sem, false, &fill);
|
Result = llvm::APFloat::getSNaN(Sem, false, &fill);
|
||||||
else
|
else
|
||||||
Result = llvm::APFloat::getQNaN(Sem, false, &fill);
|
Result = llvm::APFloat::getQNaN(Sem, false, &fill);
|
||||||
|
} else {
|
||||||
|
// Prior to IEEE 754-2008, architectures were allowed to choose whether
|
||||||
|
// the first bit of their significand was set for qNaN or sNaN. MIPS chose
|
||||||
|
// a different encoding to what became a standard in 2008, and for pre-
|
||||||
|
// 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as
|
||||||
|
// sNaN. This is now known as "legacy NaN" encoding.
|
||||||
|
if (SNaN)
|
||||||
|
Result = llvm::APFloat::getQNaN(Sem, false, &fill);
|
||||||
|
else
|
||||||
|
Result = llvm::APFloat::getSNaN(Sem, false, &fill);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5674,6 +5674,10 @@ public:
|
||||||
return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
|
return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNan2008() const override {
|
||||||
|
return IsNan2008;
|
||||||
|
}
|
||||||
|
|
||||||
StringRef getABI() const override { return ABI; }
|
StringRef getABI() const override { return ABI; }
|
||||||
bool setCPU(const std::string &Name) override {
|
bool setCPU(const std::string &Name) override {
|
||||||
bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
|
bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// RUN: %clang -target mipsel-unknown-linux -mnan=legacy -emit-llvm -S %s -o - | FileCheck %s
|
||||||
|
// CHECK: float 0x7FF4000000000000, float 0x7FF8000000000000
|
||||||
|
// CHECK: double 0x7FF4000000000000, double 0x7FF8000000000000
|
||||||
|
|
||||||
|
float f[] = {
|
||||||
|
__builtin_nan(""),
|
||||||
|
__builtin_nans(""),
|
||||||
|
};
|
||||||
|
|
||||||
|
double d[] = {
|
||||||
|
__builtin_nan(""),
|
||||||
|
__builtin_nans(""),
|
||||||
|
};
|
Loading…
Reference in New Issue