split out SUB_MUL_BORROW into two separate phases
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 18 Apr 2022 18:45:02 +0000 (19:45 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 18 Apr 2022 18:45:02 +0000 (19:45 +0100)
one that looks like standard msubx, the other just plain odd

openpower/sv/bitmanip/divmnu64.c

index 93735d8027fdcbdb22d9d759eb6e61b66cd24f53..44310d32d3655a1d91593cde3302c9dc0ec99d95 100644 (file)
@@ -107,6 +107,7 @@ again:
         if (rhat < b) goto again;
       }
 
+#define SUB_MUL_BORROW
 #ifdef ORIGINAL
       // Multiply and subtract.
       k = 0;
@@ -124,9 +125,22 @@ again:
 
       // Multiply and subtract.
       uint32_t borrow = 0;
+      uint32_t phi[2000]; // plenty space
+      uint32_t plo[2000]; // plenty space
+      // first, perform mul-and-sub and store in split hi-lo
+      // this shows the vectorised sv.msubx which stores 128-bit in
+      // two 64-bit registers
       for(int i = 0; i <= n; i++) {
          uint32_t vn_i = i < n ? vn[i] : 0;
-         uint64_t value = un[i + j] - (uint64_t)qhat * vn_i - borrow;
+         uint64_t value = un[i + j] - (uint64_t)qhat * vn_i;
+         plo[i] = value & 0xffffffffLL;
+         phi[i] = value >> 32;
+      }
+      // second, reconstruct the 64-bit result, subtract borrow,
+      // store top-half (-ve) in new borrow and store low-half as answer
+      // this is the new (odd) instruction
+      for(int i = 0; i <= n; i++) {
+         uint64_t value = (((uint64_t)phi[i]<<32) | plo[i]) - borrow;
          borrow = -(uint32_t)(value >> 32);
          un[i + j] = (uint32_t)value;
       }