Add SkDivMod with a special case for ARM.

BUG=skia:1663
R=djsollen@google.com, tomhudson@google.com, reed@google.com

Author: mtklein@google.com

Review URL: https://chromiumcodereview.appspot.com/24159009

git-svn-id: http://skia.googlecode.com/svn/trunk@11482 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index cb4d0b8..bc8e6a3 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -691,3 +691,74 @@
 }
 
 DEFINE_TESTCLASS("Endian", EndianTestClass, TestEndian)
+
+template <typename T>
+static void test_divmod(skiatest::Reporter* r) {
+    const struct {
+        T numer;
+        T denom;
+    } kEdgeCases[] = {
+        {(T)17, (T)17},
+        {(T)17, (T)4},
+        {(T)0,  (T)17},
+        // For unsigned T these negatives are just some large numbers.  Doesn't hurt to test them.
+        {(T)-17, (T)-17},
+        {(T)-17, (T)4},
+        {(T)17,  (T)-4},
+        {(T)-17, (T)-4},
+    };
+
+    for (size_t i = 0; i < SK_ARRAY_COUNT(kEdgeCases); i++) {
+        const T numer = kEdgeCases[i].numer;
+        const T denom = kEdgeCases[i].denom;
+        T div, mod;
+        SkTDivMod(numer, denom, &div, &mod);
+        REPORTER_ASSERT(r, numer/denom == div);
+        REPORTER_ASSERT(r, numer%denom == mod);
+    }
+
+    SkRandom rand;
+    for (size_t i = 0; i < 10000; i++) {
+        const T numer = (T)rand.nextS();
+        T denom = 0;
+        while (0 == denom) {
+            denom = (T)rand.nextS();
+        }
+        T div, mod;
+        SkTDivMod(numer, denom, &div, &mod);
+        REPORTER_ASSERT(r, numer/denom == div);
+        REPORTER_ASSERT(r, numer%denom == mod);
+    }
+}
+
+DEF_TEST(divmod_u8, r) {
+    test_divmod<uint8_t>(r);
+}
+
+DEF_TEST(divmod_u16, r) {
+    test_divmod<uint16_t>(r);
+}
+
+DEF_TEST(divmod_u32, r) {
+    test_divmod<uint32_t>(r);
+}
+
+DEF_TEST(divmod_u64, r) {
+    test_divmod<uint64_t>(r);
+}
+
+DEF_TEST(divmod_s8, r) {
+    test_divmod<int8_t>(r);
+}
+
+DEF_TEST(divmod_s16, r) {
+    test_divmod<int16_t>(r);
+}
+
+DEF_TEST(divmod_s32, r) {
+    test_divmod<int32_t>(r);
+}
+
+DEF_TEST(divmod_s64, r) {
+    test_divmod<int64_t>(r);
+}