+bool bigmul(uint32_t qhat, unsigned product[], unsigned vn[], int m,
+ int n)
+{
+ long long t, k;
+ int s, i;
+ uint32_t carry = 0;
+ // 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;
+ }
+ return carry != 0;
+}
+
+bool bigadd(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
+ for (int i = 0; i <= n; i++)
+ {
+ uint64_t value = (uint64_t)vn[i] + (uint64_t)un[i] + ca;
+ ca = value >> 32 != 0;
+ result[i] = value;
+ }
+ return 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
+ for (int i = 0; i <= n; i++)
+ {
+ uint64_t value = (uint64_t)~vn[i] + (uint64_t)un[i] + ca;
+ ca = value >> 32 != 0;
+ result[i] = value;
+ }
+ return ca;
+}
+
+bool bigmulsub(unsigned long long qhat, unsigned vn[], unsigned un[], int j,
+ int m, int n)
+{
+ // Multiply and subtract.
+ uint32_t product[n + 1];
+ bigmul(qhat, product, vn, m, n);
+ bool ca = bigsub(un, product, un, m, n, true);
+ bool need_fixup = !ca;
+ return need_fixup;
+}
+