diff options
author | Leonard Chan <leonardchan@google.com> | 2019-03-06 00:28:43 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2019-03-06 00:28:43 +0000 |
commit | 8f7caae00af070fb13416dbed207f3fe18e043e8 (patch) | |
tree | 37b625e87df8172cf0fe29a715d2467c8d32e880 /clang/lib/Basic/FixedPoint.cpp | |
parent | f0c21e2ff53a2745a325136f3812b4a0e6f61ea1 (diff) | |
download | bcm5719-llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.tar.gz bcm5719-llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.zip |
[Fixed Point Arithmetic] Fixed Point and Integer Conversions
This patch includes the necessary code for converting between a fixed point type and integer.
This also includes constant expression evaluation for conversions with these types.
Differential Revision: https://reviews.llvm.org/D56900
llvm-svn: 355462
Diffstat (limited to 'clang/lib/Basic/FixedPoint.cpp')
-rw-r--r-- | clang/lib/Basic/FixedPoint.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/clang/lib/Basic/FixedPoint.cpp b/clang/lib/Basic/FixedPoint.cpp index ca84a0cf483..f049e6f64a5 100644 --- a/clang/lib/Basic/FixedPoint.cpp +++ b/clang/lib/Basic/FixedPoint.cpp @@ -218,4 +218,41 @@ APFixedPoint APFixedPoint::negate(bool *Overflow) const { return APFixedPoint(Sema); } +llvm::APSInt APFixedPoint::convertToInt(unsigned DstWidth, bool DstSign, + bool *Overflow) const { + llvm::APSInt Result = getIntPart(); + unsigned SrcWidth = getWidth(); + + llvm::APSInt DstMin = llvm::APSInt::getMinValue(DstWidth, !DstSign); + llvm::APSInt DstMax = llvm::APSInt::getMaxValue(DstWidth, !DstSign); + + if (SrcWidth < DstWidth) { + Result = Result.extend(DstWidth); + } else if (SrcWidth > DstWidth) { + DstMin = DstMin.extend(SrcWidth); + DstMax = DstMax.extend(SrcWidth); + } + + if (Overflow) { + if (Result.isSigned() && !DstSign) { + *Overflow = Result.isNegative() || Result.ugt(DstMax); + } else if (Result.isUnsigned() && DstSign) { + *Overflow = Result.ugt(DstMax); + } else { + *Overflow = Result < DstMin || Result > DstMax; + } + } + + Result.setIsSigned(DstSign); + return Result.extOrTrunc(DstWidth); +} + +APFixedPoint APFixedPoint::getFromIntValue(const llvm::APSInt &Value, + const FixedPointSemantics &DstFXSema, + bool *Overflow) { + FixedPointSemantics IntFXSema = FixedPointSemantics::GetIntegerSemantics( + Value.getBitWidth(), Value.isSigned()); + return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow); +} + } // namespace clang |