create bigsub and bigmul and bigmulsub
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Apr 2022 17:24:36 +0000 (18:24 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Apr 2022 17:24:36 +0000 (18:24 +0100)
openpower/sv/biginteger/divgnu64.c

index e40831fc755aa63adfced04780d23cde34d6012c..593b126d349f7e4b9c08bcc4a9d59e7579e835d0 100644 (file)
@@ -56,14 +56,13 @@ void dumpit(char *msg, int n, unsigned v[])
     printf("\n");
 }
 
-bool bigmul(unsigned long long qhat, unsigned vn[], unsigned un[], 
-           int j, int m, int n)
+bool bigmul(unsigned long long qhat, unsigned product[], unsigned vn[],
+           int m, int n)
 {
     long long t, k;
     int s, i;
     // Multiply and subtract.
     uint32_t carry = 0;
-    uint32_t product[n + 1];
     // VL = n + 1
     // sv.madded product.v, vn.v, qhat.s, carry.s
     for (int i = 0; i <= n; i++)
@@ -76,8 +75,8 @@ bool bigmul(unsigned long long qhat, unsigned vn[], unsigned un[],
     return carry != 0;
 }
 
-bool bigsub(unsigned long long qhat, unsigned vn[], unsigned un[], 
-           int j, int m, int n, bool ca)
+bool bigsub(unsigned result[], unsigned vn[], unsigned un[],
+           int m, int n, bool ca)
 {
     // VL = n + 1
     // sv.subfe un_j.v, product.v, un_j.v
@@ -85,40 +84,18 @@ bool bigsub(unsigned long long qhat, unsigned vn[], unsigned un[],
     {
         uint64_t value = (uint64_t)~vn[i] + (uint64_t)un[i] + ca;
         ca = value >> 32 != 0;
-        un[i] = value;
+        result[i] = value;
     }
-    bool need_fixup = !ca;
-    return need_fixup;
+    return ca;
 }
 
-bool bigmulsub(unsigned long long qhat, unsigned vn[], unsigned un[], 
+bool bigmulsub(unsigned long long qhat, unsigned vn[], unsigned un[],
            int j, int m, int n)
 {
-    unsigned long long p;                 // Product of two digits.
-    long long t, k;
-    int s, i;
     // Multiply and subtract.
-    uint32_t carry = 0;
     uint32_t product[n + 1];
-    // VL = n + 1
-    // sv.madded product.v, vn.v, qhat.s, carry.s
-    for (int i = 0; i <= n; i++)
-    {
-        uint32_t vn_v = i < n ? vn[i] : 0;
-        uint64_t value = (uint64_t)vn_v * (uint64_t)qhat + carry;
-        carry = (uint32_t)(value >> 32);
-        product[i] = (uint32_t)value;
-    }
-    bool ca = true;
-    uint32_t *un_j = &un[j];
-    // VL = n + 1
-    // sv.subfe un_j.v, product.v, un_j.v
-    for (int i = 0; i <= n; i++)
-    {
-        uint64_t value = (uint64_t)~product[i] + (uint64_t)un_j[i] + ca;
-        ca = value >> 32 != 0;
-        un_j[i] = value;
-    }
+    bigmul(qhat, product, vn, m, n);
+    bool ca = bigsub(un, product, un, m, n, true);
     bool need_fixup = !ca;
     return need_fixup;
 }
@@ -205,7 +182,8 @@ int divmnu(unsigned q[], unsigned r[], const unsigned u[], const unsigned v[],
                 goto again;
         }
 
-        bool need_fixup = bigmulsub(qhat, vn, un, j, m, n);
+        uint32_t *un_j = &un[j];
+        bool need_fixup = bigmulsub(qhat, vn, un_j, j, m, n);
 
         q[j] = qhat; // Store quotient digit.
         if (need_fixup)