[llvm] r182801 - [APInt] Implement tcDecrement as a counterpart to tcIncrement. This is for use in APFloat IEEE-754R 2008 nextUp/nextDown function.
Michael Gottesman
mgottesman at apple.com
Tue May 28 12:50:21 PDT 2013
Author: mgottesman
Date: Tue May 28 14:50:20 2013
New Revision: 182801
URL: http://llvm.org/viewvc/llvm-project?rev=182801&view=rev
Log:
[APInt] Implement tcDecrement as a counterpart to tcIncrement. This is for use in APFloat IEEE-754R 2008 nextUp/nextDown function.
rdar://13852078
Modified:
llvm/trunk/include/llvm/ADT/APInt.h
llvm/trunk/lib/Support/APInt.cpp
llvm/trunk/unittests/ADT/APIntTest.cpp
Modified: llvm/trunk/include/llvm/ADT/APInt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=182801&r1=182800&r2=182801&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APInt.h Tue May 28 14:50:20 2013
@@ -1642,6 +1642,9 @@ public:
/// Increment a bignum in-place. Return the carry flag.
static integerPart tcIncrement(integerPart *, unsigned int);
+ /// Decrement a bignum in-place. Return the borrow flag.
+ static integerPart tcDecrement(integerPart *, unsigned int);
+
/// Set the least significant BITS and clear the rest.
static void tcSetLeastSignificantBits(integerPart *, unsigned int,
unsigned int bits);
Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=182801&r1=182800&r2=182801&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Tue May 28 14:50:20 2013
@@ -2888,6 +2888,20 @@ APInt::tcIncrement(integerPart *dst, uns
return i == parts;
}
+/* Decrement a bignum in-place, return the borrow flag. */
+integerPart
+APInt::tcDecrement(integerPart *dst, unsigned int parts) {
+ for (unsigned int i = 0; i < parts; i++) {
+ // If the current word is non-zero, then the decrement has no effect on the
+ // higher-order words of the integer and no borrow can occur. Exit early.
+ if (dst[i]--)
+ return 0;
+ }
+ // If every word was zero, then there is a borrow.
+ return 1;
+}
+
+
/* Set the least significant BITS bits of a bignum, clear the
rest. */
void
Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=182801&r1=182800&r2=182801&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Tue May 28 14:50:20 2013
@@ -532,4 +532,69 @@ TEST(APIntTest, Splat) {
EXPECT_EQ(APInt(15, 0xDB6D), APInt::getSplat(15, ValB));
}
+TEST(APIntTest, tcDecrement) {
+ // Test single word decrement.
+
+ // No out borrow.
+ {
+ integerPart singleWord = ~integerPart(0) << (integerPartWidth - 1);
+ integerPart carry = APInt::tcDecrement(&singleWord, 1);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(singleWord, ~integerPart(0) >> 1);
+ }
+
+ // With out borrow.
+ {
+ integerPart singleWord = 0;
+ integerPart carry = APInt::tcDecrement(&singleWord, 1);
+ EXPECT_EQ(carry, integerPart(1));
+ EXPECT_EQ(singleWord, ~integerPart(0));
+ }
+
+ // Test multiword decrement.
+
+ // No across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x1, 0x1, 0x1, 0x1};
+ integerPart expected[4] = {0x0, 0x1, 0x1, 0x1};
+ APInt::tcDecrement(test, 4);
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 1 across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x0, 0xF, 0x1, 0x1};
+ integerPart expected[4] = {~integerPart(0), 0xE, 0x1, 0x1};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 2 across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x0, 0x0, 0xC, 0x1};
+ integerPart expected[4] = {~integerPart(0), ~integerPart(0), 0xB, 0x1};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 3 across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x0, 0x0, 0x0, 0x1};
+ integerPart expected[4] = {~integerPart(0), ~integerPart(0), ~integerPart(0), 0x0};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 3 across word borrow, with out borrow.
+ {
+ integerPart test[4] = {0x0, 0x0, 0x0, 0x0};
+ integerPart expected[4] = {~integerPart(0), ~integerPart(0), ~integerPart(0), ~integerPart(0)};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(1));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+}
}
More information about the llvm-commits
mailing list