diff options
author | Leonard Chan <leonardchan@google.com> | 2019-01-16 18:13:59 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2019-01-16 18:13:59 +0000 |
commit | 2044ac89aa5203398048b38b6e53e33f682f507d (patch) | |
tree | 0876179a140b7bfbdafbe871657660b1940feb40 /clang/lib/Basic/FixedPoint.cpp | |
parent | 07d8b321b3da50e75fbad1b23253dd3646fd6033 (diff) | |
download | bcm5719-llvm-2044ac89aa5203398048b38b6e53e33f682f507d.tar.gz bcm5719-llvm-2044ac89aa5203398048b38b6e53e33f682f507d.zip |
[Fixed Point Arithmetic] Fixed Point Addition
This patch covers addition between fixed point types and other fixed point
types or integers, using the conversion rules described in 4.1.4 of N1169.
Usual arithmetic rules do not apply to binary operations when one of the
operands is a fixed point type, and the result of the operation must be
calculated with the full precision of the operands, so we should not perform
any casting to a common type.
This patch does not include constant expression evaluation for addition of
fixed point types. That will be addressed in another patch since I think this
one is already big enough.
Differential Revision: https://reviews.llvm.org/D53738
llvm-svn: 351364
Diffstat (limited to 'clang/lib/Basic/FixedPoint.cpp')
-rw-r--r-- | clang/lib/Basic/FixedPoint.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/Basic/FixedPoint.cpp b/clang/lib/Basic/FixedPoint.cpp index bfff0fc212e..0aaa9af191d 100644 --- a/clang/lib/Basic/FixedPoint.cpp +++ b/clang/lib/Basic/FixedPoint.cpp @@ -112,4 +112,29 @@ APFixedPoint APFixedPoint::getMin(const FixedPointSemantics &Sema) { return APFixedPoint(Val, Sema); } +FixedPointSemantics FixedPointSemantics::getCommonSemantics( + const FixedPointSemantics &Other) const { + unsigned CommonScale = std::max(getScale(), Other.getScale()); + unsigned CommonWidth = + std::max(getIntegralBits(), Other.getIntegralBits()) + CommonScale; + + bool ResultIsSigned = isSigned() || Other.isSigned(); + bool ResultIsSaturated = isSaturated() || Other.isSaturated(); + bool ResultHasUnsignedPadding = false; + if (!ResultIsSigned) { + // Both are unsigned. + ResultHasUnsignedPadding = hasUnsignedPadding() && + Other.hasUnsignedPadding() && !ResultIsSaturated; + } + + // If the result is signed, add an extra bit for the sign. Otherwise, if it is + // unsigned and has unsigned padding, we only need to add the extra padding + // bit back if we are not saturating. + if (ResultIsSigned || ResultHasUnsignedPadding) + CommonWidth++; + + return FixedPointSemantics(CommonWidth, CommonScale, ResultIsSigned, + ResultIsSaturated, ResultHasUnsignedPadding); +} + } // namespace clang |