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++)
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
{
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;
}
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)