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/lib/Basic | |
| parent | 8265e390e740f0fb7464f7c20bd38d55ee145dd4 (diff) | |
| download | bcm5719-llvm-86285d2e17ea669fe53853215759c554ad101d31.tar.gz bcm5719-llvm-86285d2e17ea669fe53853215759c554ad101d31.zip | |
[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/lib/Basic')
| -rw-r--r-- | clang/lib/Basic/FixedPoint.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/clang/lib/Basic/FixedPoint.cpp b/clang/lib/Basic/FixedPoint.cpp index 0aaa9af191d..e3cffe628fd 100644 --- a/clang/lib/Basic/FixedPoint.cpp +++ b/clang/lib/Basic/FixedPoint.cpp @@ -137,4 +137,31 @@ FixedPointSemantics FixedPointSemantics::getCommonSemantics( ResultIsSaturated, ResultHasUnsignedPadding); } +void APFixedPoint::toString(llvm::SmallVectorImpl<char> &Str) const { + llvm::APSInt Val = getValue(); + unsigned Scale = getScale(); + + if (Val.isSigned() && Val.isNegative() && Val != -Val) { + Val = -Val; + Str.push_back('-'); + } + + llvm::APSInt IntPart = Val >> Scale; + + // Add 4 digits to hold the value after multiplying 10 (the radix) + unsigned Width = Val.getBitWidth() + 4; + llvm::APInt FractPart = Val.zextOrTrunc(Scale).zext(Width); + llvm::APInt FractPartMask = llvm::APInt::getAllOnesValue(Scale).zext(Width); + llvm::APInt RadixInt = llvm::APInt(Width, 10); + + IntPart.toString(Str, /*radix=*/10); + Str.push_back('.'); + do { + (FractPart * RadixInt) + .lshr(Scale) + .toString(Str, /*radix=*/10, Val.isSigned()); + FractPart = (FractPart * RadixInt) & FractPartMask; + } while (FractPart != 0); +} + } // namespace clang |

