diff options
author | Leonard Chan <leonardchan@google.com> | 2019-01-16 18:53:05 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2019-01-16 18:53:05 +0000 |
commit | 86285d2e17ea669fe53853215759c554ad101d31 (patch) | |
tree | bbedc37df9ec3971359b80ed5b9c5503f576b213 /clang/include | |
parent | 8265e390e740f0fb7464f7c20bd38d55ee145dd4 (diff) |
[Fixed Point Arithmetic] Add APFixedPoint to APValue
This adds APFixedPoint to the union of values that can be represented with an APValue.
Differential Revision: https://reviews.llvm.org/D56746
llvm-svn: 351368
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang/AST/APValue.h | 23 | ||||
-rw-r--r-- | clang/include/clang/AST/Type.h | 2 | ||||
-rw-r--r-- | clang/include/clang/Basic/FixedPoint.h | 22 |
3 files changed, 46 insertions, 1 deletions
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index d4057c9da5f3..f540ad739835 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_APVALUE_H #define LLVM_CLANG_AST_APVALUE_H +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" @@ -43,6 +44,7 @@ public: Uninitialized, Int, Float, + FixedPoint, ComplexInt, ComplexFloat, LValue, @@ -175,6 +177,9 @@ public: explicit APValue(APFloat F) : Kind(Uninitialized) { MakeFloat(); setFloat(std::move(F)); } + explicit APValue(APFixedPoint FX) : Kind(Uninitialized) { + MakeFixedPoint(std::move(FX)); + } explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { MakeVector(); setVector(E, N); } @@ -233,6 +238,7 @@ public: bool isUninit() const { return Kind == Uninitialized; } bool isInt() const { return Kind == Int; } bool isFloat() const { return Kind == Float; } + bool isFixedPoint() const { return Kind == FixedPoint; } bool isComplexInt() const { return Kind == ComplexInt; } bool isComplexFloat() const { return Kind == ComplexFloat; } bool isLValue() const { return Kind == LValue; } @@ -265,6 +271,14 @@ public: return const_cast<APValue*>(this)->getFloat(); } + APFixedPoint &getFixedPoint() { + assert(isFixedPoint() && "Invalid accessor"); + return *(APFixedPoint *)(char *)Data.buffer; + } + const APFixedPoint &getFixedPoint() const { + return const_cast<APValue *>(this)->getFixedPoint(); + } + APSInt &getComplexIntReal() { assert(isComplexInt() && "Invalid accessor"); return ((ComplexAPSInt*)(char*)Data.buffer)->Real; @@ -406,6 +420,10 @@ public: assert(isFloat() && "Invalid accessor"); *(APFloat *)(char *)Data.buffer = std::move(F); } + void setFixedPoint(APFixedPoint FX) { + assert(isFixedPoint() && "Invalid accessor"); + *(APFixedPoint *)(char *)Data.buffer = std::move(FX); + } void setVector(const APValue *E, unsigned N) { assert(isVector() && "Invalid accessor"); ((Vec*)(char*)Data.buffer)->Elts = new APValue[N]; @@ -465,6 +483,11 @@ private: new ((void*)(char*)Data.buffer) APFloat(0.0); Kind = Float; } + void MakeFixedPoint(APFixedPoint &&FX) { + assert(isUninit() && "Bad state change"); + new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX)); + Kind = FixedPoint; + } void MakeVector() { assert(isUninit() && "Bad state change"); new ((void*)(char*)Data.buffer) Vec(); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 4c48473d2e00..0ebd2bc86fe6 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6848,6 +6848,8 @@ QualType DecayedType::getPointeeType() const { // Get the decimal string representation of a fixed point type, represented // as a scaled integer. +// TODO: At some point, we should change the arguments to instead just accept an +// APFixedPoint instead of APSInt and scale. void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val, unsigned Scale); diff --git a/clang/include/clang/Basic/FixedPoint.h b/clang/include/clang/Basic/FixedPoint.h index bfba55a04103..174f7cc7d0fc 100644 --- a/clang/include/clang/Basic/FixedPoint.h +++ b/clang/include/clang/Basic/FixedPoint.h @@ -18,6 +18,7 @@ #define LLVM_CLANG_BASIC_FIXEDPOINT_H #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" namespace clang { @@ -104,19 +105,25 @@ class APFixedPoint { : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {} + // Zero initialization. + APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {} + llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); } inline unsigned getWidth() const { return Sema.getWidth(); } inline unsigned getScale() const { return Sema.getScale(); } inline bool isSaturated() const { return Sema.isSaturated(); } inline bool isSigned() const { return Sema.isSigned(); } inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } + FixedPointSemantics getSemantics() const { return Sema; } + + bool getBoolValue() const { return Val.getBoolValue(); } // Convert this number to match the semantics provided. APFixedPoint convert(const FixedPointSemantics &DstSema) const; APFixedPoint shr(unsigned Amt) const { return APFixedPoint(Val >> Amt, Sema); - } + } APFixedPoint shl(unsigned Amt) const { return APFixedPoint(Val << Amt, Sema); @@ -129,6 +136,13 @@ class APFixedPoint { return Val >> getScale(); } + void toString(llvm::SmallVectorImpl<char> &Str) const; + std::string toString() const { + llvm::SmallString<40> S; + toString(S); + return S.str(); + } + // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1. int compare(const APFixedPoint &Other) const; bool operator==(const APFixedPoint &Other) const { @@ -154,6 +168,12 @@ private: FixedPointSemantics Sema; }; +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const APFixedPoint &FX) { + OS << FX.toString(); + return OS; +} + } // namespace clang #endif |