mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[APFloat] Reduce some dispatch boilerplates. NFC.
Summary: This is an attempt to reduce the verbose manual dispatching code in APFloat. This doesn't handle multiple dispatch on single discriminator (e.g. APFloat::add(const APFloat&)), nor handles multiple dispatch on multiple discriminators (e.g. APFloat::convert()). Reviewers: hfinkel, echristo, jlebar Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D29161 llvm-svn: 293255
This commit is contained in:
parent
69098f2924
commit
75bc287023
@ -21,6 +21,15 @@
|
|||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
|
||||||
|
do { \
|
||||||
|
if (usesLayout<IEEEFloat>(getSemantics())) \
|
||||||
|
return U.IEEE.METHOD_CALL; \
|
||||||
|
if (usesLayout<DoubleAPFloat>(getSemantics())) \
|
||||||
|
return U.Double.METHOD_CALL; \
|
||||||
|
llvm_unreachable("Unexpected semantics"); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
struct fltSemantics;
|
struct fltSemantics;
|
||||||
@ -771,76 +780,24 @@ class APFloat : public APFloatBase {
|
|||||||
llvm_unreachable("Unexpected semantics");
|
llvm_unreachable("Unexpected semantics");
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeZero(bool Neg) {
|
void makeZero(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeZero(Neg)); }
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
|
||||||
U.IEEE.makeZero(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
U.Double.makeZero(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeInf(bool Neg) {
|
void makeInf(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeInf(Neg)); }
|
||||||
if (usesLayout<IEEEFloat>(*U.semantics)) {
|
|
||||||
U.IEEE.makeInf(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(*U.semantics)) {
|
|
||||||
U.Double.makeInf(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
|
void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
APFLOAT_DISPATCH_ON_SEMANTICS(makeNaN(SNaN, Neg, fill));
|
||||||
U.IEEE.makeNaN(SNaN, Neg, fill);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
return U.Double.makeNaN(SNaN, Neg, fill);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeLargest(bool Neg) {
|
void makeLargest(bool Neg) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
APFLOAT_DISPATCH_ON_SEMANTICS(makeLargest(Neg));
|
||||||
U.IEEE.makeLargest(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
U.Double.makeLargest(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeSmallest(bool Neg) {
|
void makeSmallest(bool Neg) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallest(Neg));
|
||||||
U.IEEE.makeSmallest(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
U.Double.makeSmallest(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeSmallestNormalized(bool Neg) {
|
void makeSmallestNormalized(bool Neg) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallestNormalized(Neg));
|
||||||
U.IEEE.makeSmallestNormalized(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
U.Double.makeSmallestNormalized(Neg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This is due to clang 3.3 (or older version) always checks for the
|
// FIXME: This is due to clang 3.3 (or older version) always checks for the
|
||||||
@ -879,13 +836,7 @@ public:
|
|||||||
|
|
||||||
~APFloat() = default;
|
~APFloat() = default;
|
||||||
|
|
||||||
bool needsCleanup() const {
|
bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); }
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
|
||||||
return U.IEEE.needsCleanup();
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.needsCleanup();
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Factory for Positive and Negative Zero.
|
/// Factory for Positive and Negative Zero.
|
||||||
///
|
///
|
||||||
@ -1044,21 +995,13 @@ public:
|
|||||||
llvm_unreachable("Unexpected semantics");
|
llvm_unreachable("Unexpected semantics");
|
||||||
}
|
}
|
||||||
opStatus roundToIntegral(roundingMode RM) {
|
opStatus roundToIntegral(roundingMode RM) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(roundToIntegral(RM));
|
||||||
return U.IEEE.roundToIntegral(RM);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.roundToIntegral(RM);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: bool parameters are not readable and a source of bugs.
|
// TODO: bool parameters are not readable and a source of bugs.
|
||||||
// Do something.
|
// Do something.
|
||||||
opStatus next(bool nextDown) {
|
opStatus next(bool nextDown) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown));
|
||||||
return U.IEEE.next(nextDown);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.next(nextDown);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add two APFloats, rounding ties to the nearest even.
|
/// Add two APFloats, rounding ties to the nearest even.
|
||||||
@ -1093,17 +1036,7 @@ public:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeSign() {
|
void changeSign() { APFLOAT_DISPATCH_ON_SEMANTICS(changeSign()); }
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
|
||||||
U.IEEE.changeSign();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
U.Double.changeSign();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
void clearSign() {
|
void clearSign() {
|
||||||
if (isNegative())
|
if (isNegative())
|
||||||
changeSign();
|
changeSign();
|
||||||
@ -1125,51 +1058,30 @@ public:
|
|||||||
opStatus convertToInteger(integerPart *Input, unsigned int Width,
|
opStatus convertToInteger(integerPart *Input, unsigned int Width,
|
||||||
bool IsSigned, roundingMode RM,
|
bool IsSigned, roundingMode RM,
|
||||||
bool *IsExact) const {
|
bool *IsExact) const {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(
|
||||||
return U.IEEE.convertToInteger(Input, Width, IsSigned, RM, IsExact);
|
convertToInteger(Input, Width, IsSigned, RM, IsExact));
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.convertToInteger(Input, Width, IsSigned, RM, IsExact);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
opStatus convertToInteger(APSInt &Result, roundingMode RM,
|
opStatus convertToInteger(APSInt &Result, roundingMode RM,
|
||||||
bool *IsExact) const;
|
bool *IsExact) const;
|
||||||
opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
|
opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
|
||||||
roundingMode RM) {
|
roundingMode RM) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM));
|
||||||
return U.IEEE.convertFromAPInt(Input, IsSigned, RM);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.convertFromAPInt(Input, IsSigned, RM);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
opStatus convertFromSignExtendedInteger(const integerPart *Input,
|
opStatus convertFromSignExtendedInteger(const integerPart *Input,
|
||||||
unsigned int InputSize, bool IsSigned,
|
unsigned int InputSize, bool IsSigned,
|
||||||
roundingMode RM) {
|
roundingMode RM) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(
|
||||||
return U.IEEE.convertFromSignExtendedInteger(Input, InputSize, IsSigned,
|
convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM));
|
||||||
RM);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.convertFromSignExtendedInteger(Input, InputSize, IsSigned,
|
|
||||||
RM);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
opStatus convertFromZeroExtendedInteger(const integerPart *Input,
|
opStatus convertFromZeroExtendedInteger(const integerPart *Input,
|
||||||
unsigned int InputSize, bool IsSigned,
|
unsigned int InputSize, bool IsSigned,
|
||||||
roundingMode RM) {
|
roundingMode RM) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(
|
||||||
return U.IEEE.convertFromZeroExtendedInteger(Input, InputSize, IsSigned,
|
convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
|
||||||
RM);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.convertFromZeroExtendedInteger(Input, InputSize, IsSigned,
|
|
||||||
RM);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
opStatus convertFromString(StringRef, roundingMode);
|
opStatus convertFromString(StringRef, roundingMode);
|
||||||
APInt bitcastToAPInt() const {
|
APInt bitcastToAPInt() const {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
|
||||||
return U.IEEE.bitcastToAPInt();
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.bitcastToAPInt();
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
double convertToDouble() const { return getIEEE().convertToDouble(); }
|
double convertToDouble() const { return getIEEE().convertToDouble(); }
|
||||||
float convertToFloat() const { return getIEEE().convertToFloat(); }
|
float convertToFloat() const { return getIEEE().convertToFloat(); }
|
||||||
@ -1198,11 +1110,8 @@ public:
|
|||||||
|
|
||||||
unsigned int convertToHexString(char *DST, unsigned int HexDigits,
|
unsigned int convertToHexString(char *DST, unsigned int HexDigits,
|
||||||
bool UpperCase, roundingMode RM) const {
|
bool UpperCase, roundingMode RM) const {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(
|
||||||
return U.IEEE.convertToHexString(DST, HexDigits, UpperCase, RM);
|
convertToHexString(DST, HexDigits, UpperCase, RM));
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.convertToHexString(DST, HexDigits, UpperCase, RM);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isZero() const { return getCategory() == fcZero; }
|
bool isZero() const { return getCategory() == fcZero; }
|
||||||
@ -1210,13 +1119,7 @@ public:
|
|||||||
bool isNaN() const { return getCategory() == fcNaN; }
|
bool isNaN() const { return getCategory() == fcNaN; }
|
||||||
|
|
||||||
bool isNegative() const { return getIEEE().isNegative(); }
|
bool isNegative() const { return getIEEE().isNegative(); }
|
||||||
bool isDenormal() const {
|
bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); }
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
|
||||||
return U.IEEE.isDenormal();
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.isDenormal();
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
bool isSignaling() const { return getIEEE().isSignaling(); }
|
bool isSignaling() const { return getIEEE().isSignaling(); }
|
||||||
|
|
||||||
bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
|
bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
|
||||||
@ -1228,53 +1131,24 @@ public:
|
|||||||
bool isFiniteNonZero() const { return isFinite() && !isZero(); }
|
bool isFiniteNonZero() const { return isFinite() && !isZero(); }
|
||||||
bool isPosZero() const { return isZero() && !isNegative(); }
|
bool isPosZero() const { return isZero() && !isNegative(); }
|
||||||
bool isNegZero() const { return isZero() && isNegative(); }
|
bool isNegZero() const { return isZero() && isNegative(); }
|
||||||
bool isSmallest() const {
|
bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); }
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); }
|
||||||
return U.IEEE.isSmallest();
|
bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); }
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.isSmallest();
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
bool isLargest() const {
|
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
|
||||||
return U.IEEE.isLargest();
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.isLargest();
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
bool isInteger() const {
|
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
|
||||||
return U.IEEE.isInteger();
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.isInteger();
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
|
||||||
|
|
||||||
APFloat &operator=(const APFloat &RHS) = default;
|
APFloat &operator=(const APFloat &RHS) = default;
|
||||||
APFloat &operator=(APFloat &&RHS) = default;
|
APFloat &operator=(APFloat &&RHS) = default;
|
||||||
|
|
||||||
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
|
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
|
||||||
unsigned FormatMaxPadding = 3) const {
|
unsigned FormatMaxPadding = 3) const {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics())) {
|
APFLOAT_DISPATCH_ON_SEMANTICS(
|
||||||
U.IEEE.toString(Str, FormatPrecision, FormatMaxPadding);
|
toString(Str, FormatPrecision, FormatMaxPadding));
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics())) {
|
|
||||||
U.Double.toString(Str, FormatPrecision, FormatMaxPadding);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(raw_ostream &) const;
|
void print(raw_ostream &) const;
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
bool getExactInverse(APFloat *inv) const {
|
bool getExactInverse(APFloat *inv) const {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv));
|
||||||
return U.IEEE.getExactInverse(inv);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.getExactInverse(inv);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
friend hash_code hash_value(const APFloat &Arg);
|
friend hash_code hash_value(const APFloat &Arg);
|
||||||
@ -1345,4 +1219,5 @@ inline APFloat maxnum(const APFloat &A, const APFloat &B) {
|
|||||||
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
|
#undef APFLOAT_DISPATCH_ON_SEMANTICS
|
||||||
#endif // LLVM_ADT_APFLOAT_H
|
#endif // LLVM_ADT_APFLOAT_H
|
||||||
|
@ -26,6 +26,15 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
|
||||||
|
do { \
|
||||||
|
if (usesLayout<IEEEFloat>(getSemantics())) \
|
||||||
|
return U.IEEE.METHOD_CALL; \
|
||||||
|
if (usesLayout<DoubleAPFloat>(getSemantics())) \
|
||||||
|
return U.Double.METHOD_CALL; \
|
||||||
|
llvm_unreachable("Unexpected semantics"); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/// A macro used to combine two fcCategory enums into one key which can be used
|
/// A macro used to combine two fcCategory enums into one key which can be used
|
||||||
@ -4418,11 +4427,7 @@ APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
|
APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
|
||||||
if (usesLayout<IEEEFloat>(getSemantics()))
|
APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM));
|
||||||
return U.IEEE.convertFromString(Str, RM);
|
|
||||||
if (usesLayout<DoubleAPFloat>(getSemantics()))
|
|
||||||
return U.Double.convertFromString(Str, RM);
|
|
||||||
llvm_unreachable("Unexpected semantics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_code hash_value(const APFloat &Arg) {
|
hash_code hash_value(const APFloat &Arg) {
|
||||||
@ -4512,3 +4517,5 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
#undef APFLOAT_DISPATCH_ON_SEMANTICS
|
||||||
|
Loading…
Reference in New Issue
Block a user