summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/FixedPoint.cpp
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2019-03-06 00:28:43 +0000
committerLeonard Chan <leonardchan@google.com>2019-03-06 00:28:43 +0000
commit8f7caae00af070fb13416dbed207f3fe18e043e8 (patch)
tree37b625e87df8172cf0fe29a715d2467c8d32e880 /clang/lib/Basic/FixedPoint.cpp
parentf0c21e2ff53a2745a325136f3812b4a0e6f61ea1 (diff)
downloadbcm5719-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.cpp37
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
OpenPOWER on IntegriCloud